Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into cdac-abstractions2
Browse files Browse the repository at this point in the history
  • Loading branch information
lambdageek committed Sep 27, 2024
2 parents f0700c2 + c315bac commit 32d956b
Show file tree
Hide file tree
Showing 45 changed files with 649 additions and 506 deletions.
6 changes: 6 additions & 0 deletions docs/design/features/globalization-hybrid-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,12 @@ Affected public APIs:
- String.Compare,
- String.Equals.

Mapped to Apple Native API `compare:options:range:locale:`(https://developer.apple.com/documentation/foundation/nsstring/1414561-compare?language=objc)
This implementation uses normalization techniques such as `precomposedStringWithCanonicalMapping`,
which can result in behavior differences compared to other platforms.
Specifically, the use of precomposed strings and additional locale-based string folding can affect the results of comparisons.
Due to these differences, the exact result of string compariso on Apple platforms may differ.

The number of `CompareOptions` and `NSStringCompareOptions` combinations are limited. Originally supported combinations can be found [here for CompareOptions](https://learn.microsoft.com/dotnet/api/system.globalization.compareoptions) and [here for NSStringCompareOptions](https://developer.apple.com/documentation/foundation/nsstringcompareoptions).

- `IgnoreSymbols` is not supported because there is no equivalent in native api. Throws `PlatformNotSupportedException`.
Expand Down
17 changes: 15 additions & 2 deletions src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,21 @@ internal static unsafe bool InternalEqualTypes(object a, object b)

// Used by the ctor. Do not call directly.
// The name of this function will appear in managed stacktraces as delegate constructor.
[MethodImpl(MethodImplOptions.InternalCall)]
private extern void DelegateConstruct(object target, IntPtr slot);
private void DelegateConstruct(object target, IntPtr method)
{
// Via reflection you can pass in just about any value for the method.
// We can do some basic verification up front to prevent EE exceptions.
if (method == IntPtr.Zero)
{
throw new ArgumentNullException(nameof(method));
}

Delegate _this = this;
Construct(ObjectHandleOnStack.Create(ref _this), ObjectHandleOnStack.Create(ref target), method);
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_Construct")]
private static partial void Construct(ObjectHandleOnStack _this, ObjectHandleOnStack target, IntPtr method);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern unsafe void* GetMulticastInvoke(MethodTable* pMT);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/daccess/dacdbiimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3391,7 +3391,7 @@ HRESULT DacDbiInterfaceImpl::GetDelegateType(VMPTR_Object delegateObject, Delega
// - System.Private.CoreLib!System.Delegate.GetMethodImpl and System.Private.CoreLib!System.MulticastDelegate.GetMethodImpl
// - System.Private.CoreLib!System.Delegate.GetTarget and System.Private.CoreLib!System.MulticastDelegate.GetTarget
// - coreclr!COMDelegate::GetMethodDesc and coreclr!COMDelegate::FindMethodHandle
// - coreclr!COMDelegate::DelegateConstruct and the delegate type table in
// - coreclr!Delegate_Construct and the delegate type table in
// - DELEGATE KINDS TABLE in comdelegate.cpp

*delegateType = DelegateType::kUnknownDelegateType;
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/debug/runtimeinfo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,18 @@ else()
if(NOT EXISTS "${CDAC_BUILD_TOOL_BINARY_PATH}")
message(FATAL_ERROR "${CDAC_BUILD_TOOL_BINARY_PATH} does not exist")
endif()
set(CONTRACT_DESCRIPTOR_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/contract-descriptor.c.in")

set(CONTRACT_BASELINE_DIR "${CLR_REPO_ROOT_DIR}/docs/design/datacontracts/data")
set(CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc")

# generate the contract descriptor by running cdac-build-tool
# n.b. this just uses `dotnet` from the PATH. InitializeDotNetCli adds the apropropriate directory
add_custom_command(
OUTPUT "${CONTRACT_DESCRIPTOR_OUTPUT}"
VERBATIM
COMMAND ${CLR_DOTNET_HOST_PATH} ${CDAC_BUILD_TOOL_BINARY_PATH} compose -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -c "${CONTRACT_FILE}" $<TARGET_OBJECTS:cdac_data_descriptor>
DEPENDS cdac_data_descriptor cee_wks_core $<TARGET_OBJECTS:cdac_data_descriptor> "${CONTRACT_FILE}"
COMMAND ${CLR_DOTNET_HOST_PATH} ${CDAC_BUILD_TOOL_BINARY_PATH} compose -i "${CONTRACT_DESCRIPTOR_INPUT}" -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -b "${CONTRACT_BASELINE_DIR}" -c "${CONTRACT_FILE}" $<TARGET_OBJECTS:cdac_data_descriptor>
DEPENDS cdac_data_descriptor cee_wks_core $<TARGET_OBJECTS:cdac_data_descriptor> "${CONTRACT_FILE}" "${CONTRACT_DESCRIPTOR_INPUT}"
USES_TERMINAL
)

Expand Down
32 changes: 30 additions & 2 deletions src/coreclr/tools/cdac-build-tool/ComposeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ internal sealed class ComposeCommand : CliCommand
private readonly CliArgument<string[]> inputFiles = new("INPUT [INPUTS...]") { Arity = ArgumentArity.OneOrMore, Description = "One or more input files" };
private readonly CliOption<string> outputFile = new("-o") { Arity = ArgumentArity.ExactlyOne, HelpName = "OUTPUT", Required = true, Description = "Output file" };
private readonly CliOption<string[]> contractFile = new("-c") { Arity = ArgumentArity.ZeroOrMore, HelpName = "CONTRACT", Description = "Contract file (may be specified multiple times)" };
private readonly CliOption<string> baselinePath = new("-b", "--baseline") { Arity = ArgumentArity.ExactlyOne, HelpName = "BASELINEPATH", Description = "Directory containing the baseline contracts"};
private readonly CliOption<string> templateFile = new ("-i", "--input-template") { Arity = ArgumentArity.ExactlyOne, HelpName = "TEMPLATE", Description = "Contract descriptor template to be filled in" };
private readonly CliOption<bool> _verboseOption;
public ComposeCommand(CliOption<bool> verboseOption) : base("compose")
{
_verboseOption = verboseOption;
Add(inputFiles);
Add(outputFile);
Add(contractFile);
Add(baselinePath);
Add(templateFile);
SetAction(Run);
}

Expand All @@ -37,9 +41,33 @@ private async Task<int> Run(ParseResult parse, CancellationToken token = default
Console.Error.WriteLine("No output file specified");
return 1;
}
var baselinesDir = parse.GetValue(baselinePath);
if (baselinesDir == null)
{
Console.Error.WriteLine("No baseline path specified");
return 1;
}
baselinesDir = System.IO.Path.GetFullPath(baselinesDir);
if (!System.IO.Directory.Exists(baselinesDir))
{
Console.Error.WriteLine($"Baseline path {baselinesDir} does not exist");
return 1;
}
var templateFilePath = parse.GetValue(templateFile);
if (templateFilePath == null)
{
Console.Error.WriteLine("No template file specified");
return 1;
}
templateFilePath = System.IO.Path.GetFullPath(templateFilePath);
if (!System.IO.File.Exists(templateFilePath))
{
Console.Error.WriteLine($"Template file {templateFilePath} does not exist");
return 1;
}
var contracts = parse.GetValue(contractFile);
var verbose = parse.GetValue(_verboseOption);
var builder = new DataDescriptorModel.Builder();
var builder = new DataDescriptorModel.Builder(baselinesDir);
var scraper = new ObjectFileScraper(verbose, builder);
foreach (var input in inputs)
{
Expand Down Expand Up @@ -70,7 +98,7 @@ private async Task<int> Run(ParseResult parse, CancellationToken token = default
}
EnsureDirectoryExists(output);
using var writer = new System.IO.StreamWriter(output);
var emitter = new ContractDescriptorSourceFileEmitter();
var emitter = new ContractDescriptorSourceFileEmitter(templateFilePath);
emitter.SetPlatformFlags(model.PlatformFlags);
emitter.SetPointerDataCount(model.PointerDataCount);
emitter.SetJsonDescriptor(model.ToJson());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,24 @@ namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool;

public partial class ContractDescriptorSourceFileEmitter
{
public const string TemplateResourceName = "Microsoft.DotNet.Diagnostics.DataContract.Resources.contract-descriptor.c.in";
private const string JsonDescriptorKey = "jsonDescriptor";
private const string JsonDescriptorSizeKey = "jsonDescriptorSize";
private const string PointerDataCount = "pointerDataCount";
private const string PlatformFlags = "platformFlags";

private readonly string _templateFilePath;

[GeneratedRegex("%%([a-zA-Z0-9_]+)%%", RegexOptions.CultureInvariant)]
private static partial Regex FindTemplatePlaceholderRegex();

internal static Stream GetTemplateStream()
public ContractDescriptorSourceFileEmitter(string templateFilePath)
{
return typeof(ContractDescriptorSourceFileEmitter).Assembly.GetManifestResourceStream(TemplateResourceName)!;
_templateFilePath = templateFilePath;
}

internal static string GetTemplateString()
[GeneratedRegex("%%([a-zA-Z0-9_]+)%%", RegexOptions.CultureInvariant)]
private static partial Regex FindTemplatePlaceholderRegex();

private string GetTemplateString()
{
using var reader = new StreamReader(GetTemplateStream(), System.Text.Encoding.UTF8);
return reader.ReadToEnd();
return File.ReadAllText(_templateFilePath);
}

public void SetPointerDataCount(int count)
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,16 @@ public string ToJson()
public class Builder
{
private string _baseline;
private readonly string _baselinesDir;
private bool _baselineParsed;
private readonly Dictionary<string, TypeModelBuilder> _types = new();
private readonly Dictionary<string, GlobalBuilder> _globals = new();
private readonly Dictionary<string, ContractBuilder> _contracts = new();
public Builder()
public Builder(string baselinesDir)
{
_baseline = string.Empty;
_baselineParsed = false;
_baselinesDir = baselinesDir;
}

public uint PlatformFlags {get; set;}
Expand Down Expand Up @@ -151,7 +153,8 @@ public void SetBaseline(string baseline)
{
throw new InvalidOperationException($"Baseline already set to {_baseline} cannot set to {baseline}");
}
if (EmbeddedBaselines.BaselineNames.Contains(baseline))
var baselines = new DirectoryBaselines(_baselinesDir);
if (baselines.BaselineNames.Contains(baseline))
{
_baseline = baseline;
}
Expand Down
33 changes: 33 additions & 0 deletions src/coreclr/tools/cdac-build-tool/DirectoryBaselines.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.IO;

namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool;

public class DirectoryBaselines
{
private const string BaselineGlob = "*.json*"; // .json and .jsonc

private readonly string _baselinesDir;

public DirectoryBaselines(string baselinesDir)
{
_baselinesDir = baselinesDir;
}

public string[] BaselineNames => GetBaselineNames(_baselinesDir);

private static string[] GetBaselineNames(string baselineDir)
{

var baselineNames = new List<string>();
foreach (var file in Directory.EnumerateFiles(baselineDir, BaselineGlob))
{
var name = Path.GetFileNameWithoutExtension(file);
baselineNames.Add(name);
}
return baselineNames.ToArray();
}
}
52 changes: 0 additions & 52 deletions src/coreclr/tools/cdac-build-tool/EmbeddedBaselines.cs

This file was deleted.

10 changes: 0 additions & 10 deletions src/coreclr/tools/cdac-build-tool/cdac-build-tool.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,4 @@
<ItemGroup>
<PackageReference Include="System.CommandLine" Version="$(SystemCommandLineVersion)" />
</ItemGroup>

<PropertyGroup>
<BaselineManifestResourcePrefix>Microsoft.DotNet.Diagnostics.DataContract.Baseline:</BaselineManifestResourcePrefix>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Resources/contract-descriptor.c.in" WithCulture="false" />
<!-- embed baseline specs with manifest resource names like Microsoft.DotNet.Diagnostics.DataContract.Baseline:net9.0/osx-arm64.jsonc -->
<!-- TODO: [cdac] - make sure we use / not \ on windows, too. -->
<EmbeddedResource Include="$(RepoRoot)docs\design\datacontracts\data\**\*.jsonc" LogicalName="$(BaselineManifestResourcePrefix)%(RecursiveDir)%(Filename)%(Extension)" WithCulture="false" />
</ItemGroup>
</Project>
Loading

0 comments on commit 32d956b

Please sign in to comment.