diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 78d06c501e8835..fa97153cf17731 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "9.0.0-prerelease.24208.1", + "version": "9.0.0-prerelease.24229.1", "commands": [ "xharness" ] diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000000..806f7fad67b045 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 5 + labels: + - area-codeflow + ignore: + - dependency-name: "actions/checkout" + update-types: ["version-update:semver-patch","version-update:semver-minor"] diff --git a/.github/workflows/aspnetcore-sync.yml b/.github/workflows/aspnetcore-sync.yml index 01aa3dfdabca60..582f371cf9ab49 100644 --- a/.github/workflows/aspnetcore-sync.yml +++ b/.github/workflows/aspnetcore-sync.yml @@ -16,14 +16,14 @@ jobs: runs-on: windows-latest steps: - name: Checkout aspnetcore - uses: actions/checkout@v2.0.0 + uses: actions/checkout@v4 with: # Test this script using changes in a fork repository: 'dotnet/aspnetcore' path: aspnetcore ref: main - name: Checkout runtime - uses: actions/checkout@v2.0.0 + uses: actions/checkout@v4 with: # Test this script using changes in a fork repository: 'dotnet/runtime' @@ -42,7 +42,7 @@ jobs: mkdir ..\artifacts git status > ..\artifacts\status.txt git diff > ..\artifacts\diff.txt - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v4 with: name: results path: artifacts @@ -57,7 +57,7 @@ jobs: - name: Send PR if: steps.check.outputs.changed == 'true' # https://github.com/marketplace/actions/create-pull-request - uses: dotnet/actions-create-pull-request@v3 + uses: dotnet/actions-create-pull-request@v4 with: token: ${{ secrets.GITHUB_TOKEN }} path: .\runtime diff --git a/.github/workflows/bump-chrome-version.yml b/.github/workflows/bump-chrome-version.yml index fc2f09cf3d01f7..e1d1e89658ca02 100644 --- a/.github/workflows/bump-chrome-version.yml +++ b/.github/workflows/bump-chrome-version.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Branch run: | git config user.name github-actions[bot] @@ -47,7 +47,7 @@ jobs: - name: Create PR if: steps.check_changes.outputs.has_changes == 'true' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const { CHROME_LINUX_VER, CHROME_WIN_VER } = process.env; diff --git a/Directory.Build.props b/Directory.Build.props index b1ac2559f9ed1e..c6bae2a825b1bf 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -56,18 +56,22 @@ - eng/native/configurecompiler.cmake - eng/native/build-commons.sh - src/native/libs/build-native.sh - - src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs + - src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.cs - src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets + - src/mono/mono/tools/offsets-tool/offsets-tool.py + - src/mono/msbuild/apple/build/AppleBuild.targets - src/installer/pkg/sfx/bundle/shared-framework-distribution-template-x64.xml - src/installer/pkg/sfx/bundle/shared-framework-distribution-template-arm64.xml + - src/tasks/AotCompilerTask/MonoAOTCompiler.props + - src/tasks/AppleAppBuilder/Xcode.cs - src/tasks/MobileBuildTasks/Apple/AppleProject.cs - dotnet/installer repo > src/redist/targets/GeneratePKG.targets --> 21 - 11.0 - 11.0 - 10.15 - 11.0 + 12.2 + 12.2 + 12.0 + 15.0 @@ -180,7 +184,9 @@ $([MSBuild]::NormalizePath('$(TestExclusionListTasksDir)', 'TestExclusionListTasks.dll')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'coreclr', '$(TargetOS).$(TargetArchitecture).$(RuntimeConfiguration)')) $(CoreCLRToolPath) + $([MSBuild]::NormalizeDirectory($(ArtifactsObjDir), 'wasmtime')) true $([MSBuild]::NormalizeDirectory($(WasmProjectRoot), 'build')) @@ -397,12 +403,10 @@ true true - true - true - true + true - false + false @@ -413,7 +417,7 @@ '$(IsReferenceAssemblyProject)' != 'true' and '$(IsGeneratorProject)' != 'true' and '$(IsTestProject)' != 'true' and - '$(IsPublishedAppTestProject)' != 'true' and + '$(IsTrimmingTestProject)' != 'true' and '$(IsTestSupportProject)' != 'true' and '$(UsingMicrosoftDotNetSharedFrameworkSdk)' != 'true' and '$(MSBuildProjectExtension)' != '.pkgproj' and @@ -464,7 +468,7 @@ - + true diff --git a/docs/coding-guidelines/coding-style.md b/docs/coding-guidelines/coding-style.md index d584de83130279..32dd1ec8bb65e5 100644 --- a/docs/coding-guidelines/coding-style.md +++ b/docs/coding-guidelines/coding-style.md @@ -36,7 +36,7 @@ The general rule we follow is "use Visual Studio defaults". An [EditorConfig](https://editorconfig.org "EditorConfig homepage") file (`.editorconfig`) has been provided at the root of the runtime repository, enabling C# auto-formatting conforming to the above guidelines. -We also use the [.NET Codeformatter Tool](https://github.com/dotnet/codeformatter) to ensure the code base maintains a consistent style over time, the tool automatically fixes the code base to conform to the guidelines outlined above. +We also use the [dotnet-format tool](https://learn.microsoft.com/dotnet/core/tools/dotnet-format) to ensure the code base maintains a consistent style over time, the tool automatically fixes the code base to conform to the guidelines outlined above. ### Example File: diff --git a/docs/design/datacontracts/contract-descriptor.md b/docs/design/datacontracts/contract-descriptor.md index 1e3ddabd6dd735..fbd58eb33eb9a5 100644 --- a/docs/design/datacontracts/contract-descriptor.md +++ b/docs/design/datacontracts/contract-descriptor.md @@ -24,9 +24,9 @@ struct DotNetRuntimeContractDescriptor uint32_t flags; uint32_t descriptor_size; const char *descriptor; - uint32_t aux_data_count; + uint32_t pointer_data_count; uint32_t pad0; - uintptr_t *aux_data; + uintptr_t *pointer_data; }; ``` @@ -45,7 +45,7 @@ reserved bits should be written as zero. Diagnostic tooling may ignore non-zero The `descriptor` is a pointer to a UTF-8 JSON string described in [data descriptor physical layout](./data_descriptor.md#Physical_JSON_descriptor). The total number of bytes is given by `descriptor_size`. -The auxiliary data for the JSON descriptor is stored at the location `aux_data` in `aux_data_count` pointer-sized slots. +The auxiliary data for the JSON descriptor is stored at the location `pointer_data` in `pointer_data_count` pointer-sized slots. ### Architecture properties @@ -83,7 +83,7 @@ a JSON integer constant. "globals": { "FEATURE_COMINTEROP": 0, - "s_pThreadStore": [ 0 ] // indirect from aux data offset 0 + "s_pThreadStore": [ 0 ] // indirect from pointer data offset 0 }, "contracts": {"Thread": 1, "GCHandle": 1, "ThreadStore": 1} } diff --git a/docs/design/datacontracts/data/empty.jsonc b/docs/design/datacontracts/data/empty.jsonc new file mode 100644 index 00000000000000..29d15882a36b81 --- /dev/null +++ b/docs/design/datacontracts/data/empty.jsonc @@ -0,0 +1,4 @@ +// the empty baseline data descriptor +{ + "version": 0 +} diff --git a/docs/design/mono/mono-manpage-1.md b/docs/design/mono/mono-manpage-1.md new file mode 100644 index 00000000000000..8f5bd56abb3d8e --- /dev/null +++ b/docs/design/mono/mono-manpage-1.md @@ -0,0 +1,2012 @@ +# Mono Manual Page + +Copyright 2003 Ximian, Inc. \ +Copyright 2004-2011 Novell, Inc. \ +Copyright 2011-2012 Xamarin Inc \ +Copyright 2013 7digital Media Ltd. \ +Copyright (c) .NET Foundation and Contributors + +Author: \ +Miguel de Icaza (miguel@gnu.org) + +## NAME + +mono - Mono's ECMA-CLI native code generator (Just-in-Time and +Ahead-of-Time) + +## SYNOPSIS + +**mono \[options\] file \[arguments...\]** + +**mono-sgen \[options\] file \[arguments...\]** + +## DESCRIPTION + +*mono* is a runtime implementation of the ECMA Common Language +Infrastructure. This can be used to run ECMA and .NET applications. + +The runtime loads the specified *file* and optionally passes the +*arguments* to it. The *file* is an ECMA assembly. They typically have a +.exe or .dll extension. + +These executables can reference additional functionality in the form of +assembly references. By default those assembly references are resolved +as follows: the **mscorlib.dll** is resolved from the system profile +that is configured by Mono, and other assemblies are loaded from the +Global Assembly Cache (GAC). + +The runtime contains a native code generator that transforms the Common +Intermediate Language into native code. + +The code generator can operate in two modes: Just-in-time compilation +(JIT) or Ahead-of-time compilation (AOT). Since code can be dynamically +loaded, the runtime environment and the JIT are always present, even if +code is compiled ahead of time. + +The runtime provides a number of configuration options for running +applications, for developing and debugging, and for testing and +debugging the runtime itself. + +The *mono* command uses the moving and generational SGen garbage +collector while the *mono-boehm* command uses the conservative Boehm +garbage collector. + +## PORTABILITY + +On Unix-based systems, Mono provides a mechanism to emulate the +Windows-style file access, this includes providing a case insensitive +view of the file system, directory separator mapping (from \\ to /) and +stripping the drive letters. + +This functionality is enabled by setting the **MONO_IOMAP** environment +variable to one of **all, drive** and **case.** + +See the description for **MONO_IOMAP** in the environment variables +section for more details. + +## METHOD DESCRIPTIONS + +A number of diagnostic command line options take as argument a method +description. A method description is a textual representation that can +be used to uniquely identify a method. The syntax is as follows: + + [W:][namespace]classname:methodname[(arguments)] + +The values in brackets are optional, like the namespace and the +arguments. The arguments themselves are either empty, or a +comma-separated list of arguments. Both the **classname** and +**methodname** can be set to the special value '\*' to match any values +(Unix shell users should escape the argument to avoid the shell +interpreting this). + +The arguments, if present should be a comma separated list of types +either a full typename, or for built-in types it should use the +low-level ILAsm type names for the built-in types, like 'void', 'char', +'bool', 'byte', 'sbyte', 'uint16', 'int16', 'uint', + +Pointer types should be the name of the type, followed by a '\*', arrays +should be the typename followed by '\[' one or more commas (to indicate +the rank of the array), and '\]'. + +Generic values should use '\<', one or more type names, separated by +both a comma and a space and '\>'. + +By-reference arguments should include a "&" after the typename. + +If the method description is prefixed by 'W:' (or 'w:'), then it will +match a *wrapper* method that may be created by the runtime for the +specified method. (For example imported P/Invoke methods may have a +wrapper generated by the runtime.) + + +Examples: + + *:ctor(int) // All constructors that take an int as an argument + *:Main // Methods named Main in any class + *:Main(string[]) // Methods named Main that take a string array in any class + W:UnixSignal:install // Wrappers for the UnixSignal.install DllImport + +## RUNTIME OPTIONS + +The following options are available: + +**--aot**, **--aot\[=options\]** +This option is used to precompile the CIL code in the specified assembly +to native code. The generated code is stored in a file with the +extension .so. This file will be automatically picked up by the runtime +when the assembly is executed. + +Ahead-of-Time compilation is most useful if you use it in combination +with the -O=all,-shared flag which enables all of the optimizations in +the code generator to be performed. Some of those optimizations are not +practical for Just-in-Time compilation since they might be very time +consuming. + +Unlike the .NET Framework, Ahead-of-Time compilation will not generate +domain independent code: it generates the same code that the +Just-in-Time compiler would produce. Since most applications use a +single domain, this is fine. If you want to optimize the generated code +for use in multi-domain applications, consider using the -O=shared flag. + +This pre-compiles the methods, but the original assembly is still +required to execute as this one contains the metadata and exception +information which is not available on the generated file. When +precompiling code, you might want to compile with all optimizations +(-O=all). Pre-compiled code is position independent code. + +Precompilation is just a mechanism to reduce startup time, increase code +sharing across multiple mono processes and avoid just-in-time +compilation program startup costs. The original assembly must still be +present, as the metadata is contained there. + +AOT code typically can not be moved from one computer to another +(CPU-specific optimizations that are detected at runtime) so you should +not try to move the pre-generated assemblies or package the +pre-generated assemblies for deployment. + +A few options are available as a parameter to the **--aot** command line +option. The options are separated by commas, and more than one can be +specified: + +> *asmonly* +> Instructs the AOT compiler to output assembly code instead of an +> object file. +> +> *bind-to-runtime-version* +> +> If specified, forces the generated AOT files to be bound to the +> runtime version of the compiling Mono. This will prevent the AOT files +> from being consumed by a different Mono runtime. +> +> *data-outfile=FILE.dll.aotdata* +> +> This instructs the AOT code generator to output certain data +> constructs into a separate file. This can reduce the executable images +> some five to twenty percent. Developers need to then ship the +> resulting aotdata as a resource and register a hook to load the data +> on demand by using the *mono_install_load_aot_data_hook* method. +> +> *direct-icalls* +> +> When this option is specified, icalls (internal calls made from the +> standard library into the mono runtime code) are invoked directly +> instead of going through the operating system symbol lookup operation. +> This requires use of the *static* option. +> +> *direct-pinvoke* +> +> When this option is specified, P/Invoke methods are invoked directly +> instead of going through the operating system symbol lookup operation. +> This requires use of the *static* option. +> +> *dwarfdebug* +> Instructs the AOT compiler to emit DWARF debugging information. When +> used together with the nodebug option, only DWARF debugging +> information is emitted, but not the information that can be used at +> runtime. +> +> *full* +> +> This creates binaries which can be used with the --full-aot option. +> +> *hybrid* +> +> This creates binaries which can be used with the --hybrid-aot option. +> +> *llvm* +> AOT will be performed with the LLVM backend instead of the Mono +> backend where possible. This will be slower to compile but most likely +> result in a performance improvement. +> +> *llvmonly* +> AOT will be performed with the LLVM backend exclusively and the Mono +> backend will not be used. The only output in this mode will be the +> bitcode file normally specified with the *llvm-outfile* option. Use of +> *llvmonly* automatically enables the *full* and *llvm* options. This +> feature is experimental. +> +> *llvmopts=\[options\]* +> Use this option to add more flags to the built-in set of flags passed +> to the LLVM optimizer. When you invoke the *mono* command with the +> *--aot=llvm* it displays the current list of flags that are being +> passed to the *opt* command. *The list of possible flags that can be +> passed can be* obtained by calling the bundled *opt* program that +> comes with Mono, and calling it like this: +> +> +> +> +> opt --help +> +> *llvmllc=\[options\]* +> Use this option to add more flags to the built-in set of flags passed +> to the LLVM static compiler (llc). The list of possible flags that can +> be passed can be obtained by calling the bundled *llc* program that +> comes with Mono, and calling it like this: +> +> +> +> +> llc --help +> +> *mcpu=\[native o generic\]* +> cpu=native allows AOT mode to use all instructions current CPU +> supports, e.g. AVX2, SSE42, etc. Default value is 'generic'. +> *mattr=\[cpu feature\]* Allows AOT code generator to use specified CPU +> features where possible including \`System.Runtime.Intrinsics.\*'. +> E.g. \`mattr=+avx2,mattr=-lzcnt' unlocks sse1-4.2, avx1-2 and disables +> lzcnt. It's useful for cross-compilation or when it's not possible to +> use \`-mcpu=native' (which enables all cpu feature current cpu has). +> *llvm-outfile=\[filename\]* Gives the path for the temporary LLVM +> bitcode file created during AOT. *dedup* Each AOT module will +> typically contain the code for inflated methods and wrappers that are +> called by code in that module. In dedup mode, we identify and skip +> compiling all of those methods. When using this mode with fullaot, +> dedup-include is required or these methods will remain missing. +> +> *dedup-include=\[filename\]* +> In dedup-include mode, we are in the pass of compilation where we +> compile the methods that we had previously skipped. All of them are +> emitted into the assembly that is passed as this option. We +> consolidate the many duplicate skipped copies of the same method into +> one. +> +> +> +> *info* +> Print the architecture the AOT in this copy of Mono targets and quit. +> +> *interp* +> Generates all required wrappers, so that it is possible to run +> --interpreter without any code generation at runtime. This option only +> makes sense with **mscorlib.dll**. Embedders can set +> +> *depfile=\[filename\]* +> Outputs a gcc -M style dependency file. +> +> mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP); +> +> +> +> *ld-flags* +> Additional flags to pass to the C linker (if the current AOT mode +> calls for invoking it). +> +> *llvm-path=\* +> Same for the llvm tools 'opt' and 'llc'. +> +> *msym-dir=\* +> Instructs the AOT compiler to generate offline sequence points .msym +> files. The generated .msym files will be stored into a subfolder of +> \ named as the compilation AOTID. +> +> *mtriple=\* +> Use the GNU style target triple \ to determine some code +> generation options, i.e. --mtriple=armv7-linux-gnueabi will generate +> code that targets ARMv7. This is currently only supported by the ARM +> backend. In LLVM mode, this triple is passed on to the LLVM llc +> compiler. +> +> *nimt-trampolines=\[number\]* +> When compiling in full aot mode, the IMT trampolines must be +> precreated in the AOT image. You can add additional method trampolines +> with this argument. Defaults to 512. +> +> *ngsharedvt-trampolines=\[number\]* +> When compiling in full aot mode, the value type generic sharing +> trampolines must be precreated in the AOT image. You can add +> additional method trampolines with this argument. Defaults to 512. +> +> *nodebug* +> Instructs the AOT compiler to not output any debugging information. +> +> *no-direct-calls* +> This prevents the AOT compiler from generating a direct calls to a +> method. The AOT compiler usually generates direct calls for certain +> methods that do not require going through the PLT (for example, +> methods that are known to not require a hook like a static +> constructor) or call into simple internal calls. +> +> *nrgctx-trampolines=\[number\]* +> When compiling in full aot mode, the generic sharing trampolines must +> be precreated in the AOT image. You can add additional method +> trampolines with this argument. Defaults to 4096. +> +> *nrgctx-fetch-trampolines=\[number\]* +> When compiling in full aot mode, the generic sharing fetch trampolines +> must be precreated in the AOT image. You can add additional method +> trampolines with this argument. Defaults to 128. +> +> *ntrampolines=\[number\]* +> When compiling in full aot mode, the method trampolines must be +> precreated in the AOT image. You can add additional method trampolines +> with this argument. Defaults to 4096. +> +> *outfile=\[filename\]* +> Instructs the AOT compiler to save the output to the specified file. +> +> *print-skipped-methods* +> If the AOT compiler cannot compile a method for any reason, enabling +> this flag will output the skipped methods to the console. +> +> *profile=\[file\]* +> Specify a file to use for profile-guided optimization. See the **AOT +> profiler** sub-section. To specify multiple files, include the +> *profile* option multiple times. +> +> *profile-only* +> AOT \*only\* the methods described in the files specified with the +> *profile* option. See the **AOT profiler** sub-section. +> +> *readonly-value=namespace.typename.fieldname=type/value* +> Override the value of a static readonly field. Usually, during JIT +> compilation, the static constructor is ran eagerly, so the value of a +> static readonly field is known at compilation time and the compiler +> can do a number of optimizations based on it. During AOT, instead, the +> static constructor can't be ran, so this option can be used to set the +> value of such a field and enable the same set of optimizations. Type +> can be any of i1, i2, i4 for integers of the respective sizes (in +> bytes). Note that signed/unsigned numbers do not matter here, just the +> storage size. This option can be specified multiple times and it +> doesn't prevent the static constructor for the type defining the field +> to execute with the usual rules at runtime (hence possibly computing a +> different value for the field). +> +> *save-temps,keep-temps* +> Instructs the AOT compiler to keep temporary files. +> +> *soft-debug* +> This instructs the compiler to generate sequence point checks that +> allow Mono's soft debugger to debug applications even on systems where +> it is not possible to set breakpoints or to single step (certain +> hardware configurations like the cell phones and video gaming +> consoles). +> +> *static* +> Create an ELF object file (.o) or .s file which can be statically +> linked into an executable when embedding the mono runtime. When this +> option is used, the object file needs to be registered with the +> embedded runtime using the mono_aot_register_module function which +> takes as its argument the mono_aot_module\_\\_info +> global symbol from the object file: +> +> extern void *mono_aot_module_hello_info; +> +> mono_aot_register_module (mono_aot_module_hello_info); +> +> +> +> *stats* +> Print various stats collected during AOT compilation. +> +> *temp-path=\[path\]* +> Explicitly specify path to store temporary files created during AOT +> compilation. +> +> *threads=\[number\]* +> This is an experimental option for the AOT compiler to use multiple +> threads when compiling the methods. +> +> *tool-prefix=\* +> Prepends \ to the name of tools ran by the AOT compiler, i.e. +> 'as'/'ld'. For example, --tool=prefix=arm-linux-gnueabi- will make the +> AOT compiler run +> +> +> +> *ld-name=NAME* +> One of the tools used for AOT builds is the linker. Its name differs +> between various systems and it may happen that the assumed default +> name of the binary is not present. If the toolchain used does not have +> a linker with the default name (e.g. Android NDK r22 does not have the +> default 'ld' linker prefixed with 'tool-prefix' above, instead it has +> prefixed 'ld.gold' and 'ld.bfd' linkers) this option can be used to +> set the linker binary name. It will be prefixed with 'tool-prefix' to +> form the full linker executable name. +> +> *verbose* +> Prints additional information about type loading failures. +> +> *write-symbols,no-write-symbols* +> Instructs the AOT compiler to emit (or not emit) debug symbol +> information. +> +> *no-opt* +> Instructs the AOT compiler tot no call opt when compiling with LLVM. +> +> For more information about AOT, see: +> http://www.mono-project.com/docs/advanced/aot/ + +**--aot-path=PATH** +List of additional directories to search for AOT images. + +**--apply-bindings=FILE** +Apply the assembly bindings from the specified configuration file when +running the AOT compiler. This is useful when compiling an auxiliary +assembly that is referenced by a main assembly that provides a +configuration file. For example, if app.exe uses lib.dll then in order +to make the assembly bindings from app.exe.config available when +compiling lib.dll ahead of time, use: + + + + mono --apply-bindings=app.exe.config --aot lib.dll + +**--assembly-loader=MODE** +If mode is **strict**, Mono will check that the public key token, +culture and version of a candidate assembly matches the requested strong +name. If mode is **legacy**, as long as the name matches, the candidate +will be allowed. **strict** is the behavior consistent with .NET +Framework but may break some existing mono-based applications. The +default is **legacy**. + +**--attach=\[options\]** +Currently the only option supported by this command line argument is +**disable** which disables the attach functionality. + +**--config filename** +Load the specified configuration file instead of the default one(s). The +default files are /etc/mono/config and ~/.mono/config or the file +specified in the MONO_CONFIG environment variable, if set. See the +mono-config(5) man page for details on the format of this file. + +**--debugger-agent=\[options\]** +This instructs the Mono runtime to start a debugging agent inside the +Mono runtime and connect it to a client user interface will control the +Mono process. This option is typically used by IDEs, like the +MonoDevelop or Visual Studio IDEs. + +The configuration is specified using one of more of the following +options: + +> *address=host:port* +> +> Use this option to specify the IP address where your debugger client +> is listening to. +> +> *loglevel=LEVEL* +> +> Specifies the diagnostics log level for +> +> *logfile=filename* +> +> Used to specify the file where the log will be stored, it defaults to +> standard output. +> +> *server=\[y/n\]* +> Defaults to no, with the default option Mono will actively connect to +> the host/port configured with the **address** option. If you set it to +> 'y', it instructs the Mono runtime to start debugging in server mode, +> where Mono actively waits for the debugger front end to connect to the +> Mono process. Mono will print out to stdout the IP address and port +> where it is listening. +> +> *setpgid=\[y/n\]* +> If set to yes, Mono will call **setpgid(0, 0)** on startup, if that +> function is available on the system. This is useful for ensuring that +> signals delivered to a process that is executing the debuggee are not +> propagated to the debuggee, e.g. when Ctrl-C sends **SIGINT** to the +> **sdb** tool. +> +> *suspend=\[y/n\]* +> Defaults to yes, with the default option Mono will suspend the vm on +> startup until it connects successfully to a debugger front end. If you +> set it to 'n', in conjunction with **server=y**, it instructs the Mono +> runtime to run as normal, while caching metadata to send to the +> debugger front end on connection.. +> +> *transport=transport_name* +> +> This is used to specify the transport that the debugger will use to +> communicate. It must be specified and currently requires this to be +> 'dt_socket'. + +**--desktop** +Configures the virtual machine to be better suited for desktop +applications. Currently this sets the GC system to avoid expanding the +heap as much as possible at the expense of slowing down garbage +collection a bit. + +**--full-aot** +This flag instructs the Mono runtime to not generate any code at runtime +and depend exclusively on the code generated from using mono --aot=full +previously. This is useful for platforms that do not permit dynamic code +generation, or if you need to run assemblies that have been stripped of +IL (for example using mono-cil-strip). + +Notice that this feature will abort execution at runtime if a codepath +in your program, or Mono's class libraries attempts to generate code +dynamically. You should test your software upfront and make sure that +you do not use any dynamic features. + +**--full-aot-interp** +Same as --full-aot with fallback to the interpreter. + +**--gc=boehm**, **--gc=sgen** +Selects the Garbage Collector engine for Mono to use, Boehm or SGen. +Currently this merely ensures that you are running either the *mono* or +*mono-sgen* commands. This flag can be set in the **MONO_ENV_OPTIONS** +environment variable to force all of your child processes to use one +particular kind of GC with the Mono runtime. + +**--gc-debug=\[options\]** +Command line equivalent of the **MONO_GC_DEBUG** environment variable. + +**--gc-params=\[options\]** +Command line equivalent of the **MONO_GC_PARAMS** environment variable. + +**--arch=32**, **--arch=64** +(Mac OS X only): Selects the bitness of the Mono binary used, if +available. If the binary used is already for the selected bitness, +nothing changes. If not, the execution switches to a binary with the +selected bitness suffix installed side by side (for example, '/bin/mono +--arch=64' will switch to '/bin/mono64' iff '/bin/mono' is a 32-bit +build). + +**--help**, **-h** +Displays usage instructions. + +**--interpreter** +The Mono runtime will use its interpreter to execute a given assembly. +The interpreter is usually slower than the JIT, but it can be useful on +platforms where code generation at runtime is not allowed. + +**--hybrid-aot** +This flag allows the Mono runtime to run assemblies that have been +stripped of IL, for example using mono-cil-strip. For this to work, the +assembly must have been AOT compiled with --aot=hybrid. + +This flag is similar to --full-aot, but it does not disable the JIT. +This means you can use dynamic features such as System.Reflection.Emit. + +**--llvm** +If the Mono runtime has been compiled with LLVM support (not available +in all configurations), Mono will use the LLVM optimization and code +generation engine to JIT or AOT compile. + +For more information, consult: +http://www.mono-project.com/docs/advanced/mono-llvm/ + +**--ffast-math** +This flag allows Mono and LLVM to apply aggressive floating point +optimizations. Can break IEEE754 compliance. + +**--nollvm** +When using a Mono that has been compiled with LLVM support, it forces +Mono to fallback to its JIT engine and not use the LLVM backend. + +**--optimize=MODE**, **-O=MODE** +MODE is a comma separated list of optimizations. They also allow +optimizations to be turned off by prefixing the optimization name with a +minus sign. + +In general, Mono has been tuned to use the default set of flags, before +using these flags for a deployment setting, you might want to actually +measure the benefits of using them. + +The following optimization flags are implemented in the core engine: + + abcrem Array bound checks removal + all Turn on all optimizations + aot Usage of Ahead Of Time compiled code + branch Branch optimizations + cfold Constant folding + cmov Conditional moves [arch-dependency] + deadce Dead code elimination + consprop Constant propagation + copyprop Copy propagation + fcmov Fast x86 FP compares [arch-dependency] + float32 Perform 32-bit float arithmetic using 32-bit operations + gshared Enable generic code sharing. + inline Inline method calls + intrins Intrinsic method implementations + linears Linear scan global reg allocation + leaf Leaf procedures optimizations + loop Loop related optimizations + peephole Peephole postpass + precomp Precompile all methods before executing Main + sched Instruction scheduling + shared Emit per-domain code + sse2 SSE2 instructions on x86 [arch-dependency] + tailc Tail recursion and tail calls + +For example, to enable all the optimization but dead code elimination +and inlining, you can use: + + -O=all,-deadce,-inline + +The flags that are flagged with \[arch-dependency\] indicate that the +given option if used in combination with Ahead of Time compilation +(--aot flag) would produce pre-compiled code that will depend on the +current CPU and might not be safely moved to another computer. + +> The following optimizations are supported +> +> *float32* +> Requests that the runtime performn 32-bit floating point operations +> using only 32-bits. By default the Mono runtime tries to use the +> highest precision available for floating point operations, but while +> this might render better results, the code might run slower. This +> options also affects the code generated by the LLVM backend. +> +> *inline* +> Controls whether the runtime should attempt to inline (the default), +> or not inline methods invocations + +**--response=FILE** Provides a response file, this instructs the Mono +command to read other command line options from the specified file, as +if the options had been specified on the command line. Useful when you +have very long command lines. + +**--runtime=VERSION** +Mono supports different runtime versions. The version used depends on +the program that is being run or on its configuration file (named +program.exe.config). This option can be used to override such +autodetection, by forcing a different runtime version to be used. Note +that this should only be used to select a later compatible runtime +version than the one the program was compiled against. A typical usage +is for running a 1.1 program on a 2.0 version: + + mono --runtime=v2.0.50727 program.exe + +**--server** +Configures the virtual machine to be better suited for server operations +(currently, allows a heavier threadpool initialization). + +**--use-map-jit** +Instructs Mono to generate code using MAP_JIT on MacOS. Necessary for +bundled applications. + +**--verify-all** +Verifies mscorlib and assemblies in the global assembly cache for valid +IL, and all user code for IL verifiability. + +This is different from **--security**'s verifiable or validil in that +these options only check user code and skip mscorlib and assemblies +located on the global assembly cache. + +**-V**, **--version** +Prints JIT version information (system configuration, release number and +branch names if available). + +**--version=number** +Print version number only. + +## DEVELOPMENT OPTIONS + +The following options are used to help when developing a JITed +application. + +**--debug**, **--debug=OPTIONS** +Turns on the debugging mode in the runtime. If an assembly was compiled +with debugging information, it will produce line number information for +stack traces. + +The optional OPTIONS argument is a comma separated list of debugging +options. These options are turned off by default since they generate +much larger and slower code at runtime. + +The following options are supported: +*casts* +Produces a detailed error when throwing a InvalidCastException. This +option needs to be enabled as this generates more verbose code at +execution time. + +*mdb-optimizations* +Disable some JIT optimizations which are usually only disabled when +running inside the debugger. This can be helpful if you want to attach +to the running process with mdb. + +*gdb* +Generate and register debugging information with gdb. This is only +supported on some platforms, and only when using gdb 7.0 or later. + +**--profile**\[=*profiler*\[:*profiler_args*\]\] +Loads a profiler module with the given arguments. For more information, +see the **PROFILING** section. + +This option can be used multiple times; each time will load an +additional profiler module. + +**--trace\[=expression\]** +Shows method names as they are invoked. By default all methods are +traced. + +The trace can be customized to include or exclude methods, classes or +assemblies. A trace expression is a comma separated list of targets, +each target can be prefixed with a minus sign to turn off a particular +target. The words \`program', \`all' and \`disabled' have special +meaning. \`program' refers to the main program being executed, and +\`all' means all the method calls. + +The \`disabled' option is used to start up with tracing disabled. It can +be enabled at a later point in time in the program by sending the +SIGUSR2 signal to the runtime. + +Assemblies are specified by their name, for example, to trace all calls +in the System assembly, use: + + + mono --trace=System app.exe + +Classes are specified with the T: prefix. For example, to trace all +calls to the System.String class, use: + + + mono --trace=T:System.String app.exe + +And individual methods are referenced with the M: prefix, and the +standard method notation: + + + mono --trace=M:System.Console:WriteLine app.exe + +Exceptions can also be traced, it will cause a stack trace to be printed +every time an exception of the specified type is thrown. The exception +type can be specified with or without the namespace, and to trace all +exceptions, specify 'all' as the type name. + + + mono --trace=E:System.Exception app.exe + +As previously noted, various rules can be specified at once: + + + mono --trace=T:System.String,T:System.Random app.exe + +You can exclude pieces, the next example traces calls to System.String +except for the System.String:Concat method. + + + mono --trace=T:System.String,-M:System.String:Concat + +You can trace managed to unmanaged transitions using the wrapper +qualifier: + + + mono --trace=wrapper app.exe + +Finally, namespaces can be specified using the N: prefix: + + + mono --trace=N:System.Xml + +**--no-x86-stack-align** +Don't align stack frames on the x86 architecture. By default, Mono +aligns stack frames to 16 bytes on x86, so that local floating point and +SIMD variables can be properly aligned. This option turns off the +alignment, which usually saves one instruction per call, but might +result in significantly lower floating point and SIMD performance. + +**--jitmap** +Generate a JIT method map in a /tmp/perf-PID.map file. This file is then +used, for example, by the perf tool included in recent Linux kernels. +Each line in the file has: + + + + + HEXADDR HEXSIZE methodname + +Currently this option is only supported on Linux. + +## JIT MAINTAINER OPTIONS + +The maintainer options are only used by those developing the runtime +itself, and not typically of interest to runtime users or developers. + +**--bisect=optimization:filename** +This flag is used by the automatic optimization bug bisector. It takes +an optimization flag and a filename of a file containing a list of full +method names, one per line. When it compiles one of the methods in the +file it will use the optimization given, in addition to the +optimizations that are otherwise enabled. Note that if the optimization +is enabled by default, you should disable it with \`-O\`, otherwise it +will just apply to every method, whether it's in the file or not. + +**--break method** +Inserts a breakpoint before the method whose name is \`method' +(namespace.class:methodname). Use \`Main' as method name to insert a +breakpoint on the application's main method. You can use it also with +generics, for example "System.Collections.Generic.Queue\`1:Peek" + +**--breakonex** +Inserts a breakpoint on exceptions. This allows you to debug your +application with a native debugger when an exception is thrown. + +**--compile name** +This compiles a method (namespace.name:methodname), this is used for +testing the compiler performance or to examine the output of the code +generator. + +**--compile-all** +Compiles all the methods in an assembly. This is used to test the +compiler performance or to examine the output of the code generator + +**--graph=TYPE METHOD** +This generates a postscript file with a graph with the details about the +specified method (namespace.name:methodname). This requires \`dot' and +ghostview to be installed (it expects Ghostview to be called "gv"). + +The following graphs are available: + + cfg Control Flow Graph (CFG) + dtree Dominator Tree + code CFG showing code + ssa CFG showing code after SSA translation + optcode CFG showing code after IR optimizations + +Some graphs will only be available if certain optimizations are turned +on. + +**--ncompile** +Instruct the runtime on the number of times that the method specified by +--compile (or all the methods if --compile-all is used) to be compiled. +This is used for testing the code generator performance. + +**--stats=\[method\]** +Displays information about the work done by the runtime during the +execution of an application. If a method (namespace.name:methodname) is +specified, it will display that information when the method is first run +in addition to the end of program execution. + +**--wapi=hps\|semdel** +Perform maintenance of the process shared data. + +semdel will delete the global semaphore. + +hps will list the currently used handles. + +**-v**, **--verbose** +Increases the verbosity level, each time it is listed, increases the +verbosity level to include more information (including, for example, a +disassembly of the native code produced, code selector info etc.). + +## ATTACH SUPPORT + +The Mono runtime allows external processes to attach to a running +process and load assemblies into the running program. To attach to the +process, a special protocol is implemented in the Mono.Management +assembly. + +With this support it is possible to load assemblies that have an entry +point (they are created with -target:exe or -target:winexe) to be loaded +and executed in the Mono process. + +The code is loaded into the root domain, and it starts execution on the +special runtime attach thread. The attached program should create its +own threads and return after invocation. + +This support allows for example debugging applications by having the +csharp shell attach to running processes. + +## PROFILING + +The Mono runtime includes a profiler API that dynamically loaded +profiler modules and embedders can use to collect performance-related +data about an application. Profiler modules are loaded by passing the +**--profile** command line argument to the Mono runtime. + +Mono ships with a few profiler modules, of which the **log** profiler is +the most feature-rich. It is also the default profiler if the *profiler* +argument is not given, or if **default** is given. It is possible to +write your own profiler modules; see the **Custom profilers** +sub-section. + +### Log profiler + +The log profiler can be used to collect a lot of information about a +program running in the Mono runtime. This data can be used (both while +the process is running and later) to do analyses of the program +behavior, determine resource usage, performance issues or even look for +particular execution patterns. + +This is accomplished by logging the events provided by the Mono runtime +through the profiler API and periodically writing them to a file which +can later be inspected with the **mprof-report**(1) tool. + +More information about how to use the log profiler is available on the +**mono-profilers**(1) page, under the **LOG PROFILER** section, as well +as the **mprof-report**(1) page. + +### Coverage profiler + +The code coverage profiler can instrument a program to help determine +which classes, methods, code paths, etc are actually executed. This is +most useful when running a test suite to determine whether the tests +actually cover the code they're expected to. + +More information about how to use the coverage profiler is available on +the **mono-profilers**(1) page, under the **COVERAGE** PROFILER section. + +### AOT profiler + +The AOT profiler can help improve startup performance by logging which +generic instantiations are used by a program, which the AOT compiler can +then use to compile those instantiations ahead of time so that they +won't have to be JIT compiled at startup. + +More information about how to use the AOT profiler is available on the +**mono-profilers**(1) page, under the **AOT PROFILER** section. + +### Custom profilers + +Custom profiler modules can be loaded in exactly the same way as the +standard modules that ship with Mono. They can also access the same +profiler API to gather all kinds of information about the code being +executed. + +For example, to use a third-party profiler called **custom**, you would +load it like this: + + mono --profile=custom program.exe + +You could also pass arguments to it: + + mono --profile=custom:arg1,arg2=arg3 program.exe + +In the above example, Mono will load the profiler from the shared +library called *libmono-profiler-custom.so* (name varies based on +platform, e.g., *libmono-profiler-custom.dylib* on OS X). This profiler +module must be on your dynamic linker library path (**LD_LIBRARY_PATH** +on most systems, **DYLD_LIBRARY_PATH** on OS X). + +For a sample of how to write your own custom profiler, look at the +*samples/profiler/sample.c* file in the Mono source tree. + +## DEBUGGING AIDS + +To debug managed applications, you can use the **mdb** command, a +command line debugger. + +It is possible to obtain a stack trace of all the active threads in Mono +by sending the QUIT signal to Mono, you can do this from the command +line, like this: + + + kill -QUIT pid + +Where pid is the Process ID of the Mono process you want to examine. The +process will continue running afterwards, but its state is not +guaranteed. + +**Important:** this is a last-resort mechanism for debugging +applications and should not be used to monitor or probe a production +application. The integrity of the runtime after sending this signal is +not guaranteed and the application might crash or terminate at any given +point afterwards. + +The **--debug=casts** option can be used to get more detailed +information for Invalid Cast operations, it will provide information +about the types involved. + +You can use the MONO_LOG_LEVEL and MONO_LOG_MASK environment variables +to get verbose debugging output about the execution of your application +within Mono. + +The *MONO_LOG_LEVEL* environment variable if set, the logging level is +changed to the set value. Possible values are "error", "critical", +"warning", "message", "info", "debug". The default value is "error". +Messages with a logging level greater then or equal to the log level +will be printed to stdout/stderr. + +Use "info" to track the dynamic loading of assemblies. + +Use the *MONO_LOG_MASK* environment variable to limit the extent of the +messages you get: If set, the log mask is changed to the set value. +Possible values are "asm" (assembly loader), "type", "dll" (native +library loader), "gc" (garbage collector), "cfg" (config file loader), +"aot" (precompiler), "security" (e.g. Moonlight CoreCLR support), +"threadpool" (thread pool generic), "io-selector" (async socket +operations), "io-layer" (I/O layer - processes, files, sockets, events, +semaphores, mutexes and handles), "io-layer-process", "io-layer-file", +"io-layer-socket", "io-layer-event", "io-layer-semaphore", +"io-layer-mutex", "io-layer-handle" and "all". The default value is +"all". Changing the mask value allows you to display only messages for a +certain component. You can use multiple masks by comma separating them. +For example to see config file messages and assembly loader messages set +you mask to "asm,cfg". + +The following is a common use to track down problems with P/Invoke: + + + $ MONO_LOG_LEVEL="debug" MONO_LOG_MASK="dll" mono glue.exe + +## DEBUGGING WITH LLDB + +If you are using LLDB, you can use the **mono.py** script to print some +internal data structures with it. To use this, add this to your +**\$HOME/.lldbinit** file: + + command script import $PREFIX/lib/mono/lldb/mono.py + +Where \$PREFIX is the prefix value that you used when you configured +Mono (typically /usr). + +Once this is done, then you can inspect some Mono Runtime data +structures, for example: + + (lldb) p method + + (MonoMethod *) $0 = 0x05026ac0 [mscorlib]System.OutOfMemoryException:.ctor() + +## SERIALIZATION + +Mono's XML serialization engine by default will use a reflection-based +approach to serialize which might be slow for continuous processing (web +service applications). The serialization engine will determine when a +class must use a hand-tuned serializer based on a few parameters and if +needed it will produce a customized C# serializer for your types at +runtime. This customized serializer then gets dynamically loaded into +your application. + +You can control this with the MONO_XMLSERIALIZER_THS environment +variable. + +The possible values are **\`no'** to disable the use of a C# customized +serializer, or an integer that is the minimum number of uses before the +runtime will produce a custom serializer (0 will produce a custom +serializer on the first access, 50 will produce a serializer on the 50th +use). Mono will fallback to an interpreted serializer if the serializer +generation somehow fails. This behavior can be disabled by setting the +option **\`nofallback'** (for example: +MONO_XMLSERIALIZER_THS=0,nofallback). + +## ENVIRONMENT VARIABLES + +**GC_DONT_GC** +Turns off the garbage collection in Mono. This should be only used for +debugging purposes + +**HTTP_PROXY** +(Also **http_proxy**) If set, web requests using the Mono Class Library +will be automatically proxied through the given URL. Not supported on +Windows, Mac OS, iOS or Android. See also **NO_PROXY**. + +**LLVM_COUNT** +When Mono is compiled with LLVM support, this instructs the runtime to +stop using LLVM after the specified number of methods are JITed. This is +a tool used in diagnostics to help isolate problems in the code +generation backend. For example **LLVM_COUNT=10** would only compile 10 +methods with LLVM and then switch to the Mono JIT engine. +**LLVM_COUNT=0** would disable the LLVM engine altogether. + +**MONO_ASPNET_INHIBIT_SETTINGSMAP** +Mono contains a feature which allows modifying settings in the .config +files shipped with Mono by using config section mappers. The mappers and +the mapping rules are defined in the \$prefix/etc/mono/2.0/settings.map +file and, optionally, in the settings.map file found in the top-level +directory of your ASP.NET application. Both files are read by System.Web +on application startup, if they are found at the above locations. If you +don't want the mapping to be performed you can set this variable in your +environment before starting the application and no action will be taken. + +**MONO_ASPNET_WEBCONFIG_CACHESIZE** +Mono has a cache of ConfigSection objects for speeding up +WebConfigurationManager queries. Its default size is 100 items, and when +more items are needed, cache evictions start happening. If evictions are +too frequent this could impose unnecessary overhead, which could be +avoided by using this environment variable to set up a higher cache size +(or to lower memory requirements by decreasing it). + +**MONO_CAIRO_DEBUG_DISPOSE** +If set, causes Mono.Cairo to collect stack traces when objects are +allocated, so that the finalization/Dispose warnings include information +about the instance's origin. + +**MONO_CFG_DIR** +If set, this variable overrides the default system configuration +directory (\$PREFIX/etc). It's used to locate machine.config file. + +**MONO_COM** +Sets the style of COM interop. If the value of this variable is "MS" +Mono will use string marhsalling routines from the liboleaut32 for the +BSTR type library, any other values will use the mono-builtin BSTR +string marshalling. + +**MONO_CONFIG** +If set, this variable overrides the default runtime configuration file +(\$PREFIX/etc/mono/config). The --config command line options overrides +the environment variable. + +**MONO_CPU_ARCH** +Override the automatic cpu detection mechanism. Currently used only on +arm. The format of the value is as follows: + + + + + "armvV [thumb[2]]" + +where V is the architecture number 4, 5, 6, 7 and the options can be +currently be "thumb" or "thumb2". Example: + + + MONO_CPU_ARCH="armv4 thumb" mono ... + +**MONO_ARM_FORCE_SOFT_FLOAT** +When Mono is built with a soft float fallback on ARM and this variable +is set to "1", Mono will always emit soft float code, even if a VFP unit +is detected. + +**MONO_DARWIN_USE_KQUEUE_FSW** +Fall back on the kqueue FileSystemWatcher implementation in Darwin. The +default is the FSEvent implementation. + +**MONO_DARWIN_WATCHER_MAXFDS** +This is a debugging aid used to force limits on the kqueue +FileSystemWatcher implementation in Darwin. There is no limit by +default. + +**MONO_DISABLE_MANAGED_COLLATION** +If this environment variable is \`yes', the runtime uses unmanaged +collation (which actually means no culture-sensitive collation). It +internally disables managed collation functionality invoked via the +members of System.Globalization.CompareInfo class. Collation is enabled +by default. + +**MONO_DISABLE_SHARED_AREA** +Unix only: If set, disable usage of shared memory for exposing +performance counters. This means it will not be possible to both +externally read performance counters from this processes or read those +of external processes. + +**MONO_DNS** +When set, enables the use of a fully managed DNS resolver instead of the +regular libc functions. This resolver performs much better when multiple +queries are run in parallel. + +Note that /etc/nsswitch.conf will be ignored. + +**MONO_EGD_SOCKET** +For platforms that do not otherwise have a way of obtaining random bytes +this can be set to the name of a file system socket on which an egd or +prngd daemon is listening. + +**MONO_ENABLE_AIO** +If set, tells mono to attempt using native asynchronous I/O services. If +not set, a default select/poll implementation is used. Currently epoll +and kqueue are supported. + +**MONO_THREADS_SUSPEND** Selects a mechanism that Mono will use to suspend +threads. May be set to "preemptive", "coop", or "hybrid". Threads may +need to be suspended by the debugger, or using some .NET threading APIs, +and most commonly when the SGen garbage collector needs to stop all +threads during a critical phase of garbage collection. Preemptive mode +is the mode that Mono has used historically, going back to the Boehm +days, where the garbage collector would run at any point and suspend +execution of all threads as required to perform a garbage collection. +The cooperative mode on the other hand requires the cooperation of all +threads to stop at a safe point. This makes for an easier to debug +garbage collector and it improves the stability of the runtime because +threads are not suspended when accessing critical resources. In +scenarios where Mono is embedded in another application, cooperative +suspend requires the embedder code to follow coding guidelines in order +to cooperate with the garbage collector. Cooperative suspend in embedded +Mono is currently experimental. Hybrid mode is a combination of the two +that retains better compatability with scenarios where Mono is embedded +in another application: threads that are running managed code or code +that comprises the Mono runtime will be cooperatively suspended, while +threads running embedder code will be preemptively suspended. Hybrid +suspend is the default on some desktop platforms. + +Alternatively, coop and hybrid mode can be enabled at compile time by +using the --enable-cooperative-suspend or --enable-hybrid-suspend flags, +respectively, when calling configure. The **MONO_THREADS_SUSPEND** +environment variable takes priority over the compiled default. + +**MONO_ENABLE_COOP_SUSPEND** +This environment variable is obsolete, but retained for backward +compatibility. Use **MONO_THREADS_SUSPEND** set to "coop" instead. Note +that if configure flags were provided to enable cooperative or hybrid +suspend, this variable is ignored. + +**MONO_ENV_OPTIONS** +This environment variable allows you to pass command line arguments to a +Mono process through the environment. This is useful for example to +force all of your Mono processes to use LLVM or SGEN without having to +modify any launch scripts. + +**MONO_SDB_ENV_OPTIONS** +Used to pass extra options to the debugger agent in the runtime, as they +were passed using --debugger-agent=. + +**MONO_EVENTLOG_TYPE** +Sets the type of event log provider to use (for +System.Diagnostics.EventLog). + +Possible values are: + +> *local\[:path\]* +> +> Persists event logs and entries to the local file system. +> +> The directory in which to persist the event logs, event sources and +> entries can be specified as part of the value. +> +> If the path is not explicitly set, it defaults to +> "/var/lib/mono/eventlog" on unix and "%APPDATA%no\ventlog" on Windows. +> +> *win32* +> +> **Uses the native win32 API to write events and registers event logs +> and** event sources in the registry. This is only available on +> Windows. +> +> On Unix, the directory permission for individual event log and event +> source directories is set to 777 (with +t bit) allowing everyone to +> read and write event log entries while only allowing entries to be +> deleted by the user(s) that created them. +> +> *null* +> +> Silently discards any events. +> +> The default is "null" on Unix (and versions of Windows before NT), and +> "win32" on Windows NT (and higher). + +**MONO_EXTERNAL_ENCODINGS** +If set, contains a colon-separated list of text encodings to try when +turning externally-generated text (e.g. command-line arguments or +filenames) into Unicode. The encoding names come from the list provided +by iconv, and the special case "default_locale" which refers to the +current locale's default encoding. + +When reading externally-generated text strings UTF-8 is tried first, and +then this list is tried in order with the first successful conversion +ending the search. When writing external text (e.g. new filenames or +arguments to new processes) the first item in this list is used, or +UTF-8 if the environment variable is not set. + +The problem with using MONO_EXTERNAL_ENCODINGS to process your files is +that it results in a problem: although its possible to get the right +file name it is not necessarily possible to open the file. In general if +you have problems with encodings in your filenames you should use the +"convmv" program. + +**MONO_GC_PARAMS** +When using Mono with the SGen garbage collector this variable controls +several parameters of the collector. The variable's value is a comma +separated list of words. + +**max-heap-size=***size* +Sets the maximum size of the heap. The size is specified in bytes and +must be a power of two. The suffixes \`k', \`m' and \`g' can be used to +specify kilo-, mega- and gigabytes, respectively. The limit is the sum +of the nursery, major heap and large object heap. Once the limit is +reached the application will receive OutOfMemoryExceptions when trying +to allocate. Not the full extent of memory set in max-heap-size could be +available to satisfy a single allocation due to internal fragmentation. +By default heap limits is disabled and the GC will try to use all +available memory. + +**nursery-size=***size* +Sets the size of the nursery. The size is specified in bytes and must be +a power of two. The suffixes \`k', \`m' and \`g' can be used to specify +kilo-, mega- and gigabytes, respectively. The nursery is the first +generation (of two). A larger nursery will usually speed up the program +but will obviously use more memory. The default nursery size 4 MB. + +**major=***collector* +Specifies which major collector to use. Options are \`marksweep' for the +Mark&Sweep collector, \`marksweep-conc' for concurrent Mark&Sweep and +\`marksweep-conc-par' for parallel and concurrent Mark&Sweep. The +concurrent Mark&Sweep collector is the default. + +**mode=balanced\|throughput\|pause**\[:*max-pause*\] +Specifies what should be the garbage collector's target. The +\`throughput' mode aims to reduce time spent in the garbage collector +and improve application speed, the \`pause' mode aims to keep pause +times to a minimum and it receives the argument *max-pause* which +specifies the maximum pause time in milliseconds that is acceptable and +the \`balanced' mode which is a general purpose optimal mode. + +**soft-heap-limit=***size* +Once the heap size gets larger than this size, ignore what the default +major collection trigger metric says and only allow four nursery size's +of major heap growth between major collections. + +**evacuation-threshold=***threshold* +Sets the evacuation threshold in percent. This option is only available +on the Mark&Sweep major collectors. The value must be an integer in the +range 0 to 100. The default is 66. If the sweep phase of the collection +finds that the occupancy of a specific heap block type is less than this +percentage, it will do a copying collection for that block type in the +next major collection, thereby restoring occupancy to close to 100 +percent. A value of 0 turns evacuation off. + +**(no-)lazy-sweep** +Enables or disables lazy sweep for the Mark&Sweep collector. If enabled, +the sweeping of individual major heap blocks is done piecemeal whenever +the need arises, typically during nursery collections. Lazy sweeping is +enabled by default. + +**(no-)concurrent-sweep** +Enables or disables concurrent sweep for the Mark&Sweep collector. If +enabled, the iteration of all major blocks to determine which ones can +be freed and which ones have to be kept and swept, is done concurrently +with the running program. Concurrent sweeping is enabled by default. + +**stack-mark=***mark-mode* +Specifies how application threads should be scanned. Options are +\`precise\` and \`conservative\`. Precise marking allow the collector to +know what values on stack are references and what are not. Conservative +marking threats all values as potentially references and leave them +untouched. Precise marking reduces floating garbage and can speed up +nursery collection and allocation rate, it has the downside of requiring +a significant extra memory per compiled method. The right option, +unfortunately, requires experimentation. + +**save-target-ratio=***ratio* +Specifies the target save ratio for the major collector. The collector +lets a given amount of memory to be promoted from the nursery due to +minor collections before it triggers a major collection. This amount is +based on how much memory it expects to free. It is represented as a +ratio of the size of the heap after a major collection. Valid values are +between 0.1 and 2.0. The default is 0.5. Smaller values will keep the +major heap size smaller but will trigger more major collections. +Likewise, bigger values will use more memory and result in less frequent +major collections. This option is EXPERIMENTAL, so it might disappear in +later versions of mono. + +**default-allowance-ratio=***ratio* +Specifies the default allocation allowance when the calculated size is +too small. The allocation allowance is how much memory the collector let +be promoted before triggered a major collection. It is a ratio of the +nursery size. Valid values are between 1.0 and 10.0. The default is 4.0. +Smaller values lead to smaller heaps and more frequent major +collections. Likewise, bigger values will allow the heap to grow faster +but use more memory when it reaches a stable size. This option is +EXPERIMENTAL, so it might disappear in later versions of mono. + +**minor=***minor-collector* +Specifies which minor collector to use. Options are \`simple' which +promotes all objects from the nursery directly to the old generation, +\`simple-par' which has same promotion behavior as \`simple' but using +multiple workers and \`split' which lets objects stay longer on the +nursery before promoting. + +**alloc-ratio=***ratio* +Specifies the ratio of memory from the nursery to be use by the alloc +space. This only can only be used with the split minor collector. Valid +values are integers between 1 and 100. Default is 60. + +**promotion-age=***age* +Specifies the required age of an object must reach inside the nursery +before been promoted to the old generation. This only can only be used +with the split minor collector. Valid values are integers between 1 +and 14. Default is 2. + +**(no-)cementing** +Enables or disables cementing. This can dramatically shorten nursery +collection times on some benchmarks where pinned objects are referred to +from the major heap. + +**allow-synchronous-major** +This forbids the major collector from performing synchronous major +collections. The major collector might want to do a synchronous +collection due to excessive fragmentation. Disabling this might trigger +OutOfMemory error in situations that would otherwise not happen. + +**MONO_GC_DEBUG** +When using Mono with the SGen garbage collector this environment +variable can be used to turn on various debugging features of the +collector. The value of this variable is a comma separated list of +words. Do not use these options in production. + +*number* +Sets the debug level to the specified number. + +**print-allowance** +After each major collection prints memory consumption for before and +after the collection and the allowance for the minor collector, i.e. how +much the heap is allowed to grow from minor collections before the next +major collection is triggered. + +**print-pinning** +Gathers statistics on the classes whose objects are pinned in the +nursery and for which global remset entries are added. Prints those +statistics when shutting down. + +**collect-before-allocs** +**check-remset-consistency** +This performs a remset consistency check at various opportunities, and +also clears the nursery at collection time, instead of the default, when +buffers are allocated (clear-at-gc). The consistency check ensures that +there are no major to minor references that are not on the remembered +sets. + +**mod-union-consistency-check** +Checks that the mod-union cardtable is consistent before each finishing +major collection pause. This check is only applicable to concurrent +major collectors. + +**check-mark-bits** +Checks that mark bits in the major heap are consistent at the end of +each major collection. Consistent mark bits mean that if an object is +marked, all objects that it had references to must also be marked. + +**check-nursery-untag** +After garbage collections, check whether all vtable pointers are no +longer tagged. + +**xdomain-checks** +Performs a check to make sure that no references are left to an unloaded +AppDomain. + +**clear-at-tlab-creation** +Clears the nursery incrementally when the thread local allocation +buffers (TLAB) are created. The default setting clears the whole nursery +at GC time. + +**debug-clear-at-tlab-creation** +Clears the nursery incrementally when the thread local allocation +buffers (TLAB) are created, but at GC time fills it with the byte +\`0xff\`, which should result in a crash more quickly if +\`clear-at-tlab-creation\` doesn't work properly. + +**clear-at-gc** +This clears the nursery at GC time instead of doing it when the thread +local allocation buffer (TLAB) is created. The default is to clear the +nursery at TLAB creation time. + +**disable-minor** +Don't do minor collections. If the nursery is full, a major collection +is triggered instead, unless it, too, is disabled. + +**disable-major** +Don't do major collections. + +**conservative-stack-mark** +Forces the GC to scan the stack conservatively, even if precise scanning +is available. + +**no-managed-allocator** +Disables the managed allocator. + +**managed-allocator** +Enables the managed allocator. + +**check-scan-starts** +If set, does a plausibility check on the scan_starts before and after +each collection + +**verify-nursery-at-minor-gc** +If set, does a complete object walk of the nursery at the start of each +minor collection. + +**dump-nursery-at-minor-gc** +If set, dumps the contents of the nursery at the start of each minor +collection. Requires verify-nursery-at-minor-gc to be set. + +**heap-dump=***file* +Dumps the heap contents to the specified file. To visualize the +information, use the mono-heapviz tool. + +**binary-protocol=***file* +Outputs the debugging output to the specified file. For this to work, +Mono needs to be compiled with the BINARY_PROTOCOL define on sgen-gc.c. +You can then use this command to explore the output + + sgen-grep-binprot 0x1234 0x5678 < file + +**nursery-canaries** +If set, objects allocated in the nursery are suffixed with a canary +(guard) word, which is checked on each minor collection. Can be used to +detect/debug heap corruption issues. This disables the usage of the +managed allocator, because allocation from full aot code is inconsistent +with this option. If the application is guaranteed not to use aot code, +the managed allocator can be enabled back with managed-allocator option. + +**do-not-finalize(=***classes***)** +If enabled, finalizers will not be run. Everything else will be +unaffected: finalizable objects will still be put into the finalization +queue where they survive until they're scheduled to finalize. Once +they're not in the queue anymore they will be collected regularly. If a +list of comma-separated class names is given, only objects from those +classes will not be finalized. + +**log-finalizers** +Log verbosely around the finalization process to aid debugging. + +**MONO_GAC_PREFIX** +Provides a prefix the runtime uses to look for Global Assembly Caches. +Directories are separated by the platform path separator (colons on +unix). MONO_GAC_PREFIX should point to the top directory of a prefixed +install. Or to the directory provided in the gacutil /gacdir command. +Example: **/home/username/.mono:/usr/local/mono/** + +**MONO_IOMAP** +(deprecated) Enabled some filename rewriting support to assist +badly-written applications that hard-code Windows paths. It no longer +works as of Mono 6.0. + +**MONO_LLVM** +When Mono is using the LLVM code generation backend you can use this +environment variable to pass code generation options to the LLVM +compiler. + +**MONO_MANAGED_WATCHER** +If set to "disabled", System.IO.FileSystemWatcher will use a file +watcher implementation which silently ignores all the watching requests. +If set to any other value, System.IO.FileSystemWatcher will use the +default managed implementation (slow). If unset, mono will try to use +inotify, FAM, Gamin, kevent under Unix systems and native API calls on +Windows, falling back to the managed implementation on error. + +**MONO_MESSAGING_PROVIDER** +Mono supports a plugin model for its implementation of System.Messaging +making it possible to support a variety of messaging implementations +(e.g. AMQP, ActiveMQ). To specify which messaging implementation is to +be used the evironement variable needs to be set to the full class name +for the provider. E.g. to use the RabbitMQ based AMQP implementation the +variable should be set to: + + Mono.Messaging.RabbitMQ.RabbitMQMessagingProvider,Mono.Messaging.RabbitMQ + MONO_NO_SMP + If set causes the mono process to be bound to a single processor. This may be + useful when debugging or working around race conditions. + MONO_NO_TLS + Disable inlining of thread local accesses. Try setting this if you get a segfault + early on in the execution of mono. + MONO_PATH + Provides a search path to the runtime where to look for library + files. This is a tool convenient for debugging applications, but + should not be used by deployed applications as it breaks the assembly + loader in subtle ways. + Directories are separated by the platform path separator (colons on unix). Example: + /home/username/lib:/usr/local/mono/lib + Relative paths are resolved based on the launch-time current directory. + Alternative solutions to MONO_PATH include: installing libraries into + the Global Assembly Cache (see gacutil(1)) or having the dependent + libraries side-by-side with the main executable. + For a complete description of recommended practices for application + deployment, see + http://www.mono-project.com/docs/getting-started/application-deployment/ + MONO_SHARED_DIR + If set its the directory where the ".wapi" handle state is stored. + This is the directory where the Windows I/O Emulation layer stores its + shared state data (files, events, mutexes, pipes). By default Mono + will store the ".wapi" directory in the users's home directory. + MONO_SHARED_HOSTNAME + Uses the string value of this variable as a replacement for the host name when + creating file names in the ".wapi" directory. This helps if the host name of + your machine is likely to be changed when a mono application is running or if + you have a .wapi directory shared among several different computers. + Mono typically uses the hostname to create the files that are used to + share state across multiple Mono processes. This is done to support + home directories that might be shared over the network. + MONO_STRICT_IO_EMULATION + If set, extra checks are made during IO operations. Currently, this + includes only advisory locks around file writes. + MONO_TLS_PROVIDER + This environment variable controls which TLS/SSL provider Mono will + use. The options are usually determined by the operating system where + Mono was compiled and the configuration options that were used for + it. + default + Uses the default TLS stack that the Mono runtime was configured with. + Usually this is configured to use Apple's SSL stack on Apple + platforms, and Boring SSL on other platforms. + apple + Forces the use of the Apple SSL stack, only works on Apple platforms. + btls + Forces the use of the BoringSSL stack. See + https://opensource.google.com/projects/boringssl for more information + about this stack. + legacy + This is the old Mono stack, which only supports SSL and TLS up to + version 1.0. It is deprecated and will be removed in the future. + MONO_TLS_SESSION_CACHE_TIMEOUT + The time, in seconds, that the SSL/TLS session cache will keep it's entry to + avoid a new negotiation between the client and a server. Negotiation are very + CPU intensive so an application-specific custom value may prove useful for + small embedded systems. + The default is 180 seconds. + MONO_THREADS_PER_CPU + The minimum number of threads in the general threadpool will be + MONO_THREADS_PER_CPU * number of CPUs. The default value for this + variable is 1. + MONO_XMLSERIALIZER_THS + Controls the threshold for the XmlSerializer to produce a custom + serializer for a given class instead of using the Reflection-based + interpreter. The possible values are `no' to disable the use of a + custom serializer or a number to indicate when the XmlSerializer + should start serializing. The default value is 50, which means that + the a custom serializer will be produced on the 50th use. + MONO_X509_REVOCATION_MODE + Sets the revocation mode used when validating a X509 certificate chain (https, + ftps, smtps...). The default is 'nocheck', which performs no revocation check + at all. The other possible values are 'offline', which performs CRL check (not + implemented yet) and 'online' which uses OCSP and CRL to verify the revocation + status (not implemented yet). + NO_PROXY + (Also no_proxy) If both HTTP_PROXY and NO_PROXY are + set, NO_PROXY will be treated as a comma-separated list of "bypass" domains + which will not be sent through the proxy. Domains in NO_PROXY may contain + wildcards, as in "*.mono-project.com" or "build????.local". Not supported on + Windows, Mac OS, iOS or Android. + +## ENVIRONMENT VARIABLES FOR DEBUGGING + +**MONO_ASPNET_NODELETE** +If set to any value, temporary source files generated by ASP.NET support +classes will not be removed. They will be kept in the user's temporary +directory. + +**MONO_DEBUG** +If set, enables some features of the runtime useful for debugging. This +variable should contain a comma separated list of debugging options. +Currently, the following options are supported: + +**align-small-structs** +Enables small structs alignment to 4/8 bytes. + +**arm-use-fallback-tls** +When this option is set on ARM, a fallback thread local store will be +used instead of the default fast thread local storage primitives. + +**break-on-unverified** +If this variable is set, when the Mono VM runs into a verification +problem, instead of throwing an exception it will break into the +debugger. This is useful when debugging verifier problems + +**casts** +This option can be used to get more detailed information from +InvalidCast exceptions, it will provide information about the types +involved. + +**check-pinvoke-callconv** +This option causes the runtime to check for calling convention +mismatches when using pinvoke, i.e. mixing cdecl/stdcall. It only works +on windows. If a mismatch is detected, an ExecutionEngineException is +thrown. + +**collect-pagefault-stats** +Collects information about pagefaults. This is used internally to track +the number of page faults produced to load metadata. To display this +information you must use this option with "--stats" command line option. + +**debug-domain-unload** +When this option is set, the runtime will invalidate the domain memory +pool instead of destroying it. + +**disable_omit_fp** +Disables a compiler optimization where the frame pointer is omitted from +the stack. This optimization can interact badly with debuggers. + +**dont-free-domains** +This is an Optimization for multi-AppDomain applications (most commonly +ASP.NET applications). Due to internal limitations Mono, Mono by default +does not use typed allocations on multi-appDomain applications as they +could leak memory when a domain is unloaded. + +Although this is a fine default, for applications that use more than on +AppDomain heavily (for example, ASP.NET applications) it is worth +trading off the small leaks for the increased performance (additionally, +since ASP.NET applications are not likely going to unload the +application domains on production systems, it is worth using this +feature). + +**dyn-runtime-invoke** +Instructs the runtime to try to use a generic runtime-invoke wrapper +instead of creating one invoke wrapper. + +**explicit-null-checks** +Makes the JIT generate an explicit NULL check on variable dereferences +instead of depending on the operating system to raise a SIGSEGV or +another form of trap event when an invalid memory location is accessed. + +**gdb** +Equivalent to setting the **MONO_XDEBUG** variable, this emits symbols +into a shared library as the code is JITed that can be loaded into GDB +to inspect symbols. + +**gen-seq-points** +Automatically generates sequence points where the IL stack is empty. +These are places where the debugger can set a breakpoint. + +**llvm-disable-implicit-null-checks** +Makes the LLVM backend use explicit NULL checks on variable dereferences +instead of depending on operating system support for signals or traps +when an invalid memory location is accessed. Unconditionally enabled by +explicit-null-checks. + +**no-compact-seq-points** +Unless the option is used, the runtime generates sequence points data +that maps native offsets to IL offsets. Sequence point data is used to +display IL offset in stacktraces. Stacktraces with IL offsets can be +symbolicated using mono-symbolicate tool. + +**handle-sigint** +Captures the interrupt signal (Control-C) and displays a stack trace +when pressed. Useful to find out where the program is executing at a +given point. This only displays the stack trace of a single thread. + +**init-stacks** +Instructs the runtime to initialize the stack with some known values +(0x2a on x86-64) at the start of a method to assist in debuggin the JIT +engine. + +**keep-delegates** +This option will leak delegate trampolines that are no longer referenced +as to present the user with more information about a delegate misuse. +Basically a delegate instance might be created, passed to unmanaged +code, and no references kept in managed code, which will garbage collect +the code. With this option it is possible to track down the source of +the problems. + +**no-gdb-backtrace** +This option will disable the GDB backtrace emitted by the runtime after +a SIGSEGV or SIGABRT in unmanaged code. + +**partial-sharing** +When this option is set, the runtime can share generated code between +generic types effectively reducing the amount of code generated. + +**reverse-pinvoke-exceptions** +This option will cause mono to abort with a descriptive message when +during stack unwinding after an exception it reaches a native stack +frame. This happens when a managed delegate is passed to native code, +and the managed delegate throws an exception. Mono will normally try to +unwind the stack to the first (managed) exception handler, and it will +skip any native stack frames in the process. This leads to undefined +behaviour (since mono doesn't know how to process native frames), leaks, +and possibly crashes too. + +**single-imm-size** +This guarantees that each time managed code is compiled the same +instructions and registers are used, regardless of the size of used +values. + +**soft-breakpoints** +This option allows using single-steps and breakpoints in hardware where +we cannot do it with signals. + +**suspend-on-native-crash** +This option will suspend the program when a native crash occurs +(SIGSEGV, SIGILL, ...). This is useful for debugging crashes which do +not happen under gdb, since a live process contains more information +than a core file. + +**suspend-on-sigsegv** +Same as **suspend-on-native-crash**. + +**suspend-on-exception** +This option will suspend the program when an exception occurs. + +**suspend-on-unhandled** +This option will suspend the program when an unhandled exception occurs. + +**thread-dump-dir=DIR** +Use DIR for storage thread dumps created by SIGQUIT. + +**weak-memory-model** +Don't enforce the CLR memory model on platforms with weak memory models. +This can introduce random crashes in some rare cases, for multithreaded +environments. This can be used for a performance boost on applications +that are single threaded. + +**verbose-gdb** +Make gdb output on native crashes more verbose. + +**MONO_LOG_LEVEL** +The logging level, possible values are \`error', \`critical', +\`warning', \`message', \`info' and \`debug'. See the DEBUGGING section +for more details. + +**MONO_LOG_MASK** +Controls the domain of the Mono runtime that logging will apply to. If +set, the log mask is changed to the set value. Possible values are "asm" +(assembly loader), "type", "dll" (native library loader), "gc" (garbage +collector), "cfg" (config file loader), "aot" (precompiler), "security" +(e.g. Moonlight CoreCLR support) and "all". The default value is "all". +Changing the mask value allows you to display only messages for a +certain component. You can use multiple masks by comma separating them. +For example to see config file messages and assembly loader messages set +you mask to "asm,cfg". + +**MONO_LOG_DEST** +Controls where trace log messages are written. If not set then the +messages go to stdout. If set, the string either specifies a path to a +file that will have messages appended to it, or the string "syslog" in +which case the messages will be written to the system log. Under +Windows, this is simulated by writing to a file called "mono.log". +**MONO_LOG_HEADER** Controls whether trace log messages not directed to +syslog have the id, timestamp, and pid as the prefix to the log message. +To enable a header this environment variable need just be non-null. + +**MONO_TRACE** +Used for runtime tracing of method calls. The format of the comma +separated trace options is: + + + + + [-]M:method name + [-]N:namespace + [-]T:class name + [-]all + [-]program + disabled Trace output off upon start. + +You can toggle trace output on/off sending a SIGUSR2 signal to the +program. + +**MONO_TRACE_LISTENER** +If set, enables the System.Diagnostics.DefaultTraceListener, which will +print the output of the System.Diagnostics Trace and Debug classes. It +can be set to a filename, and to Console.Out or Console.Error to display +output to standard output or standard error, respectively. If it's set +to Console.Out or Console.Error you can append an optional prefix that +will be used when writing messages like this: +Console.Error:MyProgramName. See the +System.Diagnostics.DefaultTraceListener documentation for more +information. + +**MONO_WCF_TRACE** +This eases WCF diagnostics functionality by simply outputs all log +messages from WCF engine to "stdout", "stderr" or any file passed to +this environment variable. The log format is the same as usual +diagnostic output. + +**MONO_XEXCEPTIONS** +This throws an exception when a X11 error is encountered; by default a +message is displayed but execution continues + +**MONO_XMLSERIALIZER_DEBUG** +Set this value to 1 to prevent the serializer from removing the +temporary files that are created for fast serialization; This might be +useful when debugging. + +**MONO_XSYNC** +This is used in the System.Windows.Forms implementation when running +with the X11 backend. This is used to debug problems in Windows.Forms as +it forces all of the commands send to X11 server to be done +synchronously. The default mode of operation is asynchronous which makes +it hard to isolate the root of certain problems. + +**MONO_XDEBUG** +When the the MONO_XDEBUG env var is set, debugging info for JITted code +is emitted into a shared library, loadable into gdb. This enables, for +example, to see managed frame names on gdb backtraces. + +**MONO_VERBOSE_METHOD** +Enables the maximum JIT verbosity for the specified method. This is very +helpfull to diagnose a miscompilation problems of a specific method. +This can be a semicolon-separated list of method names to match. If the +name is simple, this applies to any method with that name, otherwise you +can use a mono method description (see the section METHOD DESCRIPTIONS). + +**MONO_JIT_DUMP_METHOD** +Enables sending of the JITs intermediate representation for a specified +method to the IdealGraphVisualizer tool. + +**MONO_VERBOSE_HWCAP** +If set, makes the JIT output information about detected CPU features +(such as SSE, CMOV, FCMOV, etc) to stdout. + +**MONO_CONSERVATIVE_HWCAP** +If set, the JIT will not perform any hardware capability detection. This +may be useful to pinpoint the cause of JIT issues. This is the default +when Mono is built as an AOT cross compiler, so that the generated code +will run on most hardware. + +**MONO_PROFILE** +Equivalent to **--profile** argument. + +## VALGRIND + +If you want to use Valgrind, you will find the file \`mono.supp' useful, +it contains the suppressions for the GC which trigger incorrect +warnings. Use it like this: + + valgrind --suppressions=mono.supp mono ... + +## DTRACE + +On some platforms, Mono can expose a set of DTrace probes (also known as +user-land statically defined, USDT Probes). + +They are defined in the file \`mono.d'. +**ves-init-begin, ves-init-end** + +Begin and end of runtime initialization. + +**method-compile-begin, method-compile-end** + +Begin and end of method compilation. The probe arguments are class name, +method name and signature, and in case of method-compile-end success or +failure of compilation. + +**gc-begin, gc-end** + +Begin and end of Garbage Collection. + +To verify the availability of the probes, run: + dtrace -P mono'$target' -l -c mono + +## PERMISSIONS + +Mono's Ping implementation for detecting network reachability can create +the ICMP packets itself without requiring the system ping command to do +the work. If you want to enable this on Linux for non-root users, you +need to give the Mono binary special permissions. + +As root, run this command: + + # setcap cap_net_raw=+ep /usr/bin/mono + +## FILES + +On Unix assemblies are loaded from the installation lib directory. If +you set \`prefix' to /usr, the assemblies will be located in /usr/lib. +On Windows, the assemblies are loaded from the directory where mono and +mint live. + +**~/.mono/aot-cache** + +The directory for the ahead-of-time compiler demand creation assemblies +are located. + +**/etc/mono/config, ~/.mono/config** + +Mono runtime configuration file. See the mono-config(5) manual page for +more information. + +**~/.config/.mono/certs, /usr/share/.mono/certs** + +Contains Mono certificate stores for users / machine. See the certmgr(1) +manual page for more information on managing certificate stores and the +mozroots(1) page for information on how to import the Mozilla root +certificates into the Mono certificate store. + +**~/.mono/assemblies/ASSEMBLY/ASSEMBLY.config** + +Files in this directory allow a user to customize the configuration for +a given system assembly, the format is the one described in the +mono-config(5) page. + +**~/.config/.mono/keypairs, /usr/share/.mono/keypairs** + +Contains Mono cryptographic keypairs for users / machine. They can be +accessed by using a CspParameters object with DSACryptoServiceProvider +and RSACryptoServiceProvider classes. + +**~/.config/.isolatedstorage, ~/.local/share/.isolatedstorage, /usr/share/.isolatedstorage** + +Contains Mono isolated storage for non-roaming users, roaming users and +local machine. Isolated storage can be accessed using the classes from +the System.IO.IsolatedStorage namespace. + +**\.config** + +Configuration information for individual assemblies is loaded by the +runtime from side-by-side files with the .config files, see the +http://www.mono-project.com/Config for more information. + +**Web.config, web.config** + +ASP.NET applications are configured through these files, the +configuration is done on a per-directory basis. For more information on +this subject see the http://www.mono-project.com/Config_system.web page. + +## MAILING LISTS + +Mailing lists are listed at the +http://www.mono-project.com/community/help/mailing-lists/ + +## WEB SITE + +http://www.mono-project.com + +## SEE ALSO + +**certmgr**(1), **cert-sync**(1), **csharp**(1), **gacutil**(1), +**mcs**(1), **monodis**(1), **mono-config**(5), **mono-profilers**(1), +**mprof-report**(1), **pdb2mdb**(1), **xsp**(1), **mod_mono**(8) + +For more information on AOT: +http://www.mono-project.com/docs/advanced/aot/ + +For ASP.NET-related documentation, see the xsp(1) manual page diff --git a/docs/workflow/building/coreclr/linux-instructions.md b/docs/workflow/building/coreclr/linux-instructions.md index 8e7457ff521850..3acec5e95ad9a9 100644 --- a/docs/workflow/building/coreclr/linux-instructions.md +++ b/docs/workflow/building/coreclr/linux-instructions.md @@ -59,14 +59,15 @@ docker pull mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-ar All official builds are cross-builds with a rootfs for the target OS, and will use the clang version available on the container. | Host OS | Target OS | Target Arch | Image location | crossrootfs location | -| --------------------- | ------------ | --------------- | -------------------------------------------------------------------------------- | -------------------- | -| CBL-mariner 2.0 (x64) | Alpine 3.13 | x64 | `mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64-alpine` | `/crossrootfs/x64` | -| CBL-mariner 2.0 (x64) | Ubuntu 16.04 | x64 | `mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64` | `/crossrootfs/x64` | -| CBL-mariner 2.0 (x64) | Alpine | arm32 (armhf) | `mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm-alpine` | `/crossrootfs/arm` | -| CBL-mariner 2.0 (x64) | Ubuntu 16.04 | arm32 (armhf) | `mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm` | `/crossrootfs/arm` | -| CBL-mariner 2.0 (x64) | Alpine | arm64 (arm64v8) | `mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64-alpine` | `/crossrootfs/arm64` | -| CBL-mariner 2.0 (x64) | Ubuntu 16.04 | arm64 (arm64v8) | `mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64` | `/crossrootfs/arm64` | -| Ubuntu 18.04 (x64) | FreeBSD | x64 | `mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-12` | `/crossrootfs/x64` | +| --------------------- | ------------ | --------------- | -------------------------------------------------------------------------------------- | -------------------- | +| Azure Linux (x64) | Alpine 3.13 | x64 | `mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-alpine-net9.0` | `/crossrootfs/x64` | +| Azure Linux (x64) | Ubuntu 16.04 | x64 | `mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-net9.0` | `/crossrootfs/x64` | +| Azure Linux (x64) | Alpine | arm32 (armhf) | `mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-alpine-net9.0` | `/crossrootfs/arm` | +| Azure Linux (x64) | Ubuntu 16.04 | arm32 (armhf) | `mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-net9.0` | `/crossrootfs/arm` | +| Azure Linux (x64) | Alpine | arm64 (arm64v8) | `mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm64-alpine-net9.0` | `/crossrootfs/arm64` | +| Azure Linux (x64) | Ubuntu 16.04 | arm64 (arm64v8) | `mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm64-net9.0` | `/crossrootfs/arm64` | +| Azure Linux (x64) | Ubuntu 16.04 | x86 | `mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-x86-net9.0` | `/crossrootfs/x86` | +| CBL-mariner 2.0 (x64) | FreeBSD 13 | x64 | `mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-amd64-freebsd-13` | `/crossrootfs/x64` | These Docker images are built using the Dockerfiles maintained in the [dotnet-buildtools-prereqs-docker repo](https://github.com/dotnet/dotnet-buildtools-prereqs-docker). diff --git a/eng/DotNetBuild.props b/eng/DotNetBuild.props index 52abdf92f094a2..9d68b8265b0c1f 100644 --- a/eng/DotNetBuild.props +++ b/eng/DotNetBuild.props @@ -84,6 +84,7 @@ $(InnerBuildArgs) /p:SourceBuiltNonShippingPackagesDir=$(SourceBuiltNonShippingPackagesDir) $(InnerBuildArgs) /p:SourceBuiltAssetManifestsDir=$(SourceBuiltAssetManifestsDir) $(InnerBuildArgs) /p:SourceBuiltSymbolsDir=$(SourceBuiltSymbolsDir) + $(InnerBuildArgs) /p:GitHubRepositoryName=$(GitHubRepositoryName) diff --git a/eng/Subsets.props b/eng/Subsets.props index 499e9c3cb645fe..0a51b12649d1e8 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -173,6 +173,8 @@ + + @@ -358,6 +360,8 @@ + + @@ -369,6 +373,10 @@ Test="true" Category="clr" Condition="'$(DotNetBuildSourceOnly)' != 'true' and '$(NativeAotSupported)' == 'true'"/> + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 81d16576e39003..1f961bfe2544fc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - 0ea0175965771285846b5d077bebe5946036a595 + 3230636546e2b2dc9648c4385c201e28a550f0ea https://github.com/dotnet/msquic @@ -12,9 +12,9 @@ https://github.com/dotnet/wcf 7f504aabb1988e9a093c1e74d8040bd52feb2f01 - + https://github.com/dotnet/emsdk - 19c9523f5c2dd091b49959700723af795d6ad2b4 + 53288f87c588907e8ff01f129786820fe998573c https://github.com/dotnet/llvm-project @@ -58,24 +58,24 @@ a045dd54a4c44723c215d992288160eb1401bb7f - + https://github.com/dotnet/cecil - 861f49c137941b9722a43e5993ccac7716c8528c + 7a4a59f9f66baf6711a6ce2de01d3b2c62ed72d8 - + https://github.com/dotnet/cecil - 861f49c137941b9722a43e5993ccac7716c8528c + 7a4a59f9f66baf6711a6ce2de01d3b2c62ed72d8 - + https://github.com/dotnet/emsdk - 19c9523f5c2dd091b49959700723af795d6ad2b4 + 53288f87c588907e8ff01f129786820fe998573c - + https://github.com/dotnet/emsdk - 19c9523f5c2dd091b49959700723af795d6ad2b4 + 53288f87c588907e8ff01f129786820fe998573c @@ -85,146 +85,146 @@ - + https://github.com/dotnet/source-build-externals - 5a273649709de76f61957e3d69e1f031e5ac82e2 + b02769661c9a51985877819e8bdebfbcbee65710 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 https://github.com/dotnet/llvm-project @@ -282,127 +282,127 @@ https://github.com/dotnet/llvm-project 26f8c30340764cfa7fa9090dc01a36c222bf09c1 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/runtime - 85fbd98765c47a867564fff6ae18cc92423cdc66 + 7745b5ec3db34cd358b26710c0ec32db8b0b23f7 - + https://github.com/dotnet/xharness - 50b43ece7daf9f8a88ac16a95a4f8647a4c71c4b + ff14b0c0b6d72bf4447d57758a40dbf9494f1ac0 - + https://github.com/dotnet/xharness - 50b43ece7daf9f8a88ac16a95a4f8647a4c71c4b + ff14b0c0b6d72bf4447d57758a40dbf9494f1ac0 - + https://github.com/dotnet/xharness - 50b43ece7daf9f8a88ac16a95a4f8647a4c71c4b + ff14b0c0b6d72bf4447d57758a40dbf9494f1ac0 - + https://github.com/dotnet/arcade - 8ec8057ac5073b6b2e3fcb0a33d588d2a3357ad3 + 020255bcf7d0b8beed7de05338d97396982ae527 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 78a5b978e1965c1335edb4b9a22bc4d6ff5a77a6 + c3acfd159662959ff09f3a0d7663023db48bb78a - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 78a5b978e1965c1335edb4b9a22bc4d6ff5a77a6 + c3acfd159662959ff09f3a0d7663023db48bb78a - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 78a5b978e1965c1335edb4b9a22bc4d6ff5a77a6 + c3acfd159662959ff09f3a0d7663023db48bb78a - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 78a5b978e1965c1335edb4b9a22bc4d6ff5a77a6 + c3acfd159662959ff09f3a0d7663023db48bb78a - + https://github.com/dotnet/hotreload-utils - 4670b9e37293570f8d93d6af40c4710e2686bf67 + 249050528f8ac9882f04b2c719bda3e5a532b258 - + https://github.com/dotnet/runtime-assets - 30b6a8d9d3af5681e4caef1ea453619a4b0e9f2e + 422b5e7d39642735eacc85b2a060abb3899ce497 - + https://github.com/dotnet/roslyn - ca66296efa86bd8078508fe7b38b91b415364f78 + 75995e26b4c6f9a30ace7bcb65c0b4e42c0b397c - + https://github.com/dotnet/roslyn - ca66296efa86bd8078508fe7b38b91b415364f78 + 75995e26b4c6f9a30ace7bcb65c0b4e42c0b397c - + https://github.com/dotnet/roslyn - ca66296efa86bd8078508fe7b38b91b415364f78 + 75995e26b4c6f9a30ace7bcb65c0b4e42c0b397c - + https://github.com/dotnet/roslyn-analyzers - b07c100bfc66013a8444172d00cfa04c9ceb5a97 + 8dccccec1ce3bd2fb532ec77d7e092ab9d684db7 - + https://github.com/dotnet/roslyn-analyzers - b07c100bfc66013a8444172d00cfa04c9ceb5a97 + 8dccccec1ce3bd2fb532ec77d7e092ab9d684db7 - + https://github.com/dotnet/roslyn - ca66296efa86bd8078508fe7b38b91b415364f78 + 75995e26b4c6f9a30ace7bcb65c0b4e42c0b397c - + https://github.com/dotnet/sdk - cf8c24575410adf397c0823fd7061f9451049ea1 + 0f7644da23265f1be382b28ff56f5505b0329334 - + https://github.com/dotnet/sdk - cf8c24575410adf397c0823fd7061f9451049ea1 + 0f7644da23265f1be382b28ff56f5505b0329334 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 78a5b978e1965c1335edb4b9a22bc4d6ff5a77a6 + c3acfd159662959ff09f3a0d7663023db48bb78a - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 78a5b978e1965c1335edb4b9a22bc4d6ff5a77a6 + c3acfd159662959ff09f3a0d7663023db48bb78a diff --git a/eng/Versions.props b/eng/Versions.props index 46b53f8ae070c9..3f0cf7c4d63ade 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -11,7 +11,7 @@ 7.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet8)').Build),14)) 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11)) preview - 4 + 5 false release @@ -34,17 +34,17 @@ - 3.11.0-beta1.24216.2 - 9.0.0-preview.24216.2 + 3.11.0-beta1.24225.1 + 9.0.0-preview.24225.1 - 4.11.0-1.24215.10 - 4.11.0-1.24215.10 - 4.11.0-1.24215.10 + 4.11.0-1.24228.2 + 4.11.0-1.24228.2 + 4.11.0-1.24228.2 - 9.0.100-preview.4.24215.1 + 9.0.100-preview.5.24227.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 2.6.7-beta.24217.1 - 9.0.0-beta.24217.1 - 2.6.7-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 - 9.0.0-beta.24217.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 2.6.7-beta.24253.1 + 9.0.0-beta.24253.1 + 2.6.7-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 + 9.0.0-beta.24253.1 1.4.0 6.0.0-preview.1.102 - 9.0.0-preview.4.24215.1 + 9.0.0-preview.4.24229.1 6.0.0 - 9.0.0-preview.4.24215.1 + 9.0.0-preview.4.24229.1 6.0.0 1.1.1 @@ -119,46 +119,46 @@ 8.0.0 5.0.0 4.5.5 - 9.0.0-preview.4.24215.1 - 9.0.0-preview.4.24215.1 + 9.0.0-preview.4.24229.1 + 9.0.0-preview.4.24229.1 6.0.0 5.0.0 5.0.0 5.0.0 7.0.0 - 9.0.0-preview.4.24215.1 + 9.0.0-preview.4.24229.1 6.0.0 7.0.0 4.5.4 4.5.0 - 9.0.0-preview.4.24215.1 + 9.0.0-preview.4.24229.1 8.0.0 8.0.0 8.0.0 8.0.0 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 - 9.0.0-beta.24215.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 + 9.0.0-beta.24229.1 - 1.0.0-prerelease.24106.4 - 1.0.0-prerelease.24106.4 - 1.0.0-prerelease.24106.4 - 1.0.0-prerelease.24106.4 - 1.0.0-prerelease.24106.4 - 1.0.0-prerelease.24106.4 + 1.0.0-prerelease.24223.3 + 1.0.0-prerelease.24223.3 + 1.0.0-prerelease.24223.3 + 1.0.0-prerelease.24223.3 + 1.0.0-prerelease.24223.3 + 1.0.0-prerelease.24223.3 2.0.0 17.8.0-beta1.23475.2 @@ -179,10 +179,10 @@ 1.4.0 17.4.0-preview-20220707-01 - 9.0.0-prerelease.24208.1 - 9.0.0-prerelease.24208.1 - 9.0.0-prerelease.24208.1 - 9.0.0-alpha.0.24215.1 + 9.0.0-prerelease.24229.1 + 9.0.0-prerelease.24229.1 + 9.0.0-prerelease.24229.1 + 9.0.0-alpha.0.24222.1 3.12.0 4.5.0 6.0.0 @@ -208,11 +208,11 @@ 8.0.0-preview-20230918.1 - 0.11.4-alpha.24215.1 + 0.11.4-alpha.24230.1 - 9.0.0-preview.4.24215.1 + 9.0.0-preview.4.24229.1 - 9.0.0-preview.4.24215.1 + 9.0.0-preview.5.24230.1 2.3.5 9.0.0-alpha.1.24167.3 @@ -235,9 +235,9 @@ Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-9_0_100_Transport --> - 9.0.0-preview.4.24215.3 + 9.0.0-preview.5.24223.2 $(MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion) - 9.0.0-preview.4.24215.3 + 9.0.0-preview.5.24223.2 1.1.87-gba258badda 1.0.0-v3.14.0.5722 diff --git a/eng/common/build.ps1 b/eng/common/build.ps1 index 83e6d82e027a82..438f9920c43e4e 100644 --- a/eng/common/build.ps1 +++ b/eng/common/build.ps1 @@ -19,7 +19,6 @@ Param( [switch] $pack, [switch] $publish, [switch] $clean, - [switch] $verticalBuild, [switch][Alias('pb')]$productBuild, [switch][Alias('bl')]$binaryLog, [switch][Alias('nobl')]$excludeCIBinarylog, @@ -60,7 +59,6 @@ function Print-Usage() { Write-Host " -sign Sign build outputs" Write-Host " -publish Publish artifacts (e.g. symbols)" Write-Host " -clean Clean the solution" - Write-Host " -verticalBuild Run in 'vertical build' infra mode." Write-Host " -productBuild Build the solution in the way it will be built in the full .NET product (VMR) build (short: -pb)" Write-Host "" @@ -124,7 +122,7 @@ function Build { /p:Deploy=$deploy ` /p:Test=$test ` /p:Pack=$pack ` - /p:DotNetBuildRepo=$($productBuild -or $verticalBuild) ` + /p:DotNetBuildRepo=$productBuild ` /p:IntegrationTest=$integrationTest ` /p:PerformanceTest=$performanceTest ` /p:Sign=$sign ` diff --git a/eng/common/build.sh b/eng/common/build.sh index d82ebf7428080f..ac1ee8620cd2ab 100755 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -62,7 +62,6 @@ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" restore=false build=false source_build=false -vertical_build=false product_build=false rebuild=false test=false @@ -141,13 +140,6 @@ while [[ $# > 0 ]]; do restore=true pack=true ;; - -verticalbuild|-vb) - build=true - vertical_build=true - product_build=true - restore=true - pack=true - ;; -test|-t) test=true ;; diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml new file mode 100644 index 00000000000000..dc3bd560a50e24 --- /dev/null +++ b/eng/common/core-templates/job/job.yml @@ -0,0 +1,266 @@ +parameters: +# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + cancelTimeoutInMinutes: '' + condition: '' + container: '' + continueOnError: false + dependsOn: '' + displayName: '' + pool: '' + steps: [] + strategy: '' + timeoutInMinutes: '' + variables: [] + workspace: '' + templateContext: {} + +# Job base template specific parameters + # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md + # publishing defaults + artifacts: '' + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishBuildAssets: false + enablePublishTestResults: false + enablePublishUsingPipelines: false + enableBuildRetry: false + disableComponentGovernance: '' + componentGovernanceIgnoreDirectories: '' + mergeTestResults: false + testRunTitle: '' + testResultsFormat: '' + name: '' + preSteps: [] + artifactPublishSteps: [] + runAsPublic: false + +# Sbom related params + enableSbom: true + PackageVersion: 9.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + +# 1es specific parameters + is1ESPipeline: '' + +jobs: +- job: ${{ parameters.name }} + + ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: + cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} + + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + + ${{ if ne(parameters.container, '') }}: + container: ${{ parameters.container }} + + ${{ if ne(parameters.continueOnError, '') }}: + continueOnError: ${{ parameters.continueOnError }} + + ${{ if ne(parameters.dependsOn, '') }}: + dependsOn: ${{ parameters.dependsOn }} + + ${{ if ne(parameters.displayName, '') }}: + displayName: ${{ parameters.displayName }} + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + + ${{ if ne(parameters.strategy, '') }}: + strategy: ${{ parameters.strategy }} + + ${{ if ne(parameters.timeoutInMinutes, '') }}: + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + + variables: + - ${{ if ne(parameters.enableTelemetry, 'false') }}: + - name: DOTNET_CLI_TELEMETRY_PROFILE + value: '$(Build.Repository.Uri)' + - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: + - name: EnableRichCodeNavigation + value: 'true' + # Retry signature validation up to three times, waiting 2 seconds between attempts. + # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures + - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY + value: 3,2000 + - ${{ each variable in parameters.variables }}: + # handle name-value variable syntax + # example: + # - name: [key] + # value: [value] + - ${{ if ne(variable.name, '') }}: + - name: ${{ variable.name }} + value: ${{ variable.value }} + + # handle variable groups + - ${{ if ne(variable.group, '') }}: + - group: ${{ variable.group }} + + # handle template variable syntax + # example: + # - template: path/to/template.yml + # parameters: + # [key]: [value] + - ${{ if ne(variable.template, '') }}: + - template: ${{ variable.template }} + ${{ if ne(variable.parameters, '') }}: + parameters: ${{ variable.parameters }} + + # handle key-value variable syntax. + # example: + # - [key]: [value] + - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: + - ${{ each pair in variable }}: + - name: ${{ pair.key }} + value: ${{ pair.value }} + + # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds + - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: DotNet-HelixApi-Access + + ${{ if ne(parameters.workspace, '') }}: + workspace: ${{ parameters.workspace }} + + steps: + - ${{ if eq(parameters.is1ESPipeline, '') }}: + - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error + + - ${{ if ne(parameters.preSteps, '') }}: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - task: MicroBuildSigningPlugin@4 + displayName: Install MicroBuild plugin + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + env: + TeamName: $(_TeamName) + MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + + - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: + - task: NuGetAuthenticate@1 + + - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: + - task: DownloadPipelineArtifact@2 + inputs: + buildType: current + artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} + targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} + itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} + + - ${{ each step in parameters.steps }}: + - ${{ step }} + + - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: + - task: RichCodeNavIndexer@0 + displayName: RichCodeNav Upload + inputs: + languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} + environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'internal') }} + richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin + uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} + continueOnError: true + + - template: /eng/common/core-templates/steps/component-governance.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false + ${{ else }}: + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + env: + TeamName: $(_TeamName) + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - template: /eng/common/core-templates/steps/generate-sbom.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + PackageVersion: ${{ parameters.packageVersion}} + BuildDropPath: ${{ parameters.buildDropPath }} + IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + publishArtifacts: false + + # Publish test results + - ${{ if and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')) }}: + - ${{ if eq(parameters.testResultsFormat, 'xunit') }}: + - task: PublishTestResults@2 + displayName: Publish XUnit Test Results + inputs: + testResultsFormat: 'xUnit' + testResultsFiles: '*.xml' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + - ${{ if eq(parameters.testResultsFormat, 'vstest') }}: + - task: PublishTestResults@2 + displayName: Publish TRX Test Results + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '*.trx' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + + # gather artifacts + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - task: CopyFiles@2 + displayName: Gather binaries for publish to artifacts + inputs: + SourceFolder: 'artifacts/bin' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' + - task: CopyFiles@2 + displayName: Gather packages for publish to artifacts + inputs: + SourceFolder: 'artifacts/packages' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - task: CopyFiles@2 + displayName: Gather logs for publish to artifacts + inputs: + SourceFolder: 'artifacts/log' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log' + + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - task: CopyFiles@2 + displayName: Gather logs for publish to artifacts + inputs: + SourceFolder: 'artifacts/log/$(_BuildConfig)' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - task: CopyFiles@2 + displayName: Gather buildconfiguration for build retry + inputs: + SourceFolder: '$(Build.SourcesDirectory)/eng/common/BuildConfiguration' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/eng/common/BuildConfiguration' + + - ${{ each step in parameters.artifactPublishSteps }}: + - ${{ step }} diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml new file mode 100644 index 00000000000000..00feec8ebbc3ab --- /dev/null +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -0,0 +1,121 @@ +parameters: + # Optional: dependencies of the job + dependsOn: '' + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: '' + + CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex + GithubPat: $(BotAccount-dotnet-bot-repo-PAT) + + SourcesDirectory: $(Build.SourcesDirectory) + CreatePr: true + AutoCompletePr: false + ReusePr: true + UseLfLineEndings: true + UseCheckedInLocProjectJson: false + SkipLocProjectJsonGeneration: false + LanguageSet: VS_Main_Languages + LclSource: lclFilesInRepo + LclPackageId: '' + RepoType: gitHub + GitHubOrg: dotnet + MirrorRepo: '' + MirrorBranch: main + condition: '' + JobNameSuffix: '' + is1ESPipeline: '' +jobs: +- job: OneLocBuild${{ parameters.JobNameSuffix }} + + dependsOn: ${{ parameters.dependsOn }} + + displayName: OneLocBuild${{ parameters.JobNameSuffix }} + + variables: + - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat + - name: _GenerateLocProjectArguments + value: -SourcesDirectory ${{ parameters.SourcesDirectory }} + -LanguageSet "${{ parameters.LanguageSet }}" + -CreateNeutralXlfs + - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: + - name: _GenerateLocProjectArguments + value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson + - template: /eng/common/core-templates/variables/pool-providers.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + + steps: + - ${{ if eq(parameters.is1ESPipeline, '') }}: + - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error + + - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: + - task: Powershell@2 + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 + arguments: $(_GenerateLocProjectArguments) + displayName: Generate LocProject.json + condition: ${{ parameters.condition }} + + - task: OneLocBuild@2 + displayName: OneLocBuild + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + locProj: eng/Localize/LocProject.json + outDir: $(Build.ArtifactStagingDirectory) + lclSource: ${{ parameters.LclSource }} + lclPackageId: ${{ parameters.LclPackageId }} + isCreatePrSelected: ${{ parameters.CreatePr }} + isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} + ${{ if eq(parameters.CreatePr, true) }}: + isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + isShouldReusePrSelected: ${{ parameters.ReusePr }} + packageSourceAuth: patAuth + patVariable: ${{ parameters.CeapexPat }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + repoType: ${{ parameters.RepoType }} + gitHubPatVariable: "${{ parameters.GithubPat }}" + ${{ if ne(parameters.MirrorRepo, '') }}: + isMirrorRepoSelected: true + gitHubOrganization: ${{ parameters.GitHubOrg }} + mirrorRepo: ${{ parameters.MirrorRepo }} + mirrorBranch: ${{ parameters.MirrorBranch }} + condition: ${{ parameters.condition }} + + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + displayName: Publish Localization Files + pathToPublish: '$(Build.ArtifactStagingDirectory)/loc' + publishLocation: Container + artifactName: Loc + condition: ${{ parameters.condition }} + + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + displayName: Publish LocProject.json + pathToPublish: '$(Build.SourcesDirectory)/eng/Localize/' + publishLocation: Container + artifactName: Loc + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml new file mode 100644 index 00000000000000..8fe9299542c531 --- /dev/null +++ b/eng/common/core-templates/job/publish-build-assets.yml @@ -0,0 +1,172 @@ +parameters: + configuration: 'Debug' + + # Optional: condition for the job to run + condition: '' + + # Optional: 'true' if future jobs should run even if this job fails + continueOnError: false + + # Optional: dependencies of the job + dependsOn: '' + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: {} + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishUsingPipelines: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishAssetsImmediately: false + + artifactsPublishingAdditionalParameters: '' + + signingValidationAdditionalParameters: '' + + is1ESPipeline: '' + +jobs: +- job: Asset_Registry_Publish + + dependsOn: ${{ parameters.dependsOn }} + timeoutInMinutes: 150 + + ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + displayName: Publish Assets + ${{ else }}: + displayName: Publish to Build Asset Registry + + variables: + - template: /eng/common/core-templates/variables/pool-providers.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats + - name: runCodesignValidationInjection + value: false + # unconditional - needed for logs publishing (redactor tool version) + - template: /eng/common/core-templates/post-build/common-variables.yml + + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: NetCore1ESPool-Publishing-Internal + image: windows.vs2019.amd64 + os: windows + steps: + - ${{ if eq(parameters.is1ESPipeline, '') }}: + - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - checkout: self + fetchDepth: 3 + clean: true + + - task: DownloadBuildArtifacts@0 + displayName: Download artifact + inputs: + artifactName: AssetManifests + downloadPath: '$(Build.StagingDirectory)/Download' + checkDownloadedFiles: true + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Build Assets + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet + /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' + /p:BuildAssetRegistryToken=$(MaestroAccessToken) + /p:MaestroApiEndpoint=https://maestro.dot.net + /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} + /p:OfficialBuildId=$(Build.BuildNumber) + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: powershell@2 + displayName: Create ReleaseConfigs Artifact + inputs: + targetType: inline + script: | + New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force + $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" + Add-Content -Path $filePath -Value $(BARBuildId) + Add-Content -Path $filePath -Value "$(DefaultChannels)" + Add-Content -Path $filePath -Value $(IsStableBuild) + + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + displayName: Publish ReleaseConfigs Artifact + pathToPublish: '$(Build.StagingDirectory)/ReleaseConfigs' + publishLocation: Container + artifactName: ReleaseConfigs + + - task: powershell@2 + displayName: Check if SymbolPublishingExclusionsFile.txt exists + inputs: + targetType: inline + script: | + $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" + if(Test-Path -Path $symbolExclusionfile) + { + Write-Host "SymbolExclusionFile exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" + } + else{ + Write-Host "Symbols Exclusion file does not exist" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" + } + + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + displayName: Publish SymbolPublishingExclusionsFile Artifact + condition: eq(variables['SymbolExclusionFile'], 'true') + pathToPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' + publishLocation: Container + artifactName: ReleaseConfigs + + - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion 3 + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - template: /eng/common/core-templates/steps/publish-logs.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml new file mode 100644 index 00000000000000..c0ce4b3c861861 --- /dev/null +++ b/eng/common/core-templates/job/source-build.yml @@ -0,0 +1,80 @@ +parameters: + # This template adds arcade-powered source-build to CI. The template produces a server job with a + # default ID 'Source_Build_Complete' to put in a dependency list if necessary. + + # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. + jobNamePrefix: 'Source_Build' + + # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for + # managed-only repositories. This is an object with these properties: + # + # name: '' + # The name of the job. This is included in the job ID. + # targetRID: '' + # The name of the target RID to use, instead of the one auto-detected by Arcade. + # nonPortable: false + # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than + # linux-x64), and compiling against distro-provided packages rather than portable ones. + # skipPublishValidation: false + # Disables publishing validation. By default, a check is performed to ensure no packages are + # published by source-build. + # container: '' + # A container to use. Runs in docker. + # pool: {} + # A pool to use. Runs directly on an agent. + # buildScript: '' + # Specifies the build script to invoke to perform the build in the repo. The default + # './build.sh' should work for typical Arcade repositories, but this is customizable for + # difficult situations. + # jobProperties: {} + # A list of job properties to inject at the top level, for potential extensibility beyond + # container and pool. + platform: {} + + is1ESPipeline: '' + +jobs: +- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} + displayName: Source-Build (${{ parameters.platform.name }}) + + ${{ each property in parameters.platform.jobProperties }}: + ${{ property.key }}: ${{ property.value }} + + ${{ if ne(parameters.platform.container, '') }}: + container: ${{ parameters.platform.container }} + + ${{ if eq(parameters.platform.pool, '') }}: + # The default VM host AzDO pool. This should be capable of running Docker containers: almost all + # source-build builds run in Docker, including the default managed platform. + # /eng/common/core-templates/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic + ${{ if eq(parameters.is1ESPipeline, 'true') }}: + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] + demands: ImageOverride -equals build.ubuntu.2004.amd64 + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] + image: 1es-mariner-2 + os: linux + ${{ else }}: + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] + demands: ImageOverride -equals Build.Ubuntu.2204.Amd64.Open + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] + demands: ImageOverride -equals Build.Ubuntu.2204.Amd64 + ${{ if ne(parameters.platform.pool, '') }}: + pool: ${{ parameters.platform.pool }} + + workspace: + clean: all + + steps: + - ${{ if eq(parameters.is1ESPipeline, '') }}: + - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error + + - template: /eng/common/core-templates/steps/source-build.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + platform: ${{ parameters.platform }} diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml new file mode 100644 index 00000000000000..9c6e5ae3c3e45a --- /dev/null +++ b/eng/common/core-templates/job/source-index-stage1.yml @@ -0,0 +1,73 @@ +parameters: + runAsPublic: false + sourceIndexPackageVersion: 1.0.1-20240129.2 + sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" + preSteps: [] + binlogPath: artifacts/log/Debug/Build.binlog + condition: '' + dependsOn: '' + pool: '' + is1ESPipeline: '' + +jobs: +- job: SourceIndexStage1 + dependsOn: ${{ parameters.dependsOn }} + condition: ${{ parameters.condition }} + variables: + - name: SourceIndexPackageVersion + value: ${{ parameters.sourceIndexPackageVersion }} + - name: SourceIndexPackageSource + value: ${{ parameters.sourceIndexPackageSource }} + - name: BinlogPath + value: ${{ parameters.binlogPath }} + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: source-dot-net stage1 variables + - template: /eng/common/core-templates/variables/pool-providers.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + image: windows.vs2022.amd64.open + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $(DncEngInternalBuildPool) + image: windows.vs2022.amd64 + + steps: + - ${{ if eq(parameters.is1ESPipeline, '') }}: + - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error + + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - task: UseDotNet@2 + displayName: Use .NET 8 SDK + inputs: + packageType: sdk + version: 8.0.x + installationPath: $(Agent.TempDirectory)/dotnet + workingDirectory: $(Agent.TempDirectory) + + - script: | + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + displayName: Download Tools + # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. + workingDirectory: $(Agent.TempDirectory) + + - script: ${{ parameters.sourceIndexBuildCommand }} + displayName: Build Repository + + - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output + displayName: Process Binlog into indexable sln + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) + displayName: Upload stage1 artifacts to source index + env: + BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) diff --git a/eng/common/core-templates/jobs/codeql-build.yml b/eng/common/core-templates/jobs/codeql-build.yml new file mode 100644 index 00000000000000..f2144252cc65c8 --- /dev/null +++ b/eng/common/core-templates/jobs/codeql-build.yml @@ -0,0 +1,33 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + is1ESPipeline: '' + +jobs: +- template: /eng/common/core-templates/jobs/jobs.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishTestResults: false + enablePublishBuildAssets: false + enablePublishUsingPipelines: false + enableTelemetry: true + + variables: + - group: Publish-Build-Assets + # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in + # sync with the packages.config file. + - name: DefaultGuardianVersion + value: 0.109.0 + - name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config + - name: GuardianVersion + value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} + + jobs: ${{ parameters.jobs }} + diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml new file mode 100644 index 00000000000000..ea69be4341c62f --- /dev/null +++ b/eng/common/core-templates/jobs/jobs.yml @@ -0,0 +1,119 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: Enable publishing using release pipelines + enablePublishUsingPipelines: false + + # Optional: Enable running the source-build jobs to build repo from source + enableSourceBuild: false + + # Optional: Parameters for source-build template. + # See /eng/common/core-templates/jobs/source-build.yml for options + sourceBuildParameters: [] + + graphFileGeneration: + # Optional: Enable generating the graph files at the end of the build + enabled: false + # Optional: Include toolset dependencies in the generated graph files + includeToolset: false + + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + + # Optional: Override automatically derived dependsOn value for "publish build assets" job + publishBuildAssetsDependsOn: '' + + # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. + publishAssetsImmediately: false + + # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml) + artifactsPublishingAdditionalParameters: '' + signingValidationAdditionalParameters: '' + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + enableSourceIndex: false + sourceIndexParams: {} + + artifacts: {} + is1ESPipeline: '' + +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +jobs: +- ${{ each job in parameters.jobs }}: + - ${{ if eq(parameters.is1ESPipeline, 'true') }}: + - template: /eng/common/templates-official/job/job.yml + parameters: + # pass along parameters + ${{ each parameter in parameters }}: + ${{ if ne(parameter.key, 'jobs') }}: + ${{ parameter.key }}: ${{ parameter.value }} + + # pass along job properties + ${{ each property in job }}: + ${{ if ne(property.key, 'job') }}: + ${{ property.key }}: ${{ property.value }} + + name: ${{ job.job }} + + - ${{ else }}: + - template: /eng/common/templates/job/job.yml + parameters: + # pass along parameters + ${{ each parameter in parameters }}: + ${{ if ne(parameter.key, 'jobs') }}: + ${{ parameter.key }}: ${{ parameter.value }} + + # pass along job properties + ${{ each property in job }}: + ${{ if ne(property.key, 'job') }}: + ${{ property.key }}: ${{ property.value }} + + name: ${{ job.job }} + +- ${{ if eq(parameters.enableSourceBuild, true) }}: + - template: /eng/common/core-templates/jobs/source-build.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + allCompletedJobId: Source_Build_Complete + ${{ each parameter in parameters.sourceBuildParameters }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if eq(parameters.enableSourceIndex, 'true') }}: + - template: ../job/source-index-stage1.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + runAsPublic: ${{ parameters.runAsPublic }} + ${{ each parameter in parameters.sourceIndexParams }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - template: ../job/publish-build-assets.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + continueOnError: ${{ parameters.continueOnError }} + dependsOn: + - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.publishBuildAssetsDependsOn }}: + - ${{ job.job }} + - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.jobs }}: + - ${{ job.job }} + - ${{ if eq(parameters.enableSourceBuild, true) }}: + - Source_Build_Complete + + runAsPublic: ${{ parameters.runAsPublic }} + publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} + publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} + enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} diff --git a/eng/common/core-templates/jobs/source-build.yml b/eng/common/core-templates/jobs/source-build.yml new file mode 100644 index 00000000000000..d8e5d008522682 --- /dev/null +++ b/eng/common/core-templates/jobs/source-build.yml @@ -0,0 +1,50 @@ +parameters: + # This template adds arcade-powered source-build to CI. A job is created for each platform, as + # well as an optional server job that completes when all platform jobs complete. + + # The name of the "join" job for all source-build platforms. If set to empty string, the job is + # not included. Existing repo pipelines can use this job depend on all source-build jobs + # completing without maintaining a separate list of every single job ID: just depend on this one + # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. + allCompletedJobId: '' + + # See /eng/common/core-templates/job/source-build.yml + jobNamePrefix: 'Source_Build' + + # This is the default platform provided by Arcade, intended for use by a managed-only repo. + defaultManagedPlatform: + name: 'Managed' + container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9' + + # Defines the platforms on which to run build jobs. One job is created for each platform, and the + # object in this array is sent to the job template as 'platform'. If no platforms are specified, + # one job runs on 'defaultManagedPlatform'. + platforms: [] + + is1ESPipeline: '' + +jobs: + +- ${{ if ne(parameters.allCompletedJobId, '') }}: + - job: ${{ parameters.allCompletedJobId }} + displayName: Source-Build Complete + pool: server + dependsOn: + - ${{ each platform in parameters.platforms }}: + - ${{ parameters.jobNamePrefix }}_${{ platform.name }} + - ${{ if eq(length(parameters.platforms), 0) }}: + - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} + +- ${{ each platform in parameters.platforms }}: + - template: /eng/common/core-templates/job/source-build.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ platform }} + +- ${{ if eq(length(parameters.platforms), 0) }}: + - template: /eng/common/core-templates/job/source-build.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ parameters.defaultManagedPlatform }} diff --git a/eng/common/core-templates/post-build/common-variables.yml b/eng/common/core-templates/post-build/common-variables.yml new file mode 100644 index 00000000000000..b9ede10bf099ae --- /dev/null +++ b/eng/common/core-templates/post-build/common-variables.yml @@ -0,0 +1,24 @@ +variables: + - group: Publish-Build-Assets + + # Whether the build is internal or not + - name: IsInternalBuild + value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} + + # Default Maestro++ API Endpoint and API Version + - name: MaestroApiEndPoint + value: "https://maestro.dot.net" + - name: MaestroApiAccessToken + value: $(MaestroAccessToken) + - name: MaestroApiVersion + value: "2020-02-20" + + - name: SourceLinkCLIVersion + value: 3.0.0 + - name: SymbolToolVersion + value: 1.0.1 + - name: BinlogToolVersion + value: 1.0.11 + + - name: runCodesignValidationInjection + value: false diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml new file mode 100644 index 00000000000000..ed1e6692f739b2 --- /dev/null +++ b/eng/common/core-templates/post-build/post-build.yml @@ -0,0 +1,298 @@ +parameters: + # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. + # Publishing V1 is no longer supported + # Publishing V2 is no longer supported + # Publishing V3 is the default + - name: publishingInfraVersion + displayName: Which version of publishing should be used to promote the build definition? + type: number + default: 3 + values: + - 3 + + - name: BARBuildId + displayName: BAR Build Id + type: number + default: 0 + + - name: PromoteToChannelIds + displayName: Channel to promote BARBuildId to + type: string + default: '' + + - name: enableSourceLinkValidation + displayName: Enable SourceLink validation + type: boolean + default: false + + - name: enableSigningValidation + displayName: Enable signing validation + type: boolean + default: true + + - name: enableSymbolValidation + displayName: Enable symbol validation + type: boolean + default: false + + - name: enableNugetValidation + displayName: Enable NuGet validation + type: boolean + default: true + + - name: publishInstallersAndChecksums + displayName: Publish installers and checksums + type: boolean + default: true + + - name: SDLValidationParameters + type: object + default: + enable: false + publishGdn: false + continueOnError: false + params: '' + artifactNames: '' + downloadArtifacts: true + + # These parameters let the user customize the call to sdk-task.ps1 for publishing + # symbols & general artifacts as well as for signing validation + - name: symbolPublishingAdditionalParameters + displayName: Symbol publishing additional parameters + type: string + default: '' + + - name: artifactsPublishingAdditionalParameters + displayName: Artifact publishing additional parameters + type: string + default: '' + + - name: signingValidationAdditionalParameters + displayName: Signing validation additional parameters + type: string + default: '' + + # Which stages should finish execution before post-build stages start + - name: validateDependsOn + type: object + default: + - build + + - name: publishDependsOn + type: object + default: + - Validate + + # Optional: Call asset publishing rather than running in a separate stage + - name: publishAssetsImmediately + type: boolean + default: false + + - name: is1ESPipeline + type: boolean + default: false + +stages: +- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + - stage: Validate + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Validate Build Assets + variables: + - template: /eng/common/core-templates/post-build/common-variables.yml + - template: /eng/common/core-templates/variables/pool-providers.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + jobs: + - job: + displayName: NuGet Validation + condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + + steps: + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + + - job: + displayName: Signing Validation + condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + steps: + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + itemPattern: | + ** + !**/Microsoft.SourceBuild.Intermediate.*.nupkg + + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@1 + displayName: 'Authenticate to AzDO Feeds' + + # Signing validation will optionally work with the buildmanifest file which is downloaded from + # Azure DevOps above. + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task SigningValidation -restore -msbuildEngine vs + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' + /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' + ${{ parameters.signingValidationAdditionalParameters }} + + - template: /eng/common/core-templates/steps/publish-logs.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + StageLabel: 'Validation' + JobLabel: 'Signing' + BinlogToolVersion: $(BinlogToolVersion) + + - job: + displayName: SourceLink Validation + condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022 + os: windows + steps: + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Blob Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: BlobArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) + -GHCommit $(Build.SourceVersion) + -SourcelinkCliVersion $(SourceLinkCLIVersion) + continueOnError: true + +- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: + - stage: publish_using_darc + ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + dependsOn: ${{ parameters.publishDependsOn }} + ${{ else }}: + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Publish using Darc + variables: + - template: /eng/common/core-templates/post-build/common-variables.yml + - template: /eng/common/core-templates/variables/pool-providers.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + jobs: + - job: + displayName: Publish Using Darc + timeoutInMinutes: 120 + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: NetCore1ESPool-Publishing-Internal + image: windows.vs2019.amd64 + os: windows + steps: + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' diff --git a/eng/common/core-templates/post-build/setup-maestro-vars.yml b/eng/common/core-templates/post-build/setup-maestro-vars.yml new file mode 100644 index 00000000000000..8d56b5726793f8 --- /dev/null +++ b/eng/common/core-templates/post-build/setup-maestro-vars.yml @@ -0,0 +1,74 @@ +parameters: + BARBuildId: '' + PromoteToChannelIds: '' + is1ESPipeline: '' + +steps: + - ${{ if eq(parameters.is1ESPipeline, '') }}: + - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error + + - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download Release Configs + inputs: + buildType: current + artifactName: ReleaseConfigs + checkDownloadedFiles: true + + - task: PowerShell@2 + name: setReleaseVars + displayName: Set Release Configs Vars + inputs: + targetType: inline + pwsh: true + script: | + try { + if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { + $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt + + $BarId = $Content | Select -Index 0 + $Channels = $Content | Select -Index 1 + $IsStableBuild = $Content | Select -Index 2 + + $AzureDevOpsProject = $Env:System_TeamProject + $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId + $AzureDevOpsBuildId = $Env:Build_BuildId + } + else { + $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" + + $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $apiHeaders.Add('Accept', 'application/json') + $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") + + $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + + $BarId = $Env:BARBuildId + $Channels = $Env:PromoteToMaestroChannels -split "," + $Channels = $Channels -join "][" + $Channels = "[$Channels]" + + $IsStableBuild = $buildInfo.stable + $AzureDevOpsProject = $buildInfo.azureDevOpsProject + $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId + $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId + } + + Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" + Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" + Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" + + Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" + Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" + Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" + } + catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + exit 1 + } + env: + MAESTRO_API_TOKEN: $(MaestroApiAccessToken) + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} diff --git a/eng/common/core-templates/post-build/trigger-subscription.yml b/eng/common/core-templates/post-build/trigger-subscription.yml new file mode 100644 index 00000000000000..da669030daf6e9 --- /dev/null +++ b/eng/common/core-templates/post-build/trigger-subscription.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Triggering subscriptions + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 + arguments: -SourceRepo $(Build.Repository.Uri) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/core-templates/steps/add-build-to-channel.yml b/eng/common/core-templates/steps/add-build-to-channel.yml new file mode 100644 index 00000000000000..f67a210d62f3e5 --- /dev/null +++ b/eng/common/core-templates/steps/add-build-to-channel.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Add Build to Channel + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 + arguments: -BuildId $(BARBuildId) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroApiAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/core-templates/steps/component-governance.yml b/eng/common/core-templates/steps/component-governance.yml new file mode 100644 index 00000000000000..df449a34c11207 --- /dev/null +++ b/eng/common/core-templates/steps/component-governance.yml @@ -0,0 +1,14 @@ +parameters: + disableComponentGovernance: false + componentGovernanceIgnoreDirectories: '' + is1ESPipeline: false + +steps: +- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: + - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + displayName: Set skipComponentGovernanceDetection variable +- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: + - task: ComponentGovernanceComponentDetection@0 + continueOnError: true + inputs: + ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml new file mode 100644 index 00000000000000..d938b60e1bb534 --- /dev/null +++ b/eng/common/core-templates/steps/generate-sbom.yml @@ -0,0 +1,54 @@ +# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. +# PackageName - The name of the package this SBOM represents. +# PackageVersion - The version of the package this SBOM represents. +# ManifestDirPath - The path of the directory where the generated manifest files will be placed +# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. + +parameters: + PackageVersion: 9.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + PackageName: '.NET' + ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom + IgnoreDirectories: '' + sbomContinueOnError: true + is1ESPipeline: false + # disable publishArtifacts if some other step is publishing the artifacts (like job.yml). + publishArtifacts: true + +steps: +- task: PowerShell@2 + displayName: Prep for SBOM generation in (Non-linux) + condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) + inputs: + filePath: ./eng/common/generate-sbom-prep.ps1 + arguments: ${{parameters.manifestDirPath}} + +# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 +- script: | + chmod +x ./eng/common/generate-sbom-prep.sh + ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} + displayName: Prep for SBOM generation in (Linux) + condition: eq(variables['Agent.Os'], 'Linux') + continueOnError: ${{ parameters.sbomContinueOnError }} + +- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 'Generate SBOM manifest' + continueOnError: ${{ parameters.sbomContinueOnError }} + inputs: + PackageName: ${{ parameters.packageName }} + BuildDropPath: ${{ parameters.buildDropPath }} + PackageVersion: ${{ parameters.packageVersion }} + ManifestDirPath: ${{ parameters.manifestDirPath }} + ${{ if ne(parameters.IgnoreDirectories, '') }}: + AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' + +- ${{ if eq(parameters.publishArtifacts, 'true')}}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + displayName: Publish SBOM manifest + continueOnError: ${{parameters.sbomContinueOnError}} + targetPath: '${{ parameters.manifestDirPath }}' + artifactName: $(ARTIFACT_NAME) + diff --git a/eng/common/core-templates/steps/publish-build-artifacts.yml b/eng/common/core-templates/steps/publish-build-artifacts.yml new file mode 100644 index 00000000000000..f24ce346684e60 --- /dev/null +++ b/eng/common/core-templates/steps/publish-build-artifacts.yml @@ -0,0 +1,20 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: false +- name: args + type: object + default: {} +steps: +- ${{ if ne(parameters.is1ESPipeline, true) }}: + - template: /eng/common/templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + ${{ each parameter in parameters.args }}: + ${{ parameter.key }}: ${{ parameter.value }} +- ${{ else }}: + - template: /eng/common/templates-official/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + ${{ each parameter in parameters.args }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml new file mode 100644 index 00000000000000..8c5ea77b586d27 --- /dev/null +++ b/eng/common/core-templates/steps/publish-logs.yml @@ -0,0 +1,59 @@ +parameters: + StageLabel: '' + JobLabel: '' + CustomSensitiveDataList: '' + # A default - in case value from eng/common/core-templates/post-build/common-variables.yml is not passed + BinlogToolVersion: '1.0.11' + is1ESPipeline: false + +steps: +- task: Powershell@2 + displayName: Prepare Binlogs to Upload + inputs: + targetType: inline + script: | + New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + continueOnError: true + condition: always() + +- task: PowerShell@2 + displayName: Redact Logs + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/redact-logs.ps1 + # For now this needs to have explicit list of all sensitive data. Taken from eng/publishing/v3/publish.yml + # Sensitive data can as well be added to $(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' + # If the file exists - sensitive data for redaction will be sourced from it + # (single entry per line, lines starting with '# ' are considered comments and skipped) + arguments: -InputPath '$(Build.SourcesDirectory)/PostBuildLogs' + -BinlogToolVersion ${{parameters.BinlogToolVersion}} + -TokensFilePath '$(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' + '$(publishing-dnceng-devdiv-code-r-build-re)' + '$(MaestroAccessToken)' + '$(dn-bot-all-orgs-artifact-feeds-rw)' + '$(akams-client-id)' + '$(akams-client-secret)' + '$(microsoft-symbol-server-pat)' + '$(symweb-symbol-server-pat)' + '$(dn-bot-all-orgs-build-rw-code-rw)' + ${{parameters.CustomSensitiveDataList}} + continueOnError: true + condition: always() + +- task: CopyFiles@2 + displayName: Gather post build logs + inputs: + SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs' + +- template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + displayName: Publish Logs + pathToPublish: '$(Build.ArtifactStagingDirectory)/PostBuildLogs' + publishLocation: Container + artifactName: PostBuildLogs + continueOnError: true + condition: always() diff --git a/eng/common/core-templates/steps/publish-pipeline-artifacts.yml b/eng/common/core-templates/steps/publish-pipeline-artifacts.yml new file mode 100644 index 00000000000000..2efec04dc2c163 --- /dev/null +++ b/eng/common/core-templates/steps/publish-pipeline-artifacts.yml @@ -0,0 +1,20 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: false + +- name: args + type: object + default: {} + +steps: +- ${{ if ne(parameters.is1ESPipeline, true) }}: + - template: /eng/common/templates/steps/publish-pipeline-artifacts.yml + parameters: + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} +- ${{ else }}: + - template: /eng/common/templates-official/steps/publish-pipeline-artifacts.yml + parameters: + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/core-templates/steps/retain-build.yml b/eng/common/core-templates/steps/retain-build.yml new file mode 100644 index 00000000000000..83d97a26a01ff9 --- /dev/null +++ b/eng/common/core-templates/steps/retain-build.yml @@ -0,0 +1,28 @@ +parameters: + # Optional azure devops PAT with build execute permissions for the build's organization, + # only needed if the build that should be retained ran on a different organization than + # the pipeline where this template is executing from + Token: '' + # Optional BuildId to retain, defaults to the current running build + BuildId: '' + # Azure devops Organization URI for the build in the https://dev.azure.com/ format. + # Defaults to the organization the current pipeline is running on + AzdoOrgUri: '$(System.CollectionUri)' + # Azure devops project for the build. Defaults to the project the current pipeline is running on + AzdoProject: '$(System.TeamProject)' + +steps: + - task: powershell@2 + inputs: + targetType: 'filePath' + filePath: eng/common/retain-build.ps1 + pwsh: true + arguments: > + -AzdoOrgUri: ${{parameters.AzdoOrgUri}} + -AzdoProject ${{parameters.AzdoProject}} + -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} + -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} + displayName: Enable permanent build retention + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + BUILD_ID: $(Build.BuildId) \ No newline at end of file diff --git a/eng/common/core-templates/steps/send-to-helix.yml b/eng/common/core-templates/steps/send-to-helix.yml new file mode 100644 index 00000000000000..68fa739c4ab215 --- /dev/null +++ b/eng/common/core-templates/steps/send-to-helix.yml @@ -0,0 +1,93 @@ +# Please remember to update the documentation if you make changes to these parameters! +parameters: + HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ + HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' + HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number + HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixProjectPath: 'eng/common/helixpublish.proj' # optional -- path to the project file to build relative to BUILD_SOURCESDIRECTORY + HelixProjectArguments: '' # optional -- arguments passed to the build command + HelixConfiguration: '' # optional -- additional property attached to a job + HelixPreCommands: '' # optional -- commands to run before Helix work item execution + HelixPostCommands: '' # optional -- commands to run after Helix work item execution + WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects + WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects + WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects + CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload + XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true + XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects + XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects + XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner + XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects + IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion + DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." + IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set + HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) + Creator: '' # optional -- if the build is external, use this to specify who is sending the job + DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO + condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() + continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false + +steps: + - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' + displayName: ${{ parameters.DisplayNamePrefix }} (Windows) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Unix) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml new file mode 100644 index 00000000000000..bdd725b496f91b --- /dev/null +++ b/eng/common/core-templates/steps/source-build.yml @@ -0,0 +1,134 @@ +parameters: + # This template adds arcade-powered source-build to CI. + + # This is a 'steps' template, and is intended for advanced scenarios where the existing build + # infra has a careful build methodology that must be followed. For example, a repo + # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline + # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to + # GitHub. Using this steps template leaves room for that infra to be included. + + # Defines the platform on which to run the steps. See 'eng/common/core-templates/job/source-build.yml' + # for details. The entire object is described in the 'job' template for simplicity, even though + # the usage of the properties on this object is split between the 'job' and 'steps' templates. + platform: {} + is1ESPipeline: false + +steps: +# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) +- script: | + set -x + df -h + + # If building on the internal project, the artifact feeds variable may be available (usually only if needed) + # In that case, call the feed setup script to add internal feeds corresponding to public ones. + # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. + # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those + # changes. + internalRestoreArgs= + if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then + # Temporarily work around https://github.com/dotnet/arcade/issues/7709 + chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh + $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) + internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' + + # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. + # This only works if there is a username/email configured, which won't be the case in most CI runs. + git config --get user.email + if [ $? -ne 0 ]; then + git config user.email dn-bot@microsoft.com + git config user.name dn-bot + fi + fi + + # If building on the internal project, the internal storage variable may be available (usually only if needed) + # In that case, add variables to allow the download of internal runtimes if the specified versions are not found + # in the default public locations. + internalRuntimeDownloadArgs= + if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + fi + + buildConfig=Release + # Check if AzDO substitutes in a build config from a variable, and use it if so. + if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then + buildConfig='$(_BuildConfig)' + fi + + officialBuildArgs= + if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then + officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' + fi + + targetRidArgs= + if [ '${{ parameters.platform.targetRID }}' != '' ]; then + targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' + fi + + runtimeOsArgs= + if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then + runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}' + fi + + baseOsArgs= + if [ '${{ parameters.platform.baseOS }}' != '' ]; then + baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}' + fi + + publishArgs= + if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then + publishArgs='--publish' + fi + + assetManifestFileName=SourceBuild_RidSpecific.xml + if [ '${{ parameters.platform.name }}' != '' ]; then + assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml + fi + + ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ + --configuration $buildConfig \ + --restore --build --pack $publishArgs -bl \ + $officialBuildArgs \ + $internalRuntimeDownloadArgs \ + $internalRestoreArgs \ + $targetRidArgs \ + $runtimeOsArgs \ + $baseOsArgs \ + /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ + /p:ArcadeBuildFromSource=true \ + /p:DotNetBuildSourceOnly=true \ + /p:DotNetBuildRepo=true \ + /p:AssetManifestFileName=$assetManifestFileName + displayName: Build + +# Upload build logs for diagnosis. +- task: CopyFiles@2 + displayName: Prepare BuildLogs staging directory + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/*.log + **/*.binlog + artifacts/sb/prebuilt-report/** + TargetFolder: '$(Build.StagingDirectory)/BuildLogs' + CleanTargetFolder: true + continueOnError: true + condition: succeededOrFailed() + +- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + displayName: Publish BuildLogs + targetPath: '$(Build.StagingDirectory)/BuildLogs' + artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) + continueOnError: true + condition: succeededOrFailed() + +# Manually inject component detection so that we can ignore the source build upstream cache, which contains +# a nupkg cache of input packages (a local feed). +# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' +# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets +- task: ComponentGovernanceComponentDetection@0 + displayName: Component Detection (Exclude upstream cache) + inputs: + ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache' diff --git a/eng/common/core-templates/variables/pool-providers.yml b/eng/common/core-templates/variables/pool-providers.yml new file mode 100644 index 00000000000000..41053d382a2e10 --- /dev/null +++ b/eng/common/core-templates/variables/pool-providers.yml @@ -0,0 +1,8 @@ +parameters: + is1ESPipeline: false + +variables: + - ${{ if eq(parameters.is1ESPipeline, 'true') }}: + - template: /eng/common/templates-official/variables/pool-providers.yml + - ${{ else }}: + - template: /eng/common/templates/variables/pool-providers.yml \ No newline at end of file diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 3762640fdcf792..9a4e285a5ae3f0 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -382,6 +382,26 @@ if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$") endif() endif() +# Set C++ standard library options if specified +set(CLR_CMAKE_CXX_STANDARD_LIBRARY "" CACHE STRING "Standard library flavor to link against. Only supported with the Clang compiler.") +if (CLR_CMAKE_CXX_STANDARD_LIBRARY) + add_compile_options($<$:--stdlib=${CLR_CMAKE_CXX_STANDARD_LIBRARY}>) + add_link_options($<$:--stdlib=${CLR_CMAKE_CXX_STANDARD_LIBRARY}>) +endif() + +option(CLR_CMAKE_CXX_STANDARD_LIBRARY_STATIC "Statically link against the C++ standard library" OFF) +if(CLR_CMAKE_CXX_STANDARD_LIBRARY_STATIC) + add_link_options($<$:-static-libstdc++>) +endif() + +set(CLR_CMAKE_CXX_ABI_LIBRARY "" CACHE STRING "C++ ABI implementation library to link against. Only supported with the Clang compiler.") +if (CLR_CMAKE_CXX_ABI_LIBRARY) + # The user may specify the ABI library with the 'lib' prefix, like 'libstdc++'. Strip the prefix here so the linker finds the right library. + string(REGEX REPLACE "^lib(.+)" "\\1" CLR_CMAKE_CXX_ABI_LIBRARY ${CLR_CMAKE_CXX_ABI_LIBRARY}) + # We need to specify this as a linker-backend option as Clang will filter this option out when linking to libc++. + add_link_options("LINKER:-l${CLR_CMAKE_CXX_ABI_LIBRARY}") +endif() + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh index afdeb7a4d54aee..ccd3a17268e243 100644 --- a/eng/common/native/init-compiler.sh +++ b/eng/common/native/init-compiler.sh @@ -64,7 +64,7 @@ if [ -z "$CLR_CC" ]; then if [ -z "$majorVersion" ]; then # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. if [ "$compiler" = "clang" ]; then versions="18 17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" - elif [ "$compiler" = "gcc" ]; then versions="13 12 11 10 9 8 7 6 5 4.9"; fi + elif [ "$compiler" = "gcc" ]; then versions="14 13 12 11 10 9 8 7 6 5 4.9"; fi for version in $versions; do _major="${version%%.*}" diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index 091023970f1c9c..aab40de3fd9aca 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.8.5" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md new file mode 100644 index 00000000000000..c114bc28dcb95d --- /dev/null +++ b/eng/common/template-guidance.md @@ -0,0 +1,137 @@ +# Overview + +Arcade provides templates for public (`/templates`) and 1ES pipeline templates (`/templates-official`) scenarios. Pipelines which are required to be managed by 1ES pipeline templates should reference `/templates-offical`, all other pipelines may reference `/templates`. + +## How to use + +Basic guidance is: + +- 1ES Pipeline Template or 1ES Microbuild template runs should reference `eng/common/templates-official`. Any internal production-graded pipeline should use these templates. + +- All other runs should reference `eng/common/templates`. + +See [azure-pipelines.yml](../../azure-pipelines.yml) (templates-official example) or [azure-pipelines-pr.yml](../../azure-pipelines-pr.yml) (templates example) for examples. + +#### The `templateIs1ESManaged` parameter + +The `templateIs1ESManaged` is available on most templates and affects which of the variants is used for nested templates. See [Development Notes](#development-notes) below for more information on the `templateIs1ESManaged1 parameter. + +- For templates under `job/`, `jobs/`, `steps`, or `post-build/`, this parameter must be explicitly set. + +## Multiple outputs + +1ES pipeline templates impose a policy where every publish artifact execution results in additional security scans being injected into your pipeline. When using `templates-official/jobs/jobs.yml`, Arcade reduces the number of additional security injections by gathering all publishing outputs into the [Build.ArtifactStagingDirectory](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services), and utilizing the [outputParentDirectory](https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs#multiple-outputs) feature of 1ES pipeline templates. When implementing your pipeline, if you ensure publish artifacts are located in the `$(Build.ArtifactStagingDirectory)`, and utilize the 1ES provided template context, then you can reduce the number of security scans for your pipeline. + +Example: +``` yaml +# azure-pipelines.yml +extends: + template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate + parameters: + stages: + - stage: build + jobs: + - template: /eng/common/templates-official/jobs/jobs.yml@self + parameters: + # 1ES makes use of outputs to reduce security task injection overhead + templateContext: + outputs: + - output: pipelineArtifact + displayName: 'Publish logs from source' + continueOnError: true + condition: always() + targetPath: $(Build.ArtifactStagingDirectory)/artifacts/log + artifactName: Logs + jobs: + - job: Windows + steps: + - script: echo "friendly neighborhood" > artifacts/marvel/spiderman.txt + # copy build outputs to artifact staging directory for publishing + - task: CopyFiles@2 + displayName: Gather build output + inputs: + SourceFolder: '$(Build.SourcesDirectory)/artifacts/marvel' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/marvel' +``` + +Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`). + +# Development notes + +**Folder / file structure** + +``` text +eng\common\ + [templates || templates-official]\ + job\ + job.yml (shim + artifact publishing logic) + onelocbuild.yml (shim) + publish-build-assets.yml (shim) + source-build.yml (shim) + source-index-stage1.yml (shim) + jobs\ + codeql-build.yml (shim) + jobs.yml (shim) + source-build.yml (shim) + post-build\ + post-build.yml (shim) + trigger-subscription.yml (shim) + common-variabls.yml (shim) + setup-maestro-vars.yml (shim) + steps\ + publish-build-artifacts.yml (logic) + publish-pipeline-artifacts.yml (logic) + add-build-channel.yml (shim) + component-governance.yml (shim) + generate-sbom.yml (shim) + publish-logs.yml (shim) + retain-build.yml (shim) + send-to-helix.yml (shim) + source-build.yml (shim) + variables\ + pool-providers.yml (logic + redirect) # templates/variables/pool-providers.yml will redirect to templates-official/variables/pool-providers.yml if you are running in the internal project + sdl-variables.yml (logic) + core-templates\ + job\ + job.yml (logic) + onelocbuild.yml (logic) + publish-build-assets.yml (logic) + source-build.yml (logic) + source-index-stage1.yml (logic) + jobs\ + codeql-build.yml (logic) + jobs.yml (logic) + source-build.yml (logic) + post-build\ + common-variabls.yml (logic) + post-build.yml (logic) + setup-maestro-vars.yml (logic) + trigger-subscription.yml (logic) + steps\ + add-build-to-channel.yml (logic) + component-governance.yml (logic) + generate-sbom.yml (logic) + publish-build-artifacts.yml (redirect) + publish-logs.yml (logic) + publish-pipeline-artifacts.yml (redirect) + retain-build.yml (logic) + send-to-helix.yml (logic) + source-build.yml (logic) + variables\ + pool-providers.yml (redirect) +``` + +In the table above, a file is designated as "shim", "logic", or "redirect". + +- shim - represents a yaml file which is an intermediate step between pipeline logic and .Net Core Engineering's templates (`core-templates`) and defines the `is1ESPipeline` parameter value. + +- logic - represents actual base template logic. + +- redirect- represents a file in `core-templates` which redirects to the "logic" file in either `templates` or `templates-official`. + +Logic for Arcade's templates live **primarily** in the `core-templates` folder. The exceptions to the location of the logic files are around artifact publishing, which is handled differently between 1es pipeline templates and standard templates. `templates` and `templates-official` provide shim entry points which redirect to `core-templates` while also defining the `is1ESPipeline` parameter. If a shim is referenced in `templates`, then `is1ESPipeline` is set to `false`. If a shim is referenced in `templates-official`, then `is1ESPipeline` is set to `true`. + +Within `templates` and `templates-official`, the templates at the "stages", and "jobs" / "job" level have been replaced with shims. Templates at the "steps" and "variables" level are typically too granular to be replaced with shims and instead persist logic which is directly applicable to either scenario. + +Within `core-templates`, there are a handful of places where logic is dependent on which shim entry point was used. In those places, we redirect back to the respective logic file in `templates` or `templates-official`. diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 761acc5eb624c6..4724e9aaa80910 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -1,264 +1,62 @@ -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - -parameters: -# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - cancelTimeoutInMinutes: '' - condition: '' - container: '' - continueOnError: false - dependsOn: '' - displayName: '' - pool: '' - steps: [] - strategy: '' - timeoutInMinutes: '' - variables: [] - workspace: '' - templateContext: '' - -# Job base template specific parameters - # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md - artifacts: '' - enableMicrobuild: false - enablePublishBuildArtifacts: false - enablePublishBuildAssets: false - enablePublishTestResults: false - enablePublishUsingPipelines: false - enableBuildRetry: false - disableComponentGovernance: '' - componentGovernanceIgnoreDirectories: '' - mergeTestResults: false - testRunTitle: '' - testResultsFormat: '' - name: '' - preSteps: [] - runAsPublic: false -# Sbom related params - enableSbom: true - PackageVersion: 7.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - jobs: -- job: ${{ parameters.name }} - - ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: - cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} - - ${{ if ne(parameters.condition, '') }}: - condition: ${{ parameters.condition }} - - ${{ if ne(parameters.container, '') }}: - container: ${{ parameters.container }} - - ${{ if ne(parameters.continueOnError, '') }}: - continueOnError: ${{ parameters.continueOnError }} - - ${{ if ne(parameters.dependsOn, '') }}: - dependsOn: ${{ parameters.dependsOn }} - - ${{ if ne(parameters.displayName, '') }}: - displayName: ${{ parameters.displayName }} - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - - ${{ if ne(parameters.strategy, '') }}: - strategy: ${{ parameters.strategy }} - - ${{ if ne(parameters.timeoutInMinutes, '') }}: - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - - ${{ if ne(parameters.templateContext, '') }}: - templateContext: ${{ parameters.templateContext }} - - variables: - - ${{ if ne(parameters.enableTelemetry, 'false') }}: - - name: DOTNET_CLI_TELEMETRY_PROFILE - value: '$(Build.Repository.Uri)' - - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: - - name: EnableRichCodeNavigation - value: 'true' - # Retry signature validation up to three times, waiting 2 seconds between attempts. - # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures - - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY - value: 3,2000 - - ${{ each variable in parameters.variables }}: - # handle name-value variable syntax - # example: - # - name: [key] - # value: [value] - - ${{ if ne(variable.name, '') }}: - - name: ${{ variable.name }} - value: ${{ variable.value }} - - # handle variable groups - - ${{ if ne(variable.group, '') }}: - - group: ${{ variable.group }} - - # handle template variable syntax - # example: - # - template: path/to/template.yml - # parameters: - # [key]: [value] - - ${{ if ne(variable.template, '') }}: - - template: ${{ variable.template }} - ${{ if ne(variable.parameters, '') }}: - parameters: ${{ variable.parameters }} - - # handle key-value variable syntax. - # example: - # - [key]: [value] - - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: - - ${{ each pair in variable }}: - - name: ${{ pair.key }} - value: ${{ pair.value }} - - # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds - - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: DotNet-HelixApi-Access - - ${{ if ne(parameters.workspace, '') }}: - workspace: ${{ parameters.workspace }} - - steps: - - ${{ if ne(parameters.preSteps, '') }}: - - ${{ each preStep in parameters.preSteps }}: - - ${{ preStep }} - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - task: MicroBuildSigningPlugin@4 - displayName: Install MicroBuild plugin - inputs: - signType: $(_SignType) - zipSources: false - feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - env: - TeamName: $(_TeamName) - MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' - continueOnError: ${{ parameters.continueOnError }} - condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - - - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: - - task: NuGetAuthenticate@1 - - - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: - - task: DownloadPipelineArtifact@2 - inputs: - buildType: current - artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} - targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} - itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} - - - ${{ each step in parameters.steps }}: - - ${{ step }} - - - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: - - task: RichCodeNavIndexer@0 - displayName: RichCodeNav Upload - inputs: - languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} - environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'internal') }} - richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin - uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} - continueOnError: true - - - template: /eng/common/templates-official/steps/component-governance.yml - parameters: - ${{ if eq(parameters.disableComponentGovernance, '') }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: - disableComponentGovernance: false - ${{ else }}: - disableComponentGovernance: true - ${{ else }}: - disableComponentGovernance: ${{ parameters.disableComponentGovernance }} - componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: MicroBuildCleanup@1 - displayName: Execute Microbuild cleanup tasks - condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - env: - TeamName: $(_TeamName) - - - ${{ if ne(parameters.artifacts.publish, '') }}: - - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - - task: CopyFiles@2 - displayName: Gather binaries for publish to artifacts - inputs: - SourceFolder: 'artifacts/bin' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' - - task: CopyFiles@2 - displayName: Gather packages for publish to artifacts - inputs: - SourceFolder: 'artifacts/packages' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish pipeline artifacts - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} - continueOnError: true - condition: always() - - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - task: 1ES.PublishPipelineArtifact@1 - inputs: - targetPath: 'artifacts/log' - artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)_Attempt$(System.JobAttempt)') }} - displayName: 'Publish logs' - continueOnError: true - condition: always() - - - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} - continueOnError: true - condition: always() - - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: - - task: PublishTestResults@2 - displayName: Publish XUnit Test Results - inputs: - testResultsFormat: 'xUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: - - task: PublishTestResults@2 - displayName: Publish TRX Test Results - inputs: - testResultsFormat: 'VSTest' - testResultsFiles: '*.trx' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: - - template: /eng/common/templates-official/steps/generate-sbom.yml - parameters: - PackageVersion: ${{ parameters.packageVersion}} - BuildDropPath: ${{ parameters.buildDropPath }} - IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if eq(parameters.enableBuildRetry, 'true') }}: - - task: 1ES.PublishPipelineArtifact@1 - inputs: - targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' - artifactName: 'BuildConfiguration' - displayName: 'Publish build retry configuration' - continueOnError: true \ No newline at end of file +- template: /eng/common/core-templates/job/job.yml + parameters: + is1ESPipeline: true + + # publish artifacts + # for 1ES managed templates, use the templateContext.output to handle multiple outputs. + templateContext: + outputParentDirectory: $(Build.ArtifactStagingDirectory) + outputs: + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - output: buildArtifacts + displayName: Publish pipeline artifacts + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + condition: always() + continueOnError: true + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - output: pipelineArtifact + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)_Attempt$(System.JobAttempt)') }} + displayName: 'Publish logs' + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}: + - output: buildArtifacts + displayName: Publish Logs + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + publishLocation: Container + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - output: pipelineArtifact + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/eng/common/BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - output: pipelineArtifact + displayName: Publish SBOM manifest + continueOnError: true + targetPath: $(Build.ArtifactStagingDirectory)/sbom + artifactName: $(ARTIFACT_NAME) + + # add any outputs provided via root yaml + - ${{ if ne(parameters.templateContext.outputs, '') }}: + - ${{ each output in parameters.templateContext.outputs }}: + - ${{ output }} + + # add any remaining templateContext properties + ${{ each context in parameters.templateContext }}: + ${{ if and(ne(context.key, 'outputParentDirectory'), ne(context.key, 'outputs')) }}: + ${{ context.key }}: ${{ context.value }} + + ${{ each parameter in parameters }}: + ${{ if and(ne(parameter.key, 'templateContext'), ne(parameter.key, 'is1ESPipeline')) }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml index 52b4d05d3f8dd6..0f0c514b912dfc 100644 --- a/eng/common/templates-official/job/onelocbuild.yml +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -1,112 +1,7 @@ -parameters: - # Optional: dependencies of the job - dependsOn: '' - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: '' - - CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex - GithubPat: $(BotAccount-dotnet-bot-repo-PAT) - - SourcesDirectory: $(Build.SourcesDirectory) - CreatePr: true - AutoCompletePr: false - ReusePr: true - UseLfLineEndings: true - UseCheckedInLocProjectJson: false - SkipLocProjectJsonGeneration: false - LanguageSet: VS_Main_Languages - LclSource: lclFilesInRepo - LclPackageId: '' - RepoType: gitHub - GitHubOrg: dotnet - MirrorRepo: '' - MirrorBranch: main - condition: '' - JobNameSuffix: '' - jobs: -- job: OneLocBuild${{ parameters.JobNameSuffix }} - - dependsOn: ${{ parameters.dependsOn }} - - displayName: OneLocBuild${{ parameters.JobNameSuffix }} - - variables: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - - name: _GenerateLocProjectArguments - value: -SourcesDirectory ${{ parameters.SourcesDirectory }} - -LanguageSet "${{ parameters.LanguageSet }}" - -CreateNeutralXlfs - - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: - - name: _GenerateLocProjectArguments - value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson - - template: /eng/common/templates-official/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - - steps: - - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: - - task: Powershell@2 - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 - arguments: $(_GenerateLocProjectArguments) - displayName: Generate LocProject.json - condition: ${{ parameters.condition }} - - - task: OneLocBuild@2 - displayName: OneLocBuild - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - inputs: - locProj: eng/Localize/LocProject.json - outDir: $(Build.ArtifactStagingDirectory) - lclSource: ${{ parameters.LclSource }} - lclPackageId: ${{ parameters.LclPackageId }} - isCreatePrSelected: ${{ parameters.CreatePr }} - isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} - ${{ if eq(parameters.CreatePr, true) }}: - isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - isShouldReusePrSelected: ${{ parameters.ReusePr }} - packageSourceAuth: patAuth - patVariable: ${{ parameters.CeapexPat }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - repoType: ${{ parameters.RepoType }} - gitHubPatVariable: "${{ parameters.GithubPat }}" - ${{ if ne(parameters.MirrorRepo, '') }}: - isMirrorRepoSelected: true - gitHubOrganization: ${{ parameters.GitHubOrg }} - mirrorRepo: ${{ parameters.MirrorRepo }} - mirrorBranch: ${{ parameters.MirrorBranch }} - condition: ${{ parameters.condition }} - - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish Localization Files - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} +- template: /eng/common/core-templates/job/onelocbuild.yml + parameters: + is1ESPipeline: true - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish LocProject.json - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} \ No newline at end of file + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml index 38340d3e38614a..d667a70e8de743 100644 --- a/eng/common/templates-official/job/publish-build-assets.yml +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -1,159 +1,7 @@ -parameters: - configuration: 'Debug' - - # Optional: condition for the job to run - condition: '' - - # Optional: 'true' if future jobs should run even if this job fails - continueOnError: false - - # Optional: dependencies of the job - dependsOn: '' - - # Optional: Include PublishBuildArtifacts task - enablePublishBuildArtifacts: false - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: {} - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. - runAsPublic: false - - # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing - publishUsingPipelines: false - - # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing - publishAssetsImmediately: false - - artifactsPublishingAdditionalParameters: '' - - signingValidationAdditionalParameters: '' - jobs: -- job: Asset_Registry_Publish - - dependsOn: ${{ parameters.dependsOn }} - timeoutInMinutes: 150 - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - displayName: Publish Assets - ${{ else }}: - displayName: Publish to Build Asset Registry - - variables: - - template: /eng/common/templates-official/variables/pool-providers.yml - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: Publish-Build-Assets - - group: AzureDevOps-Artifact-Feeds-Pats - - name: runCodesignValidationInjection - value: false - # unconditional - needed for logs publishing (redactor tool version) - - template: /eng/common/templates-official/post-build/common-variables.yml - - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: NetCore1ESPool-Publishing-Internal - image: windows.vs2019.amd64 - os: windows - steps: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - checkout: self - fetchDepth: 3 - clean: true - - - task: DownloadBuildArtifacts@0 - displayName: Download artifact - inputs: - artifactName: AssetManifests - downloadPath: '$(Build.StagingDirectory)/Download' - checkDownloadedFiles: true - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: NuGetAuthenticate@1 - - - task: PowerShell@2 - displayName: Publish Build Assets - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet - /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' - /p:BuildAssetRegistryToken=$(MaestroAccessToken) - /p:MaestroApiEndpoint=https://maestro.dot.net - /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} - /p:OfficialBuildId=$(Build.BuildNumber) - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: powershell@2 - displayName: Create ReleaseConfigs Artifact - inputs: - targetType: inline - script: | - New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force - $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" - Add-Content -Path $filePath -Value $(BARBuildId) - Add-Content -Path $filePath -Value "$(DefaultChannels)" - Add-Content -Path $filePath -Value $(IsStableBuild) - - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish ReleaseConfigs Artifact - inputs: - PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - task: powershell@2 - displayName: Check if SymbolPublishingExclusionsFile.txt exists - inputs: - targetType: inline - script: | - $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" - if(Test-Path -Path $symbolExclusionfile) - { - Write-Host "SymbolExclusionFile exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" - } - else{ - Write-Host "Symbols Exclusion file does not exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" - } - - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish SymbolPublishingExclusionsFile Artifact - condition: eq(variables['SymbolExclusionFile'], 'true') - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion 3 - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' +- template: /eng/common/core-templates/job/publish-build-assets.yml + parameters: + is1ESPipeline: true - - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - - template: /eng/common/templates-official/steps/publish-logs.yml - parameters: - JobLabel: 'Publish_Artifacts_Logs' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml index 2180e97a284f84..1a480034b678eb 100644 --- a/eng/common/templates-official/job/source-build.yml +++ b/eng/common/templates-official/job/source-build.yml @@ -1,67 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. The template produces a server job with a - # default ID 'Source_Build_Complete' to put in a dependency list if necessary. - - # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. - jobNamePrefix: 'Source_Build' - - # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for - # managed-only repositories. This is an object with these properties: - # - # name: '' - # The name of the job. This is included in the job ID. - # targetRID: '' - # The name of the target RID to use, instead of the one auto-detected by Arcade. - # nonPortable: false - # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than - # linux-x64), and compiling against distro-provided packages rather than portable ones. - # skipPublishValidation: false - # Disables publishing validation. By default, a check is performed to ensure no packages are - # published by source-build. - # container: '' - # A container to use. Runs in docker. - # pool: {} - # A pool to use. Runs directly on an agent. - # buildScript: '' - # Specifies the build script to invoke to perform the build in the repo. The default - # './build.sh' should work for typical Arcade repositories, but this is customizable for - # difficult situations. - # jobProperties: {} - # A list of job properties to inject at the top level, for potential extensibility beyond - # container and pool. - platform: {} - jobs: -- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} - displayName: Source-Build (${{ parameters.platform.name }}) - - ${{ each property in parameters.platform.jobProperties }}: - ${{ property.key }}: ${{ property.value }} - - ${{ if ne(parameters.platform.container, '') }}: - container: ${{ parameters.platform.container }} - - ${{ if eq(parameters.platform.pool, '') }}: - # The default VM host AzDO pool. This should be capable of running Docker containers: almost all - # source-build builds run in Docker, including the default managed platform. - # /eng/common/templates-official/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] - demands: ImageOverride -equals build.ubuntu.2004.amd64 - - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - image: 1es-mariner-2 - os: linux - - ${{ if ne(parameters.platform.pool, '') }}: - pool: ${{ parameters.platform.pool }} - - workspace: - clean: all +- template: /eng/common/core-templates/job/source-build.yml + parameters: + is1ESPipeline: true - steps: - - template: /eng/common/templates-official/steps/source-build.yml - parameters: - platform: ${{ parameters.platform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml index 53a9ef51fd82d2..6d5ead316f92b5 100644 --- a/eng/common/templates-official/job/source-index-stage1.yml +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -1,67 +1,7 @@ -parameters: - runAsPublic: false - sourceIndexPackageVersion: 1.0.1-20240129.2 - sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json - sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" - preSteps: [] - binlogPath: artifacts/log/Debug/Build.binlog - condition: '' - dependsOn: '' - pool: '' - jobs: -- job: SourceIndexStage1 - dependsOn: ${{ parameters.dependsOn }} - condition: ${{ parameters.condition }} - variables: - - name: SourceIndexPackageVersion - value: ${{ parameters.sourceIndexPackageVersion }} - - name: SourceIndexPackageSource - value: ${{ parameters.sourceIndexPackageSource }} - - name: BinlogPath - value: ${{ parameters.binlogPath }} - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: source-dot-net stage1 variables - - template: /eng/common/templates-official/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $(DncEngPublicBuildPool) - image: windows.vs2022.amd64.open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $(DncEngInternalBuildPool) - image: windows.vs2022.amd64 - - steps: - - ${{ each preStep in parameters.preSteps }}: - - ${{ preStep }} - - - task: UseDotNet@2 - displayName: Use .NET 8 SDK - inputs: - packageType: sdk - version: 8.0.x - installationPath: $(Agent.TempDirectory)/dotnet - workingDirectory: $(Agent.TempDirectory) - - - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - displayName: Download Tools - # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. - workingDirectory: $(Agent.TempDirectory) - - - script: ${{ parameters.sourceIndexBuildCommand }} - displayName: Build Repository - - - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output - displayName: Process Binlog into indexable sln +- template: /eng/common/core-templates/job/source-index-stage1.yml + parameters: + is1ESPipeline: true - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) - displayName: Upload stage1 artifacts to source index - env: - BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/jobs/codeql-build.yml b/eng/common/templates-official/jobs/codeql-build.yml index b68d3c2f31990f..a726322ecfe016 100644 --- a/eng/common/templates-official/jobs/codeql-build.yml +++ b/eng/common/templates-official/jobs/codeql-build.yml @@ -1,31 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - jobs: -- template: /eng/common/templates-official/jobs/jobs.yml +- template: /eng/common/core-templates/jobs/codeql-build.yml parameters: - enableMicrobuild: false - enablePublishBuildArtifacts: false - enablePublishTestResults: false - enablePublishBuildAssets: false - enablePublishUsingPipelines: false - enableTelemetry: true + is1ESPipeline: true - variables: - - group: Publish-Build-Assets - # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in - # sync with the packages.config file. - - name: DefaultGuardianVersion - value: 0.109.0 - - name: GuardianPackagesConfigFile - value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config - - name: GuardianVersion - value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} - - jobs: ${{ parameters.jobs }} - + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/jobs/jobs.yml b/eng/common/templates-official/jobs/jobs.yml index 857a0f8ba43e84..007deddaea0f53 100644 --- a/eng/common/templates-official/jobs/jobs.yml +++ b/eng/common/templates-official/jobs/jobs.yml @@ -1,97 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - - # Optional: Include PublishBuildArtifacts task - enablePublishBuildArtifacts: false - - # Optional: Enable publishing using release pipelines - enablePublishUsingPipelines: false - - # Optional: Enable running the source-build jobs to build repo from source - enableSourceBuild: false - - # Optional: Parameters for source-build template. - # See /eng/common/templates-official/jobs/source-build.yml for options - sourceBuildParameters: [] - - graphFileGeneration: - # Optional: Enable generating the graph files at the end of the build - enabled: false - # Optional: Include toolset dependencies in the generated graph files - includeToolset: false - - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - - # Optional: Override automatically derived dependsOn value for "publish build assets" job - publishBuildAssetsDependsOn: '' - - # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. - publishAssetsImmediately: false - - # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml) - artifactsPublishingAdditionalParameters: '' - signingValidationAdditionalParameters: '' - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. - runAsPublic: false - - enableSourceIndex: false - sourceIndexParams: {} - -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - jobs: -- ${{ each job in parameters.jobs }}: - - template: ../job/job.yml - parameters: - # pass along parameters - ${{ each parameter in parameters }}: - ${{ if ne(parameter.key, 'jobs') }}: - ${{ parameter.key }}: ${{ parameter.value }} - - # pass along job properties - ${{ each property in job }}: - ${{ if ne(property.key, 'job') }}: - ${{ property.key }}: ${{ property.value }} - - name: ${{ job.job }} - -- ${{ if eq(parameters.enableSourceBuild, true) }}: - - template: /eng/common/templates-official/jobs/source-build.yml - parameters: - allCompletedJobId: Source_Build_Complete - ${{ each parameter in parameters.sourceBuildParameters }}: - ${{ parameter.key }}: ${{ parameter.value }} - -- ${{ if eq(parameters.enableSourceIndex, 'true') }}: - - template: ../job/source-index-stage1.yml - parameters: - runAsPublic: ${{ parameters.runAsPublic }} - ${{ each parameter in parameters.sourceIndexParams }}: - ${{ parameter.key }}: ${{ parameter.value }} - -- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: - - template: ../job/publish-build-assets.yml - parameters: - continueOnError: ${{ parameters.continueOnError }} - dependsOn: - - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.publishBuildAssetsDependsOn }}: - - ${{ job.job }} - - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.jobs }}: - - ${{ job.job }} - - ${{ if eq(parameters.enableSourceBuild, true) }}: - - Source_Build_Complete +- template: /eng/common/core-templates/jobs/jobs.yml + parameters: + is1ESPipeline: true - runAsPublic: ${{ parameters.runAsPublic }} - publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} - publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} - enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/jobs/source-build.yml b/eng/common/templates-official/jobs/source-build.yml index 2076f4e25b43c6..483e7b611f346b 100644 --- a/eng/common/templates-official/jobs/source-build.yml +++ b/eng/common/templates-official/jobs/source-build.yml @@ -1,46 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. A job is created for each platform, as - # well as an optional server job that completes when all platform jobs complete. - - # The name of the "join" job for all source-build platforms. If set to empty string, the job is - # not included. Existing repo pipelines can use this job depend on all source-build jobs - # completing without maintaining a separate list of every single job ID: just depend on this one - # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. - allCompletedJobId: '' - - # See /eng/common/templates-official/job/source-build.yml - jobNamePrefix: 'Source_Build' - - # This is the default platform provided by Arcade, intended for use by a managed-only repo. - defaultManagedPlatform: - name: 'Managed' - container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9' - - # Defines the platforms on which to run build jobs. One job is created for each platform, and the - # object in this array is sent to the job template as 'platform'. If no platforms are specified, - # one job runs on 'defaultManagedPlatform'. - platforms: [] - jobs: +- template: /eng/common/core-templates/jobs/source-build.yml + parameters: + is1ESPipeline: true -- ${{ if ne(parameters.allCompletedJobId, '') }}: - - job: ${{ parameters.allCompletedJobId }} - displayName: Source-Build Complete - pool: server - dependsOn: - - ${{ each platform in parameters.platforms }}: - - ${{ parameters.jobNamePrefix }}_${{ platform.name }} - - ${{ if eq(length(parameters.platforms), 0) }}: - - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} - -- ${{ each platform in parameters.platforms }}: - - template: /eng/common/templates-official/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ platform }} - -- ${{ if eq(length(parameters.platforms), 0) }}: - - template: /eng/common/templates-official/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ parameters.defaultManagedPlatform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates-official/post-build/common-variables.yml b/eng/common/templates-official/post-build/common-variables.yml index b9ede10bf099ae..c32fc49233f8fd 100644 --- a/eng/common/templates-official/post-build/common-variables.yml +++ b/eng/common/templates-official/post-build/common-variables.yml @@ -1,24 +1,8 @@ variables: - - group: Publish-Build-Assets +- template: /eng/common/core-templates/post-build/common-variables.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: true - # Whether the build is internal or not - - name: IsInternalBuild - value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} - - # Default Maestro++ API Endpoint and API Version - - name: MaestroApiEndPoint - value: "https://maestro.dot.net" - - name: MaestroApiAccessToken - value: $(MaestroAccessToken) - - name: MaestroApiVersion - value: "2020-02-20" - - - name: SourceLinkCLIVersion - value: 3.0.0 - - name: SymbolToolVersion - value: 1.0.1 - - name: BinlogToolVersion - value: 1.0.11 - - - name: runCodesignValidationInjection - value: false + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml index da1f40958b450d..2364c0fd4a527e 100644 --- a/eng/common/templates-official/post-build/post-build.yml +++ b/eng/common/templates-official/post-build/post-build.yml @@ -1,285 +1,8 @@ -parameters: - # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. - # Publishing V1 is no longer supported - # Publishing V2 is no longer supported - # Publishing V3 is the default - - name: publishingInfraVersion - displayName: Which version of publishing should be used to promote the build definition? - type: number - default: 3 - values: - - 3 - - - name: BARBuildId - displayName: BAR Build Id - type: number - default: 0 - - - name: PromoteToChannelIds - displayName: Channel to promote BARBuildId to - type: string - default: '' - - - name: enableSourceLinkValidation - displayName: Enable SourceLink validation - type: boolean - default: false - - - name: enableSigningValidation - displayName: Enable signing validation - type: boolean - default: true - - - name: enableSymbolValidation - displayName: Enable symbol validation - type: boolean - default: false - - - name: enableNugetValidation - displayName: Enable NuGet validation - type: boolean - default: true - - - name: publishInstallersAndChecksums - displayName: Publish installers and checksums - type: boolean - default: true - - - name: SDLValidationParameters - type: object - default: - enable: false - publishGdn: false - continueOnError: false - params: '' - artifactNames: '' - downloadArtifacts: true - - # These parameters let the user customize the call to sdk-task.ps1 for publishing - # symbols & general artifacts as well as for signing validation - - name: symbolPublishingAdditionalParameters - displayName: Symbol publishing additional parameters - type: string - default: '' - - - name: artifactsPublishingAdditionalParameters - displayName: Artifact publishing additional parameters - type: string - default: '' - - - name: signingValidationAdditionalParameters - displayName: Signing validation additional parameters - type: string - default: '' - - # Which stages should finish execution before post-build stages start - - name: validateDependsOn - type: object - default: - - build - - - name: publishDependsOn - type: object - default: - - Validate - - # Optional: Call asset publishing rather than running in a separate stage - - name: publishAssetsImmediately - type: boolean - default: false - stages: -- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - - stage: Validate - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Validate Build Assets - variables: - - template: common-variables.yml - - template: /eng/common/templates-official/variables/pool-providers.yml - jobs: - - job: - displayName: NuGet Validation - condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - - - job: - displayName: Signing Validation - condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - itemPattern: | - ** - !**/Microsoft.SourceBuild.Intermediate.*.nupkg - - # This is necessary whenever we want to publish/restore to an AzDO private feed - # Since sdk-task.ps1 tries to restore packages we need to do this authentication here - # otherwise it'll complain about accessing a private feed. - - task: NuGetAuthenticate@1 - displayName: 'Authenticate to AzDO Feeds' - - # Signing validation will optionally work with the buildmanifest file which is downloaded from - # Azure DevOps above. - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task SigningValidation -restore -msbuildEngine vs - /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' - /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' - ${{ parameters.signingValidationAdditionalParameters }} - - - template: ../steps/publish-logs.yml - parameters: - StageLabel: 'Validation' - JobLabel: 'Signing' - BinlogToolVersion: $(BinlogToolVersion) - - - job: - displayName: SourceLink Validation - condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: BlobArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) - -GHCommit $(Build.SourceVersion) - -SourcelinkCliVersion $(SourceLinkCLIVersion) - continueOnError: true - -- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: - - stage: publish_using_darc - ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - dependsOn: ${{ parameters.publishDependsOn }} - ${{ else }}: - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Publish using Darc - variables: - - template: common-variables.yml - - template: /eng/common/templates-official/variables/pool-providers.yml - jobs: - - job: - displayName: Publish Using Darc - timeoutInMinutes: 120 - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: NetCore1ESPool-Publishing-Internal - image: windows.vs2019.amd64 - os: windows - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: NuGetAuthenticate@1 +- template: /eng/common/core-templates/post-build/post-build.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: true - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml index 0c87f149a4ad77..024397d8786452 100644 --- a/eng/common/templates-official/post-build/setup-maestro-vars.yml +++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml @@ -1,70 +1,8 @@ -parameters: - BARBuildId: '' - PromoteToChannelIds: '' - steps: - - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Release Configs - inputs: - buildType: current - artifactName: ReleaseConfigs - checkDownloadedFiles: true - - - task: PowerShell@2 - name: setReleaseVars - displayName: Set Release Configs Vars - inputs: - targetType: inline - pwsh: true - script: | - try { - if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { - $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt - - $BarId = $Content | Select -Index 0 - $Channels = $Content | Select -Index 1 - $IsStableBuild = $Content | Select -Index 2 - - $AzureDevOpsProject = $Env:System_TeamProject - $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId - $AzureDevOpsBuildId = $Env:Build_BuildId - } - else { - $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" - - $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' - $apiHeaders.Add('Accept', 'application/json') - $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") - - $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - - $BarId = $Env:BARBuildId - $Channels = $Env:PromoteToMaestroChannels -split "," - $Channels = $Channels -join "][" - $Channels = "[$Channels]" - - $IsStableBuild = $buildInfo.stable - $AzureDevOpsProject = $buildInfo.azureDevOpsProject - $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId - $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId - } - - Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" - Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" - Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" +- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: true - Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" - Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" - Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" - } - catch { - Write-Host $_ - Write-Host $_.Exception - Write-Host $_.ScriptStackTrace - exit 1 - } - env: - MAESTRO_API_TOKEN: $(MaestroApiAccessToken) - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml index f67a210d62f3e5..543dea8c6969a6 100644 --- a/eng/common/templates-official/steps/add-build-to-channel.yml +++ b/eng/common/templates-official/steps/add-build-to-channel.yml @@ -1,13 +1,7 @@ -parameters: - ChannelId: 0 - steps: -- task: PowerShell@2 - displayName: Add Build to Channel - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 - arguments: -BuildId $(BARBuildId) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) +- template: /eng/common/core-templates/steps/add-build-to-channel.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml index 0ecec47b0c9177..30bb3985ca2bf4 100644 --- a/eng/common/templates-official/steps/component-governance.yml +++ b/eng/common/templates-official/steps/component-governance.yml @@ -1,13 +1,7 @@ -parameters: - disableComponentGovernance: false - componentGovernanceIgnoreDirectories: '' - steps: -- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" - displayName: Set skipComponentGovernanceDetection variable -- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - - task: ComponentGovernanceComponentDetection@0 - continueOnError: true - inputs: - ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file +- template: /eng/common/core-templates/steps/component-governance.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/generate-sbom.yml b/eng/common/templates-official/steps/generate-sbom.yml index 488b560e8ba4eb..9a89a4706d94e4 100644 --- a/eng/common/templates-official/steps/generate-sbom.yml +++ b/eng/common/templates-official/steps/generate-sbom.yml @@ -1,48 +1,7 @@ -# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. -# PackageName - The name of the package this SBOM represents. -# PackageVersion - The version of the package this SBOM represents. -# ManifestDirPath - The path of the directory where the generated manifest files will be placed -# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. - -parameters: - PackageVersion: 7.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - PackageName: '.NET' - ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom - IgnoreDirectories: '' - sbomContinueOnError: true - steps: -- task: PowerShell@2 - displayName: Prep for SBOM generation in (Non-linux) - condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) - inputs: - filePath: ./eng/common/generate-sbom-prep.ps1 - arguments: ${{parameters.manifestDirPath}} - -# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 -- script: | - chmod +x ./eng/common/generate-sbom-prep.sh - ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} - displayName: Prep for SBOM generation in (Linux) - condition: eq(variables['Agent.Os'], 'Linux') - continueOnError: ${{ parameters.sbomContinueOnError }} - -- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: 'Generate SBOM manifest' - continueOnError: ${{ parameters.sbomContinueOnError }} - inputs: - PackageName: ${{ parameters.packageName }} - BuildDropPath: ${{ parameters.buildDropPath }} - PackageVersion: ${{ parameters.packageVersion }} - ManifestDirPath: ${{ parameters.manifestDirPath }} - ${{ if ne(parameters.IgnoreDirectories, '') }}: - AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' - -- task: 1ES.PublishPipelineArtifact@1 - displayName: Publish SBOM manifest - continueOnError: ${{parameters.sbomContinueOnError}} - inputs: - targetPath: '${{parameters.manifestDirPath}}' - artifactName: $(ARTIFACT_NAME) +- template: /eng/common/core-templates/steps/generate-sbom.yml + parameters: + is1ESPipeline: true + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/publish-build-artifacts.yml b/eng/common/templates-official/steps/publish-build-artifacts.yml new file mode 100644 index 00000000000000..100a3fc98493cd --- /dev/null +++ b/eng/common/templates-official/steps/publish-build-artifacts.yml @@ -0,0 +1,41 @@ +parameters: +- name: displayName + type: string + default: 'Publish to Build Artifact' + +- name: condition + type: string + default: succeeded() + +- name: artifactName + type: string + +- name: pathToPublish + type: string + +- name: continueOnError + type: boolean + default: false + +- name: publishLocation + type: string + default: 'Container' + +- name: is1ESPipeline + type: boolean + default: true + +steps: +- ${{ if ne(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error +- task: 1ES.PublishBuildArtifacts@1 + displayName: ${{ parameters.displayName }} + condition: ${{ parameters.condition }} + ${{ if parameters.continueOnError }}: + continueOnError: ${{ parameters.continueOnError }} + inputs: + PublishLocation: ${{ parameters.publishLocation }} + PathtoPublish: ${{ parameters.pathToPublish }} + ${{ if parameters.artifactName }}: + ArtifactName: ${{ parameters.artifactName }} + diff --git a/eng/common/templates-official/steps/publish-logs.yml b/eng/common/templates-official/steps/publish-logs.yml index 84b2f559c56e40..579fd531e94c38 100644 --- a/eng/common/templates-official/steps/publish-logs.yml +++ b/eng/common/templates-official/steps/publish-logs.yml @@ -1,49 +1,7 @@ -parameters: - StageLabel: '' - JobLabel: '' - CustomSensitiveDataList: '' - # A default - in case value from eng/common/templates-official/post-build/common-variables.yml is not passed - BinlogToolVersion: '1.0.11' - steps: -- task: Powershell@2 - displayName: Prepare Binlogs to Upload - inputs: - targetType: inline - script: | - New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - continueOnError: true - condition: always() - -- task: PowerShell@2 - displayName: Redact Logs - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/redact-logs.ps1 - # For now this needs to have explicit list of all sensitive data. Taken from eng/publishing/v3/publish.yml - # Sensitive data can as well be added to $(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' - # If the file exists - sensitive data for redaction will be sourced from it - # (single entry per line, lines starting with '# ' are considered comments and skipped) - arguments: -InputPath '$(Build.SourcesDirectory)/PostBuildLogs' - -BinlogToolVersion ${{parameters.BinlogToolVersion}} - -TokensFilePath '$(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' - '$(publishing-dnceng-devdiv-code-r-build-re)' - '$(MaestroAccessToken)' - '$(dn-bot-all-orgs-artifact-feeds-rw)' - '$(akams-client-id)' - '$(akams-client-secret)' - '$(microsoft-symbol-server-pat)' - '$(symweb-symbol-server-pat)' - '$(dn-bot-all-orgs-build-rw-code-rw)' - ${{parameters.CustomSensitiveDataList}} - continueOnError: true - condition: always() - -- task: 1ES.PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' - PublishLocation: Container - ArtifactName: PostBuildLogs - continueOnError: true - condition: always() +- template: /eng/common/core-templates/steps/publish-logs.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml new file mode 100644 index 00000000000000..d71eb0c7439862 --- /dev/null +++ b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml @@ -0,0 +1,26 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: true + +- name: args + type: object + default: {} + +steps: +- ${{ if ne(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error +- task: 1ES.PublishPipelineArtifact@1 + displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }} + ${{ if parameters.args.condition }}: + condition: ${{ parameters.args.condition }} + ${{ else }}: + condition: succeeded() + ${{ if parameters.args.continueOnError }}: + continueOnError: ${{ parameters.args.continueOnError }} + inputs: + targetPath: ${{ parameters.args.targetPath }} + ${{ if parameters.args.artifactName }}: + artifactName: ${{ parameters.args.artifactName }} + ${{ if parameters.args.properties }}: + properties: ${{ parameters.args.properties }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/retain-build.yml b/eng/common/templates-official/steps/retain-build.yml index 83d97a26a01ff9..5594551508a3cf 100644 --- a/eng/common/templates-official/steps/retain-build.yml +++ b/eng/common/templates-official/steps/retain-build.yml @@ -1,28 +1,7 @@ -parameters: - # Optional azure devops PAT with build execute permissions for the build's organization, - # only needed if the build that should be retained ran on a different organization than - # the pipeline where this template is executing from - Token: '' - # Optional BuildId to retain, defaults to the current running build - BuildId: '' - # Azure devops Organization URI for the build in the https://dev.azure.com/ format. - # Defaults to the organization the current pipeline is running on - AzdoOrgUri: '$(System.CollectionUri)' - # Azure devops project for the build. Defaults to the project the current pipeline is running on - AzdoProject: '$(System.TeamProject)' - steps: - - task: powershell@2 - inputs: - targetType: 'filePath' - filePath: eng/common/retain-build.ps1 - pwsh: true - arguments: > - -AzdoOrgUri: ${{parameters.AzdoOrgUri}} - -AzdoProject ${{parameters.AzdoProject}} - -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} - -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} - displayName: Enable permanent build retention - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - BUILD_ID: $(Build.BuildId) \ No newline at end of file +- template: /eng/common/core-templates/steps/retain-build.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/send-to-helix.yml b/eng/common/templates-official/steps/send-to-helix.yml index 68fa739c4ab215..6500f21bf845ce 100644 --- a/eng/common/templates-official/steps/send-to-helix.yml +++ b/eng/common/templates-official/steps/send-to-helix.yml @@ -1,93 +1,7 @@ -# Please remember to update the documentation if you make changes to these parameters! -parameters: - HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ - HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' - HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number - HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues - HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group - HelixProjectPath: 'eng/common/helixpublish.proj' # optional -- path to the project file to build relative to BUILD_SOURCESDIRECTORY - HelixProjectArguments: '' # optional -- arguments passed to the build command - HelixConfiguration: '' # optional -- additional property attached to a job - HelixPreCommands: '' # optional -- commands to run before Helix work item execution - HelixPostCommands: '' # optional -- commands to run after Helix work item execution - WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects - WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects - WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects - CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload - XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true - XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects - XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects - XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner - XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects - IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion - DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." - IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set - HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) - Creator: '' # optional -- if the build is external, use this to specify who is sending the job - DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO - condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() - continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false - steps: - - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' - displayName: ${{ parameters.DisplayNamePrefix }} (Windows) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Unix) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} +- template: /eng/common/core-templates/steps/send-to-helix.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml index 53ed57b6d48abc..8f92c49e7b06fc 100644 --- a/eng/common/templates-official/steps/source-build.yml +++ b/eng/common/templates-official/steps/source-build.yml @@ -1,131 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. - - # This is a 'steps' template, and is intended for advanced scenarios where the existing build - # infra has a careful build methodology that must be followed. For example, a repo - # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline - # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to - # GitHub. Using this steps template leaves room for that infra to be included. - - # Defines the platform on which to run the steps. See 'eng/common/templates-official/job/source-build.yml' - # for details. The entire object is described in the 'job' template for simplicity, even though - # the usage of the properties on this object is split between the 'job' and 'steps' templates. - platform: {} - steps: -# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) -- script: | - set -x - df -h - - # If building on the internal project, the artifact feeds variable may be available (usually only if needed) - # In that case, call the feed setup script to add internal feeds corresponding to public ones. - # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. - # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those - # changes. - internalRestoreArgs= - if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then - # Temporarily work around https://github.com/dotnet/arcade/issues/7709 - chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh - $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) - internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' - - # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. - # This only works if there is a username/email configured, which won't be the case in most CI runs. - git config --get user.email - if [ $? -ne 0 ]; then - git config user.email dn-bot@microsoft.com - git config user.name dn-bot - fi - fi - - # If building on the internal project, the internal storage variable may be available (usually only if needed) - # In that case, add variables to allow the download of internal runtimes if the specified versions are not found - # in the default public locations. - internalRuntimeDownloadArgs= - if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then - internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' - fi - - buildConfig=Release - # Check if AzDO substitutes in a build config from a variable, and use it if so. - if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then - buildConfig='$(_BuildConfig)' - fi - - officialBuildArgs= - if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then - officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' - fi - - targetRidArgs= - if [ '${{ parameters.platform.targetRID }}' != '' ]; then - targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' - fi - - runtimeOsArgs= - if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then - runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}' - fi - - baseOsArgs= - if [ '${{ parameters.platform.baseOS }}' != '' ]; then - baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}' - fi - - publishArgs= - if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then - publishArgs='--publish' - fi - - assetManifestFileName=SourceBuild_RidSpecific.xml - if [ '${{ parameters.platform.name }}' != '' ]; then - assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml - fi - - ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ - --configuration $buildConfig \ - --restore --build --pack $publishArgs -bl \ - $officialBuildArgs \ - $internalRuntimeDownloadArgs \ - $internalRestoreArgs \ - $targetRidArgs \ - $runtimeOsArgs \ - $baseOsArgs \ - /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ - /p:ArcadeBuildFromSource=true \ - /p:DotNetBuildSourceOnly=true \ - /p:DotNetBuildRepo=true \ - /p:AssetManifestFileName=$assetManifestFileName - displayName: Build - -# Upload build logs for diagnosis. -- task: CopyFiles@2 - displayName: Prepare BuildLogs staging directory - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - **/*.log - **/*.binlog - artifacts/sb/prebuilt-report/** - TargetFolder: '$(Build.StagingDirectory)/BuildLogs' - CleanTargetFolder: true - continueOnError: true - condition: succeededOrFailed() - -- task: 1ES.PublishPipelineArtifact@1 - displayName: Publish BuildLogs - inputs: - targetPath: '$(Build.StagingDirectory)/BuildLogs' - artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) - continueOnError: true - condition: succeededOrFailed() +- template: /eng/common/core-templates/steps/source-build.yml + parameters: + is1ESPipeline: true -# Manually inject component detection so that we can ignore the source build upstream cache, which contains -# a nupkg cache of input packages (a local feed). -# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' -# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets -- task: ComponentGovernanceComponentDetection@0 - displayName: Component Detection (Exclude upstream cache) - inputs: - ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml deleted file mode 100644 index 7870f93bc17652..00000000000000 --- a/eng/common/templates/job/execute-sdl.yml +++ /dev/null @@ -1,139 +0,0 @@ -parameters: - enable: 'false' # Whether the SDL validation job should execute or not - overrideParameters: '' # Optional: to override values for parameters. - additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth - # diagnosis of problems with specific tool configurations. - publishGuardianDirectoryToPipeline: false - # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL - # parameters rather than relying on YAML. It may be better to use a local script, because you can - # reproduce results locally without piecing together a command based on the YAML. - executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' - # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named - # 'continueOnError', the parameter value is not correctly picked up. - # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter - sdlContinueOnError: false # optional: determines whether to continue the build if the step errors; - # optional: determines if build artifacts should be downloaded. - downloadArtifacts: true - # optional: determines if this job should search the directory of downloaded artifacts for - # 'tar.gz' and 'zip' archive files and extract them before running SDL validation tasks. - extractArchiveArtifacts: false - dependsOn: '' # Optional: dependencies of the job - artifactNames: '' # Optional: patterns supplied to DownloadBuildArtifacts - # Usage: - # artifactNames: - # - 'BlobArtifacts' - # - 'Artifacts_Windows_NT_Release' - # Optional: download a list of pipeline artifacts. 'downloadArtifacts' controls build artifacts, - # not pipeline artifacts, so doesn't affect the use of this parameter. - pipelineArtifactNames: [] - -jobs: -- job: Run_SDL - dependsOn: ${{ parameters.dependsOn }} - displayName: Run SDL tool - condition: and(succeededOrFailed(), eq( ${{ parameters.enable }}, 'true')) - variables: - - group: DotNet-VSTS-Bot - - name: AzDOProjectName - value: ${{ parameters.AzDOProjectName }} - - name: AzDOPipelineId - value: ${{ parameters.AzDOPipelineId }} - - name: AzDOBuildId - value: ${{ parameters.AzDOBuildId }} - - template: /eng/common/templates/variables/sdl-variables.yml - - name: GuardianVersion - value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} - - template: /eng/common/templates/variables/pool-providers.yml - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - checkout: self - clean: true - - # If the template caller didn't provide an AzDO parameter, set them all up as Maestro vars. - - ${{ if not(and(parameters.AzDOProjectName, parameters.AzDOPipelineId, parameters.AzDOBuildId)) }}: - - template: /eng/common/templates/post-build/setup-maestro-vars.yml - - - ${{ if ne(parameters.downloadArtifacts, 'false')}}: - - ${{ if ne(parameters.artifactNames, '') }}: - - ${{ each artifactName in parameters.artifactNames }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Build Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: ${{ artifactName }} - downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - checkDownloadedFiles: true - - ${{ if eq(parameters.artifactNames, '') }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Build Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - downloadType: specific files - itemPattern: "**" - downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - checkDownloadedFiles: true - - - ${{ each artifactName in parameters.pipelineArtifactNames }}: - - task: DownloadPipelineArtifact@2 - displayName: Download Pipeline Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: ${{ artifactName }} - downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - checkDownloadedFiles: true - - - powershell: eng/common/sdl/trim-assets-version.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts - displayName: Trim the version from the NuGet packages - continueOnError: ${{ parameters.sdlContinueOnError }} - - - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts - -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts - displayName: Extract Blob Artifacts - continueOnError: ${{ parameters.sdlContinueOnError }} - - - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts - -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts - displayName: Extract Package Artifacts - continueOnError: ${{ parameters.sdlContinueOnError }} - - - ${{ if ne(parameters.extractArchiveArtifacts, 'false') }}: - - powershell: eng/common/sdl/extract-artifact-archives.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts - -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts - displayName: Extract Archive Artifacts - continueOnError: ${{ parameters.sdlContinueOnError }} - - - template: /eng/common/templates/steps/execute-sdl.yml - parameters: - overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} - executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} - overrideParameters: ${{ parameters.overrideParameters }} - additionalParameters: ${{ parameters.additionalParameters }} - publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} - sdlContinueOnError: ${{ parameters.sdlContinueOnError }} diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index a3277bf15c51ff..1cf9a6d48127b6 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -1,259 +1,61 @@ -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - -parameters: -# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - cancelTimeoutInMinutes: '' - condition: '' - container: '' - continueOnError: false - dependsOn: '' - displayName: '' - pool: '' - steps: [] - strategy: '' - timeoutInMinutes: '' - variables: [] - workspace: '' - templateContext: '' - -# Job base template specific parameters - # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md - artifacts: '' - enableMicrobuild: false +parameters: enablePublishBuildArtifacts: false - enablePublishBuildAssets: false - enablePublishTestResults: false - enablePublishUsingPipelines: false - enableBuildRetry: false - disableComponentGovernance: '' - componentGovernanceIgnoreDirectories: '' - mergeTestResults: false - testRunTitle: '' - testResultsFormat: '' - name: '' - preSteps: [] - runAsPublic: false -# Sbom related params - enableSbom: true - PackageVersion: 7.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' jobs: -- job: ${{ parameters.name }} - - ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: - cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} - - ${{ if ne(parameters.condition, '') }}: - condition: ${{ parameters.condition }} - - ${{ if ne(parameters.container, '') }}: - container: ${{ parameters.container }} - - ${{ if ne(parameters.continueOnError, '') }}: - continueOnError: ${{ parameters.continueOnError }} - - ${{ if ne(parameters.dependsOn, '') }}: - dependsOn: ${{ parameters.dependsOn }} - - ${{ if ne(parameters.displayName, '') }}: - displayName: ${{ parameters.displayName }} - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - - ${{ if ne(parameters.strategy, '') }}: - strategy: ${{ parameters.strategy }} - - ${{ if ne(parameters.timeoutInMinutes, '') }}: - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - - ${{ if ne(parameters.templateContext, '') }}: - templateContext: ${{ parameters.templateContext }} - - variables: - - ${{ if ne(parameters.enableTelemetry, 'false') }}: - - name: DOTNET_CLI_TELEMETRY_PROFILE - value: '$(Build.Repository.Uri)' - - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: - - name: EnableRichCodeNavigation - value: 'true' - # Retry signature validation up to three times, waiting 2 seconds between attempts. - # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures - - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY - value: 3,2000 - - ${{ each variable in parameters.variables }}: - # handle name-value variable syntax - # example: - # - name: [key] - # value: [value] - - ${{ if ne(variable.name, '') }}: - - name: ${{ variable.name }} - value: ${{ variable.value }} - - # handle variable groups - - ${{ if ne(variable.group, '') }}: - - group: ${{ variable.group }} - - # handle template variable syntax - # example: - # - template: path/to/template.yml - # parameters: - # [key]: [value] - - ${{ if ne(variable.template, '') }}: - - template: ${{ variable.template }} - ${{ if ne(variable.parameters, '') }}: - parameters: ${{ variable.parameters }} - - # handle key-value variable syntax. - # example: - # - [key]: [value] - - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: - - ${{ each pair in variable }}: - - name: ${{ pair.key }} - value: ${{ pair.value }} - - # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds - - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: DotNet-HelixApi-Access - - ${{ if ne(parameters.workspace, '') }}: - workspace: ${{ parameters.workspace }} - - steps: - - ${{ if ne(parameters.preSteps, '') }}: - - ${{ each preStep in parameters.preSteps }}: - - ${{ preStep }} - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - task: MicroBuildSigningPlugin@3 - displayName: Install MicroBuild plugin - inputs: - signType: $(_SignType) - zipSources: false - feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - env: - TeamName: $(_TeamName) - continueOnError: ${{ parameters.continueOnError }} - condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - - - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: - - task: NuGetAuthenticate@1 - - - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: - - task: DownloadPipelineArtifact@2 - inputs: - buildType: current - artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} - targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} - itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} - - - ${{ each step in parameters.steps }}: - - ${{ step }} - - - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: - - task: RichCodeNavIndexer@0 - displayName: RichCodeNav Upload - inputs: - languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} - environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'internal') }} - richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin - uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} - continueOnError: true - - - template: /eng/common/templates/steps/component-governance.yml - parameters: - ${{ if eq(parameters.disableComponentGovernance, '') }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: - disableComponentGovernance: false - ${{ else }}: - disableComponentGovernance: true - ${{ else }}: - disableComponentGovernance: ${{ parameters.disableComponentGovernance }} - componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: MicroBuildCleanup@1 - displayName: Execute Microbuild cleanup tasks - condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - env: - TeamName: $(_TeamName) - - - ${{ if ne(parameters.artifacts.publish, '') }}: - - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - - task: CopyFiles@2 - displayName: Gather binaries for publish to artifacts - inputs: - SourceFolder: 'artifacts/bin' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' - - task: CopyFiles@2 - displayName: Gather packages for publish to artifacts - inputs: - SourceFolder: 'artifacts/packages' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' - - task: PublishBuildArtifacts@1 - displayName: Publish pipeline artifacts - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} - continueOnError: true - condition: always() - - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - publish: artifacts/log - artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} - displayName: Publish logs - continueOnError: true - condition: always() - - - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: - - task: PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} - continueOnError: true - condition: always() - - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: - - task: PublishTestResults@2 - displayName: Publish XUnit Test Results - inputs: - testResultsFormat: 'xUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: - - task: PublishTestResults@2 - displayName: Publish TRX Test Results - inputs: - testResultsFormat: 'VSTest' - testResultsFiles: '*.trx' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: - - template: /eng/common/templates/steps/generate-sbom.yml - parameters: - PackageVersion: ${{ parameters.packageVersion}} - BuildDropPath: ${{ parameters.buildDropPath }} - IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if eq(parameters.enableBuildRetry, 'true') }}: - - publish: $(Build.SourcesDirectory)\eng\common\BuildConfiguration - artifact: BuildConfiguration - displayName: Publish build retry configuration - continueOnError: true +- template: /eng/common/core-templates/job/job.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ if and(ne(parameter.key, 'steps'), ne(parameter.key, 'is1ESPipeline')) }}: + ${{ parameter.key }}: ${{ parameter.value }} + + steps: + - ${{ each step in parameters.steps }}: + - ${{ step }} + + artifactPublishSteps: + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: false + args: + displayName: Publish pipeline artifacts + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + publishLocation: Container + artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: false + args: + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' + continueOnError: true + condition: always() + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: false + args: + displayName: Publish Logs + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + publishLocation: Container + artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: false + args: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml index 60ab00c4de3acd..ff829dc4c700c6 100644 --- a/eng/common/templates/job/onelocbuild.yml +++ b/eng/common/templates/job/onelocbuild.yml @@ -1,109 +1,7 @@ -parameters: - # Optional: dependencies of the job - dependsOn: '' - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: '' - - CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex - GithubPat: $(BotAccount-dotnet-bot-repo-PAT) - - SourcesDirectory: $(Build.SourcesDirectory) - CreatePr: true - AutoCompletePr: false - ReusePr: true - UseLfLineEndings: true - UseCheckedInLocProjectJson: false - SkipLocProjectJsonGeneration: false - LanguageSet: VS_Main_Languages - LclSource: lclFilesInRepo - LclPackageId: '' - RepoType: gitHub - GitHubOrg: dotnet - MirrorRepo: '' - MirrorBranch: main - condition: '' - JobNameSuffix: '' - jobs: -- job: OneLocBuild${{ parameters.JobNameSuffix }} - - dependsOn: ${{ parameters.dependsOn }} - - displayName: OneLocBuild${{ parameters.JobNameSuffix }} - - variables: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - - name: _GenerateLocProjectArguments - value: -SourcesDirectory ${{ parameters.SourcesDirectory }} - -LanguageSet "${{ parameters.LanguageSet }}" - -CreateNeutralXlfs - - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: - - name: _GenerateLocProjectArguments - value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson - - template: /eng/common/templates/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - - steps: - - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: - - task: Powershell@2 - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 - arguments: $(_GenerateLocProjectArguments) - displayName: Generate LocProject.json - condition: ${{ parameters.condition }} - - - task: OneLocBuild@2 - displayName: OneLocBuild - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - inputs: - locProj: eng/Localize/LocProject.json - outDir: $(Build.ArtifactStagingDirectory) - lclSource: ${{ parameters.LclSource }} - lclPackageId: ${{ parameters.LclPackageId }} - isCreatePrSelected: ${{ parameters.CreatePr }} - isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} - ${{ if eq(parameters.CreatePr, true) }}: - isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - isShouldReusePrSelected: ${{ parameters.ReusePr }} - packageSourceAuth: patAuth - patVariable: ${{ parameters.CeapexPat }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - repoType: ${{ parameters.RepoType }} - gitHubPatVariable: "${{ parameters.GithubPat }}" - ${{ if ne(parameters.MirrorRepo, '') }}: - isMirrorRepoSelected: true - gitHubOrganization: ${{ parameters.GitHubOrg }} - mirrorRepo: ${{ parameters.MirrorRepo }} - mirrorBranch: ${{ parameters.MirrorBranch }} - condition: ${{ parameters.condition }} - - - task: PublishBuildArtifacts@1 - displayName: Publish Localization Files - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} +- template: /eng/common/core-templates/job/onelocbuild.yml + parameters: + is1ESPipeline: false - - task: PublishBuildArtifacts@1 - displayName: Publish LocProject.json - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} \ No newline at end of file + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index bb42240f865b56..ab2edec2adb541 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -1,155 +1,7 @@ -parameters: - configuration: 'Debug' - - # Optional: condition for the job to run - condition: '' - - # Optional: 'true' if future jobs should run even if this job fails - continueOnError: false - - # Optional: dependencies of the job - dependsOn: '' - - # Optional: Include PublishBuildArtifacts task - enablePublishBuildArtifacts: false - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: {} - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. - runAsPublic: false - - # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing - publishUsingPipelines: false - - # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing - publishAssetsImmediately: false - - artifactsPublishingAdditionalParameters: '' - - signingValidationAdditionalParameters: '' - jobs: -- job: Asset_Registry_Publish - - dependsOn: ${{ parameters.dependsOn }} - timeoutInMinutes: 150 - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - displayName: Publish Assets - ${{ else }}: - displayName: Publish to Build Asset Registry - - variables: - - template: /eng/common/templates/variables/pool-providers.yml - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: Publish-Build-Assets - - group: AzureDevOps-Artifact-Feeds-Pats - - name: runCodesignValidationInjection - value: false - # unconditional - needed for logs publishing (redactor tool version) - - template: /eng/common/templates/post-build/common-variables.yml - - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: NetCore1ESPool-Publishing-Internal - demands: ImageOverride -equals windows.vs2019.amd64 - - steps: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - checkout: self - fetchDepth: 3 - clean: true - - - task: DownloadBuildArtifacts@0 - displayName: Download artifact - inputs: - artifactName: AssetManifests - downloadPath: '$(Build.StagingDirectory)/Download' - checkDownloadedFiles: true - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: NuGetAuthenticate@1 - - - task: PowerShell@2 - displayName: Publish Build Assets - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet - /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' - /p:BuildAssetRegistryToken=$(MaestroAccessToken) - /p:MaestroApiEndpoint=https://maestro.dot.net - /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} - /p:OfficialBuildId=$(Build.BuildNumber) - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: powershell@2 - displayName: Create ReleaseConfigs Artifact - inputs: - targetType: inline - script: | - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) - - - task: PublishBuildArtifacts@1 - displayName: Publish ReleaseConfigs Artifact - inputs: - PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - task: powershell@2 - displayName: Check if SymbolPublishingExclusionsFile.txt exists - inputs: - targetType: inline - script: | - $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" - if(Test-Path -Path $symbolExclusionfile) - { - Write-Host "SymbolExclusionFile exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" - } - else{ - Write-Host "Symbols Exclusion file does not exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" - } - - - task: PublishBuildArtifacts@1 - displayName: Publish SymbolPublishingExclusionsFile Artifact - condition: eq(variables['SymbolExclusionFile'], 'true') - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - - template: /eng/common/templates/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion 3 - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' +- template: /eng/common/core-templates/job/publish-build-assets.yml + parameters: + is1ESPipeline: false - - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - - template: /eng/common/templates/steps/publish-logs.yml - parameters: - JobLabel: 'Publish_Artifacts_Logs' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/source-build.yml b/eng/common/templates/job/source-build.yml index d7ed209494c7be..e44d47b1d760c4 100644 --- a/eng/common/templates/job/source-build.yml +++ b/eng/common/templates/job/source-build.yml @@ -1,66 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. The template produces a server job with a - # default ID 'Source_Build_Complete' to put in a dependency list if necessary. - - # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. - jobNamePrefix: 'Source_Build' - - # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for - # managed-only repositories. This is an object with these properties: - # - # name: '' - # The name of the job. This is included in the job ID. - # targetRID: '' - # The name of the target RID to use, instead of the one auto-detected by Arcade. - # nonPortable: false - # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than - # linux-x64), and compiling against distro-provided packages rather than portable ones. - # skipPublishValidation: false - # Disables publishing validation. By default, a check is performed to ensure no packages are - # published by source-build. - # container: '' - # A container to use. Runs in docker. - # pool: {} - # A pool to use. Runs directly on an agent. - # buildScript: '' - # Specifies the build script to invoke to perform the build in the repo. The default - # './build.sh' should work for typical Arcade repositories, but this is customizable for - # difficult situations. - # jobProperties: {} - # A list of job properties to inject at the top level, for potential extensibility beyond - # container and pool. - platform: {} - jobs: -- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} - displayName: Source-Build (${{ parameters.platform.name }}) - - ${{ each property in parameters.platform.jobProperties }}: - ${{ property.key }}: ${{ property.value }} - - ${{ if ne(parameters.platform.container, '') }}: - container: ${{ parameters.platform.container }} - - ${{ if eq(parameters.platform.pool, '') }}: - # The default VM host AzDO pool. This should be capable of running Docker containers: almost all - # source-build builds run in Docker, including the default managed platform. - # /eng/common/templates/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] - demands: ImageOverride -equals Build.Ubuntu.2204.Amd64.Open - - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - demands: ImageOverride -equals Build.Ubuntu.2204.Amd64 - - ${{ if ne(parameters.platform.pool, '') }}: - pool: ${{ parameters.platform.pool }} - - workspace: - clean: all +- template: /eng/common/core-templates/job/source-build.yml + parameters: + is1ESPipeline: false - steps: - - template: /eng/common/templates/steps/source-build.yml - parameters: - platform: ${{ parameters.platform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/source-index-stage1.yml b/eng/common/templates/job/source-index-stage1.yml index b5a3e5c4a6c847..89f3291593cb78 100644 --- a/eng/common/templates/job/source-index-stage1.yml +++ b/eng/common/templates/job/source-index-stage1.yml @@ -1,67 +1,7 @@ -parameters: - runAsPublic: false - sourceIndexPackageVersion: 1.0.1-20240129.2 - sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json - sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" - preSteps: [] - binlogPath: artifacts/log/Debug/Build.binlog - condition: '' - dependsOn: '' - pool: '' - jobs: -- job: SourceIndexStage1 - dependsOn: ${{ parameters.dependsOn }} - condition: ${{ parameters.condition }} - variables: - - name: SourceIndexPackageVersion - value: ${{ parameters.sourceIndexPackageVersion }} - - name: SourceIndexPackageSource - value: ${{ parameters.sourceIndexPackageSource }} - - name: BinlogPath - value: ${{ parameters.binlogPath }} - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: source-dot-net stage1 variables - - template: /eng/common/templates/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals windows.vs2022.amd64.open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2022.amd64 - - steps: - - ${{ each preStep in parameters.preSteps }}: - - ${{ preStep }} - - - task: UseDotNet@2 - displayName: Use .NET 8 SDK - inputs: - packageType: sdk - version: 8.0.x - installationPath: $(Agent.TempDirectory)/dotnet - workingDirectory: $(Agent.TempDirectory) - - - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - displayName: Download Tools - # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. - workingDirectory: $(Agent.TempDirectory) - - - script: ${{ parameters.sourceIndexBuildCommand }} - displayName: Build Repository - - - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output - displayName: Process Binlog into indexable sln +- template: /eng/common/core-templates/job/source-index-stage1.yml + parameters: + is1ESPipeline: false - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) - displayName: Upload stage1 artifacts to source index - env: - BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/jobs/codeql-build.yml b/eng/common/templates/jobs/codeql-build.yml index f7dc5ea4aaa63c..517f24d6a52ce7 100644 --- a/eng/common/templates/jobs/codeql-build.yml +++ b/eng/common/templates/jobs/codeql-build.yml @@ -1,31 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - jobs: -- template: /eng/common/templates/jobs/jobs.yml +- template: /eng/common/core-templates/jobs/codeql-build.yml parameters: - enableMicrobuild: false - enablePublishBuildArtifacts: false - enablePublishTestResults: false - enablePublishBuildAssets: false - enablePublishUsingPipelines: false - enableTelemetry: true + is1ESPipeline: false - variables: - - group: Publish-Build-Assets - # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in - # sync with the packages.config file. - - name: DefaultGuardianVersion - value: 0.109.0 - - name: GuardianPackagesConfigFile - value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config - - name: GuardianVersion - value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} - - jobs: ${{ parameters.jobs }} - + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml index 289bb2396ce83e..388e9037b3e601 100644 --- a/eng/common/templates/jobs/jobs.yml +++ b/eng/common/templates/jobs/jobs.yml @@ -1,97 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - - # Optional: Include PublishBuildArtifacts task - enablePublishBuildArtifacts: false - - # Optional: Enable publishing using release pipelines - enablePublishUsingPipelines: false - - # Optional: Enable running the source-build jobs to build repo from source - enableSourceBuild: false - - # Optional: Parameters for source-build template. - # See /eng/common/templates/jobs/source-build.yml for options - sourceBuildParameters: [] - - graphFileGeneration: - # Optional: Enable generating the graph files at the end of the build - enabled: false - # Optional: Include toolset dependencies in the generated graph files - includeToolset: false - - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - - # Optional: Override automatically derived dependsOn value for "publish build assets" job - publishBuildAssetsDependsOn: '' - - # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. - publishAssetsImmediately: false - - # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml) - artifactsPublishingAdditionalParameters: '' - signingValidationAdditionalParameters: '' - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. - runAsPublic: false - - enableSourceIndex: false - sourceIndexParams: {} - -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - jobs: -- ${{ each job in parameters.jobs }}: - - template: ../job/job.yml - parameters: - # pass along parameters - ${{ each parameter in parameters }}: - ${{ if ne(parameter.key, 'jobs') }}: - ${{ parameter.key }}: ${{ parameter.value }} - - # pass along job properties - ${{ each property in job }}: - ${{ if ne(property.key, 'job') }}: - ${{ property.key }}: ${{ property.value }} - - name: ${{ job.job }} - -- ${{ if eq(parameters.enableSourceBuild, true) }}: - - template: /eng/common/templates/jobs/source-build.yml - parameters: - allCompletedJobId: Source_Build_Complete - ${{ each parameter in parameters.sourceBuildParameters }}: - ${{ parameter.key }}: ${{ parameter.value }} - -- ${{ if eq(parameters.enableSourceIndex, 'true') }}: - - template: ../job/source-index-stage1.yml - parameters: - runAsPublic: ${{ parameters.runAsPublic }} - ${{ each parameter in parameters.sourceIndexParams }}: - ${{ parameter.key }}: ${{ parameter.value }} - -- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: - - template: ../job/publish-build-assets.yml - parameters: - continueOnError: ${{ parameters.continueOnError }} - dependsOn: - - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.publishBuildAssetsDependsOn }}: - - ${{ job.job }} - - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.jobs }}: - - ${{ job.job }} - - ${{ if eq(parameters.enableSourceBuild, true) }}: - - Source_Build_Complete +- template: /eng/common/core-templates/jobs/jobs.yml + parameters: + is1ESPipeline: false - runAsPublic: ${{ parameters.runAsPublic }} - publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} - publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} - enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/jobs/source-build.yml b/eng/common/templates/jobs/source-build.yml index da91481ff1d286..818d4c326dbbf1 100644 --- a/eng/common/templates/jobs/source-build.yml +++ b/eng/common/templates/jobs/source-build.yml @@ -1,46 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. A job is created for each platform, as - # well as an optional server job that completes when all platform jobs complete. - - # The name of the "join" job for all source-build platforms. If set to empty string, the job is - # not included. Existing repo pipelines can use this job depend on all source-build jobs - # completing without maintaining a separate list of every single job ID: just depend on this one - # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. - allCompletedJobId: '' - - # See /eng/common/templates/job/source-build.yml - jobNamePrefix: 'Source_Build' - - # This is the default platform provided by Arcade, intended for use by a managed-only repo. - defaultManagedPlatform: - name: 'Managed' - container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9' - - # Defines the platforms on which to run build jobs. One job is created for each platform, and the - # object in this array is sent to the job template as 'platform'. If no platforms are specified, - # one job runs on 'defaultManagedPlatform'. - platforms: [] - jobs: +- template: /eng/common/core-templates/jobs/source-build.yml + parameters: + is1ESPipeline: false -- ${{ if ne(parameters.allCompletedJobId, '') }}: - - job: ${{ parameters.allCompletedJobId }} - displayName: Source-Build Complete - pool: server - dependsOn: - - ${{ each platform in parameters.platforms }}: - - ${{ parameters.jobNamePrefix }}_${{ platform.name }} - - ${{ if eq(length(parameters.platforms), 0) }}: - - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} - -- ${{ each platform in parameters.platforms }}: - - template: /eng/common/templates/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ platform }} - -- ${{ if eq(length(parameters.platforms), 0) }}: - - template: /eng/common/templates/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ parameters.defaultManagedPlatform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index b9ede10bf099ae..7fa105875592c8 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -1,24 +1,8 @@ variables: - - group: Publish-Build-Assets +- template: /eng/common/core-templates/post-build/common-variables.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: false - # Whether the build is internal or not - - name: IsInternalBuild - value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} - - # Default Maestro++ API Endpoint and API Version - - name: MaestroApiEndPoint - value: "https://maestro.dot.net" - - name: MaestroApiAccessToken - value: $(MaestroAccessToken) - - name: MaestroApiVersion - value: "2020-02-20" - - - name: SourceLinkCLIVersion - value: 3.0.0 - - name: SymbolToolVersion - value: 1.0.1 - - name: BinlogToolVersion - value: 1.0.11 - - - name: runCodesignValidationInjection - value: false + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index ee70e2b399c5a9..53ede714bdd207 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -1,282 +1,8 @@ -parameters: - # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. - # Publishing V1 is no longer supported - # Publishing V2 is no longer supported - # Publishing V3 is the default - - name: publishingInfraVersion - displayName: Which version of publishing should be used to promote the build definition? - type: number - default: 3 - values: - - 3 - - - name: BARBuildId - displayName: BAR Build Id - type: number - default: 0 - - - name: PromoteToChannelIds - displayName: Channel to promote BARBuildId to - type: string - default: '' - - - name: enableSourceLinkValidation - displayName: Enable SourceLink validation - type: boolean - default: false - - - name: enableSigningValidation - displayName: Enable signing validation - type: boolean - default: true - - - name: enableSymbolValidation - displayName: Enable symbol validation - type: boolean - default: false - - - name: enableNugetValidation - displayName: Enable NuGet validation - type: boolean - default: true - - - name: publishInstallersAndChecksums - displayName: Publish installers and checksums - type: boolean - default: true - - - name: SDLValidationParameters - type: object - default: - enable: false - publishGdn: false - continueOnError: false - params: '' - artifactNames: '' - downloadArtifacts: true - - # These parameters let the user customize the call to sdk-task.ps1 for publishing - # symbols & general artifacts as well as for signing validation - - name: symbolPublishingAdditionalParameters - displayName: Symbol publishing additional parameters - type: string - default: '' - - - name: artifactsPublishingAdditionalParameters - displayName: Artifact publishing additional parameters - type: string - default: '' - - - name: signingValidationAdditionalParameters - displayName: Signing validation additional parameters - type: string - default: '' - - # Which stages should finish execution before post-build stages start - - name: validateDependsOn - type: object - default: - - build - - - name: publishDependsOn - type: object - default: - - Validate - - # Optional: Call asset publishing rather than running in a separate stage - - name: publishAssetsImmediately - type: boolean - default: false - stages: -- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - - stage: Validate - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Validate Build Assets - variables: - - template: common-variables.yml - - template: /eng/common/templates/variables/pool-providers.yml - jobs: - - job: - displayName: NuGet Validation - condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - - - job: - displayName: Signing Validation - condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - itemPattern: | - ** - !**/Microsoft.SourceBuild.Intermediate.*.nupkg - - # This is necessary whenever we want to publish/restore to an AzDO private feed - # Since sdk-task.ps1 tries to restore packages we need to do this authentication here - # otherwise it'll complain about accessing a private feed. - - task: NuGetAuthenticate@1 - displayName: 'Authenticate to AzDO Feeds' - - # Signing validation will optionally work with the buildmanifest file which is downloaded from - # Azure DevOps above. - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task SigningValidation -restore -msbuildEngine vs - /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' - /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' - ${{ parameters.signingValidationAdditionalParameters }} - - - template: ../steps/publish-logs.yml - parameters: - StageLabel: 'Validation' - JobLabel: 'Signing' - BinlogToolVersion: $(BinlogToolVersion) - - - job: - displayName: SourceLink Validation - condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: BlobArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) - -GHCommit $(Build.SourceVersion) - -SourcelinkCliVersion $(SourceLinkCLIVersion) - continueOnError: true - - - template: /eng/common/templates/job/execute-sdl.yml - parameters: - enable: ${{ parameters.SDLValidationParameters.enable }} - publishGuardianDirectoryToPipeline: ${{ parameters.SDLValidationParameters.publishGdn }} - additionalParameters: ${{ parameters.SDLValidationParameters.params }} - continueOnError: ${{ parameters.SDLValidationParameters.continueOnError }} - artifactNames: ${{ parameters.SDLValidationParameters.artifactNames }} - downloadArtifacts: ${{ parameters.SDLValidationParameters.downloadArtifacts }} - -- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: - - stage: publish_using_darc - ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - dependsOn: ${{ parameters.publishDependsOn }} - ${{ else }}: - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Publish using Darc - variables: - - template: common-variables.yml - - template: /eng/common/templates/variables/pool-providers.yml - jobs: - - job: - displayName: Publish Using Darc - timeoutInMinutes: 120 - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: NetCore1ESPool-Publishing-Internal - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: NuGetAuthenticate@1 +- template: /eng/common/core-templates/post-build/post-build.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: false - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml index 0c87f149a4ad77..a79fab5b441e84 100644 --- a/eng/common/templates/post-build/setup-maestro-vars.yml +++ b/eng/common/templates/post-build/setup-maestro-vars.yml @@ -1,70 +1,8 @@ -parameters: - BARBuildId: '' - PromoteToChannelIds: '' - steps: - - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Release Configs - inputs: - buildType: current - artifactName: ReleaseConfigs - checkDownloadedFiles: true - - - task: PowerShell@2 - name: setReleaseVars - displayName: Set Release Configs Vars - inputs: - targetType: inline - pwsh: true - script: | - try { - if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { - $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt - - $BarId = $Content | Select -Index 0 - $Channels = $Content | Select -Index 1 - $IsStableBuild = $Content | Select -Index 2 - - $AzureDevOpsProject = $Env:System_TeamProject - $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId - $AzureDevOpsBuildId = $Env:Build_BuildId - } - else { - $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" - - $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' - $apiHeaders.Add('Accept', 'application/json') - $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") - - $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - - $BarId = $Env:BARBuildId - $Channels = $Env:PromoteToMaestroChannels -split "," - $Channels = $Channels -join "][" - $Channels = "[$Channels]" - - $IsStableBuild = $buildInfo.stable - $AzureDevOpsProject = $buildInfo.azureDevOpsProject - $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId - $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId - } - - Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" - Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" - Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" +- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: false - Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" - Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" - Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" - } - catch { - Write-Host $_ - Write-Host $_.Exception - Write-Host $_.ScriptStackTrace - exit 1 - } - env: - MAESTRO_API_TOKEN: $(MaestroApiAccessToken) - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/steps/add-build-to-channel.yml b/eng/common/templates/steps/add-build-to-channel.yml index f67a210d62f3e5..42bbba161b9b6a 100644 --- a/eng/common/templates/steps/add-build-to-channel.yml +++ b/eng/common/templates/steps/add-build-to-channel.yml @@ -1,13 +1,7 @@ -parameters: - ChannelId: 0 - steps: -- task: PowerShell@2 - displayName: Add Build to Channel - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 - arguments: -BuildId $(BARBuildId) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) +- template: /eng/common/core-templates/steps/add-build-to-channel.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/build-reason.yml b/eng/common/templates/steps/build-reason.yml deleted file mode 100644 index eba58109b52c9d..00000000000000 --- a/eng/common/templates/steps/build-reason.yml +++ /dev/null @@ -1,12 +0,0 @@ -# build-reason.yml -# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons -# to include steps (',' separated). -parameters: - conditions: '' - steps: [] - -steps: - - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: - - ${{ parameters.steps }} - - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: - - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml index 0ecec47b0c9177..c12a5f8d21d765 100644 --- a/eng/common/templates/steps/component-governance.yml +++ b/eng/common/templates/steps/component-governance.yml @@ -1,13 +1,7 @@ -parameters: - disableComponentGovernance: false - componentGovernanceIgnoreDirectories: '' - steps: -- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" - displayName: Set skipComponentGovernanceDetection variable -- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - - task: ComponentGovernanceComponentDetection@0 - continueOnError: true - inputs: - ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file +- template: /eng/common/core-templates/steps/component-governance.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/execute-codeql.yml b/eng/common/templates/steps/execute-codeql.yml deleted file mode 100644 index 3930b1630214b3..00000000000000 --- a/eng/common/templates/steps/execute-codeql.yml +++ /dev/null @@ -1,32 +0,0 @@ -parameters: - # Language that should be analyzed. Defaults to csharp - language: csharp - # Build Commands - buildCommands: '' - overrideParameters: '' # Optional: to override values for parameters. - additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth - # diagnosis of problems with specific tool configurations. - publishGuardianDirectoryToPipeline: false - # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL - # parameters rather than relying on YAML. It may be better to use a local script, because you can - # reproduce results locally without piecing together a command based on the YAML. - executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' - # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named - # 'continueOnError', the parameter value is not correctly picked up. - # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter - # optional: determines whether to continue the build if the step errors; - sdlContinueOnError: false - -steps: -- template: /eng/common/templates/steps/execute-sdl.yml - parameters: - overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} - executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} - overrideParameters: ${{ parameters.overrideParameters }} - additionalParameters: '${{ parameters.additionalParameters }} - -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")' - publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} - sdlContinueOnError: ${{ parameters.sdlContinueOnError }} \ No newline at end of file diff --git a/eng/common/templates/steps/execute-sdl.yml b/eng/common/templates/steps/execute-sdl.yml deleted file mode 100644 index 07426fde05d824..00000000000000 --- a/eng/common/templates/steps/execute-sdl.yml +++ /dev/null @@ -1,88 +0,0 @@ -parameters: - overrideGuardianVersion: '' - executeAllSdlToolsScript: '' - overrideParameters: '' - additionalParameters: '' - publishGuardianDirectoryToPipeline: false - sdlContinueOnError: false - condition: '' - -steps: -- task: NuGetAuthenticate@1 - inputs: - nuGetServiceConnections: GuardianConnect - -- task: NuGetToolInstaller@1 - displayName: 'Install NuGet.exe' - -- ${{ if ne(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian (Overridden) - -- ${{ if eq(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian - -- ${{ if ne(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} - displayName: Execute SDL (Overridden) - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if eq(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} - -GuardianCliLocation $(GuardianCliLocation) - -NugetPackageDirectory $(Build.SourcesDirectory)\.packages - -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) - ${{ parameters.additionalParameters }} - displayName: Execute SDL - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: - # We want to publish the Guardian results and configuration for easy diagnosis. However, the - # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default - # tooling files. Some of these files are large and aren't useful during an investigation, so - # exclude them by simply deleting them before publishing. (As of writing, there is no documented - # way to selectively exclude a dir from the pipeline artifact publish task.) - - task: DeleteFiles@1 - displayName: Delete Guardian dependencies to avoid uploading - inputs: - SourceFolder: $(Agent.BuildDirectory)/.gdn - Contents: | - c - i - condition: succeededOrFailed() - - - publish: $(Agent.BuildDirectory)/.gdn - artifact: GuardianConfiguration - displayName: Publish GuardianConfiguration - condition: succeededOrFailed() - - # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration - # with the "SARIF SAST Scans Tab" Azure DevOps extension - - task: CopyFiles@2 - displayName: Copy SARIF files - inputs: - flattenFolders: true - sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ - contents: '**/*.sarif' - targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs - condition: succeededOrFailed() - - # Use PublishBuildArtifacts because the SARIF extension only checks this case - # see microsoft/sarif-azuredevops-extension#4 - - task: PublishBuildArtifacts@1 - displayName: Publish SARIF files to CodeAnalysisLogs container - inputs: - pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs - artifactName: CodeAnalysisLogs - condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates/steps/generate-sbom.yml b/eng/common/templates/steps/generate-sbom.yml index a06373f38fa5d5..26dc00a2e0f31e 100644 --- a/eng/common/templates/steps/generate-sbom.yml +++ b/eng/common/templates/steps/generate-sbom.yml @@ -1,48 +1,7 @@ -# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. -# PackageName - The name of the package this SBOM represents. -# PackageVersion - The version of the package this SBOM represents. -# ManifestDirPath - The path of the directory where the generated manifest files will be placed -# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. - -parameters: - PackageVersion: 7.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - PackageName: '.NET' - ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom - IgnoreDirectories: '' - sbomContinueOnError: true - steps: -- task: PowerShell@2 - displayName: Prep for SBOM generation in (Non-linux) - condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) - inputs: - filePath: ./eng/common/generate-sbom-prep.ps1 - arguments: ${{parameters.manifestDirPath}} - -# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 -- script: | - chmod +x ./eng/common/generate-sbom-prep.sh - ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} - displayName: Prep for SBOM generation in (Linux) - condition: eq(variables['Agent.Os'], 'Linux') - continueOnError: ${{ parameters.sbomContinueOnError }} - -- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: 'Generate SBOM manifest' - continueOnError: ${{ parameters.sbomContinueOnError }} - inputs: - PackageName: ${{ parameters.packageName }} - BuildDropPath: ${{ parameters.buildDropPath }} - PackageVersion: ${{ parameters.packageVersion }} - ManifestDirPath: ${{ parameters.manifestDirPath }} - ${{ if ne(parameters.IgnoreDirectories, '') }}: - AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' - -- task: PublishPipelineArtifact@1 - displayName: Publish SBOM manifest - continueOnError: ${{parameters.sbomContinueOnError}} - inputs: - targetPath: '${{parameters.manifestDirPath}}' - artifactName: $(ARTIFACT_NAME) +- template: /eng/common/core-templates/steps/generate-sbom.yml + parameters: + is1ESPipeline: false + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/publish-build-artifacts.yml b/eng/common/templates/steps/publish-build-artifacts.yml new file mode 100644 index 00000000000000..6428a98dfef68e --- /dev/null +++ b/eng/common/templates/steps/publish-build-artifacts.yml @@ -0,0 +1,40 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: false + +- name: displayName + type: string + default: 'Publish to Build Artifact' + +- name: condition + type: string + default: succeeded() + +- name: artifactName + type: string + +- name: pathToPublish + type: string + +- name: continueOnError + type: boolean + default: false + +- name: publishLocation + type: string + default: 'Container' + +steps: +- ${{ if eq(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates cannot be referenced from a 1ES managed template': error +- task: PublishBuildArtifacts@1 + displayName: ${{ parameters.displayName }} + condition: ${{ parameters.condition }} + ${{ if parameters.continueOnError }}: + continueOnError: ${{ parameters.continueOnError }} + inputs: + PublishLocation: ${{ parameters.publishLocation }} + PathtoPublish: ${{ parameters.pathToPublish }} + ${{ if parameters.artifactName }}: + ArtifactName: ${{ parameters.artifactName }} \ No newline at end of file diff --git a/eng/common/templates/steps/publish-logs.yml b/eng/common/templates/steps/publish-logs.yml index 80861297ddc074..4ea86bd8823555 100644 --- a/eng/common/templates/steps/publish-logs.yml +++ b/eng/common/templates/steps/publish-logs.yml @@ -1,49 +1,7 @@ -parameters: - StageLabel: '' - JobLabel: '' - CustomSensitiveDataList: '' - # A default - in case value from eng/common/templates/post-build/common-variables.yml is not passed - BinlogToolVersion: '1.0.11' - steps: -- task: Powershell@2 - displayName: Prepare Binlogs to Upload - inputs: - targetType: inline - script: | - New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - continueOnError: true - condition: always() - -- task: PowerShell@2 - displayName: Redact Logs - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/redact-logs.ps1 - # For now this needs to have explicit list of all sensitive data. Taken from eng/publishing/v3/publish.yml - # Sensitive data can as well be added to $(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' - # If the file exists - sensitive data for redaction will be sourced from it - # (single entry per line, lines starting with '# ' are considered comments and skipped) - arguments: -InputPath '$(Build.SourcesDirectory)/PostBuildLogs' - -BinlogToolVersion ${{parameters.BinlogToolVersion}} - -TokensFilePath '$(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt' - '$(publishing-dnceng-devdiv-code-r-build-re)' - '$(MaestroAccessToken)' - '$(dn-bot-all-orgs-artifact-feeds-rw)' - '$(akams-client-id)' - '$(akams-client-secret)' - '$(microsoft-symbol-server-pat)' - '$(symweb-symbol-server-pat)' - '$(dn-bot-all-orgs-build-rw-code-rw)' - ${{parameters.CustomSensitiveDataList}} - continueOnError: true - condition: always() - -- task: PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' - PublishLocation: Container - ArtifactName: PostBuildLogs - continueOnError: true - condition: always() +- template: /eng/common/core-templates/steps/publish-logs.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/publish-pipeline-artifacts.yml b/eng/common/templates/steps/publish-pipeline-artifacts.yml new file mode 100644 index 00000000000000..5dd698b212fc6b --- /dev/null +++ b/eng/common/templates/steps/publish-pipeline-artifacts.yml @@ -0,0 +1,34 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: false + +- name: args + type: object + default: {} + +steps: +- ${{ if eq(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates cannot be referenced from a 1ES managed template': error +- task: PublishPipelineArtifact@1 + displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }} + ${{ if parameters.args.condition }}: + condition: ${{ parameters.args.condition }} + ${{ else }}: + condition: succeeded() + ${{ if parameters.args.continueOnError }}: + continueOnError: ${{ parameters.args.continueOnError }} + inputs: + targetPath: ${{ parameters.args.targetPath }} + ${{ if parameters.args.artifactName }}: + artifactName: ${{ parameters.args.artifactName }} + ${{ if parameters.args.publishLocation }}: + publishLocation: ${{ parameters.args.publishLocation }} + ${{ if parameters.args.fileSharePath }}: + fileSharePath: ${{ parameters.args.fileSharePath }} + ${{ if parameters.args.Parallel }}: + parallel: ${{ parameters.args.Parallel }} + ${{ if parameters.args.parallelCount }}: + parallelCount: ${{ parameters.args.parallelCount }} + ${{ if parameters.args.properties }}: + properties: ${{ parameters.args.properties }} \ No newline at end of file diff --git a/eng/common/templates/steps/retain-build.yml b/eng/common/templates/steps/retain-build.yml index 83d97a26a01ff9..8e841ace3d293f 100644 --- a/eng/common/templates/steps/retain-build.yml +++ b/eng/common/templates/steps/retain-build.yml @@ -1,28 +1,7 @@ -parameters: - # Optional azure devops PAT with build execute permissions for the build's organization, - # only needed if the build that should be retained ran on a different organization than - # the pipeline where this template is executing from - Token: '' - # Optional BuildId to retain, defaults to the current running build - BuildId: '' - # Azure devops Organization URI for the build in the https://dev.azure.com/ format. - # Defaults to the organization the current pipeline is running on - AzdoOrgUri: '$(System.CollectionUri)' - # Azure devops project for the build. Defaults to the project the current pipeline is running on - AzdoProject: '$(System.TeamProject)' - steps: - - task: powershell@2 - inputs: - targetType: 'filePath' - filePath: eng/common/retain-build.ps1 - pwsh: true - arguments: > - -AzdoOrgUri: ${{parameters.AzdoOrgUri}} - -AzdoProject ${{parameters.AzdoProject}} - -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} - -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} - displayName: Enable permanent build retention - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - BUILD_ID: $(Build.BuildId) \ No newline at end of file +- template: /eng/common/core-templates/steps/retain-build.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/run-on-unix.yml b/eng/common/templates/steps/run-on-unix.yml deleted file mode 100644 index e1733814f65dcc..00000000000000 --- a/eng/common/templates/steps/run-on-unix.yml +++ /dev/null @@ -1,7 +0,0 @@ -parameters: - agentOs: '' - steps: [] - -steps: -- ${{ if ne(parameters.agentOs, 'Windows_NT') }}: - - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/run-on-windows.yml b/eng/common/templates/steps/run-on-windows.yml deleted file mode 100644 index 73e7e9c275a1f1..00000000000000 --- a/eng/common/templates/steps/run-on-windows.yml +++ /dev/null @@ -1,7 +0,0 @@ -parameters: - agentOs: '' - steps: [] - -steps: -- ${{ if eq(parameters.agentOs, 'Windows_NT') }}: - - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/run-script-ifequalelse.yml b/eng/common/templates/steps/run-script-ifequalelse.yml deleted file mode 100644 index 3d1242f5587c82..00000000000000 --- a/eng/common/templates/steps/run-script-ifequalelse.yml +++ /dev/null @@ -1,33 +0,0 @@ -parameters: - # if parameter1 equals parameter 2, run 'ifScript' command, else run 'elsescript' command - parameter1: '' - parameter2: '' - ifScript: '' - elseScript: '' - - # name of script step - name: Script - - # display name of script step - displayName: If-Equal-Else Script - - # environment - env: {} - - # conditional expression for step execution - condition: '' - -steps: -- ${{ if and(ne(parameters.ifScript, ''), eq(parameters.parameter1, parameters.parameter2)) }}: - - script: ${{ parameters.ifScript }} - name: ${{ parameters.name }} - displayName: ${{ parameters.displayName }} - env: ${{ parameters.env }} - condition: ${{ parameters.condition }} - -- ${{ if and(ne(parameters.elseScript, ''), ne(parameters.parameter1, parameters.parameter2)) }}: - - script: ${{ parameters.elseScript }} - name: ${{ parameters.name }} - displayName: ${{ parameters.displayName }} - env: ${{ parameters.env }} - condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/templates/steps/send-to-helix.yml b/eng/common/templates/steps/send-to-helix.yml index 68fa739c4ab215..39f99fc2762d01 100644 --- a/eng/common/templates/steps/send-to-helix.yml +++ b/eng/common/templates/steps/send-to-helix.yml @@ -1,93 +1,7 @@ -# Please remember to update the documentation if you make changes to these parameters! -parameters: - HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ - HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' - HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number - HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues - HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group - HelixProjectPath: 'eng/common/helixpublish.proj' # optional -- path to the project file to build relative to BUILD_SOURCESDIRECTORY - HelixProjectArguments: '' # optional -- arguments passed to the build command - HelixConfiguration: '' # optional -- additional property attached to a job - HelixPreCommands: '' # optional -- commands to run before Helix work item execution - HelixPostCommands: '' # optional -- commands to run after Helix work item execution - WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects - WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects - WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects - CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload - XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true - XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects - XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects - XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner - XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects - IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion - DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." - IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set - HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) - Creator: '' # optional -- if the build is external, use this to specify who is sending the job - DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO - condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() - continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false - steps: - - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' - displayName: ${{ parameters.DisplayNamePrefix }} (Windows) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Unix) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} +- template: /eng/common/core-templates/steps/send-to-helix.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml index 32738aa938013e..23c1d6f4e9f8d4 100644 --- a/eng/common/templates/steps/source-build.yml +++ b/eng/common/templates/steps/source-build.yml @@ -1,131 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. - - # This is a 'steps' template, and is intended for advanced scenarios where the existing build - # infra has a careful build methodology that must be followed. For example, a repo - # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline - # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to - # GitHub. Using this steps template leaves room for that infra to be included. - - # Defines the platform on which to run the steps. See 'eng/common/templates/job/source-build.yml' - # for details. The entire object is described in the 'job' template for simplicity, even though - # the usage of the properties on this object is split between the 'job' and 'steps' templates. - platform: {} - steps: -# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) -- script: | - set -x - df -h - - # If building on the internal project, the artifact feeds variable may be available (usually only if needed) - # In that case, call the feed setup script to add internal feeds corresponding to public ones. - # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. - # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those - # changes. - internalRestoreArgs= - if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then - # Temporarily work around https://github.com/dotnet/arcade/issues/7709 - chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh - $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) - internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' - - # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. - # This only works if there is a username/email configured, which won't be the case in most CI runs. - git config --get user.email - if [ $? -ne 0 ]; then - git config user.email dn-bot@microsoft.com - git config user.name dn-bot - fi - fi - - # If building on the internal project, the internal storage variable may be available (usually only if needed) - # In that case, add variables to allow the download of internal runtimes if the specified versions are not found - # in the default public locations. - internalRuntimeDownloadArgs= - if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then - internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' - fi - - buildConfig=Release - # Check if AzDO substitutes in a build config from a variable, and use it if so. - if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then - buildConfig='$(_BuildConfig)' - fi - - officialBuildArgs= - if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then - officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' - fi - - targetRidArgs= - if [ '${{ parameters.platform.targetRID }}' != '' ]; then - targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' - fi - - runtimeOsArgs= - if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then - runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}' - fi - - baseOsArgs= - if [ '${{ parameters.platform.baseOS }}' != '' ]; then - baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}' - fi - - publishArgs= - if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then - publishArgs='--publish' - fi - - assetManifestFileName=SourceBuild_RidSpecific.xml - if [ '${{ parameters.platform.name }}' != '' ]; then - assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml - fi - - ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ - --configuration $buildConfig \ - --restore --build --pack $publishArgs -bl \ - $officialBuildArgs \ - $internalRuntimeDownloadArgs \ - $internalRestoreArgs \ - $targetRidArgs \ - $runtimeOsArgs \ - $baseOsArgs \ - /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ - /p:ArcadeBuildFromSource=true \ - /p:DotNetBuildSourceOnly=true \ - /p:DotNetBuildRepo=true \ - /p:AssetManifestFileName=$assetManifestFileName - displayName: Build - -# Upload build logs for diagnosis. -- task: CopyFiles@2 - displayName: Prepare BuildLogs staging directory - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - **/*.log - **/*.binlog - artifacts/sb/prebuilt-report/** - TargetFolder: '$(Build.StagingDirectory)/BuildLogs' - CleanTargetFolder: true - continueOnError: true - condition: succeededOrFailed() - -- task: PublishPipelineArtifact@1 - displayName: Publish BuildLogs - inputs: - targetPath: '$(Build.StagingDirectory)/BuildLogs' - artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) - continueOnError: true - condition: succeededOrFailed() +- template: /eng/common/core-templates/steps/source-build.yml + parameters: + is1ESPipeline: false -# Manually inject component detection so that we can ignore the source build upstream cache, which contains -# a nupkg cache of input packages (a local feed). -# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' -# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets -- task: ComponentGovernanceComponentDetection@0 - displayName: Component Detection (Exclude upstream cache) - inputs: - ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/telemetry-end.yml b/eng/common/templates/steps/telemetry-end.yml deleted file mode 100644 index fadc04ca1b9a3e..00000000000000 --- a/eng/common/templates/steps/telemetry-end.yml +++ /dev/null @@ -1,102 +0,0 @@ -parameters: - maxRetries: 5 - retryDelay: 10 # in seconds - -steps: -- bash: | - if [ "$AGENT_JOBSTATUS" = "Succeeded" ] || [ "$AGENT_JOBSTATUS" = "PartiallySucceeded" ]; then - errorCount=0 - else - errorCount=1 - fi - warningCount=0 - - curlStatus=1 - retryCount=0 - # retry loop to harden against spotty telemetry connections - # we don't retry successes and 4xx client errors - until [[ $curlStatus -eq 0 || ( $curlStatus -ge 400 && $curlStatus -le 499 ) || $retryCount -ge $MaxRetries ]] - do - if [ $retryCount -gt 0 ]; then - echo "Failed to send telemetry to Helix; waiting $RetryDelay seconds before retrying..." - sleep $RetryDelay - fi - - # create a temporary file for curl output - res=`mktemp` - - curlResult=` - curl --verbose --output $res --write-out "%{http_code}"\ - -H 'Content-Type: application/json' \ - -H "X-Helix-Job-Token: $Helix_JobToken" \ - -H 'Content-Length: 0' \ - -X POST -G "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$Helix_WorkItemId/finish" \ - --data-urlencode "errorCount=$errorCount" \ - --data-urlencode "warningCount=$warningCount"` - curlStatus=$? - - if [ $curlStatus -eq 0 ]; then - if [ $curlResult -gt 299 ] || [ $curlResult -lt 200 ]; then - curlStatus=$curlResult - fi - fi - - let retryCount++ - done - - if [ $curlStatus -ne 0 ]; then - echo "Failed to Send Build Finish information after $retryCount retries" - vstsLogOutput="vso[task.logissue type=error;sourcepath=templates/steps/telemetry-end.yml;code=1;]Failed to Send Build Finish information: $curlStatus" - echo "##$vstsLogOutput" - exit 1 - fi - displayName: Send Unix Build End Telemetry - env: - # defined via VSTS variables in start-job.sh - Helix_JobToken: $(Helix_JobToken) - Helix_WorkItemId: $(Helix_WorkItemId) - MaxRetries: ${{ parameters.maxRetries }} - RetryDelay: ${{ parameters.retryDelay }} - condition: and(always(), ne(variables['Agent.Os'], 'Windows_NT')) -- powershell: | - if (($env:Agent_JobStatus -eq 'Succeeded') -or ($env:Agent_JobStatus -eq 'PartiallySucceeded')) { - $ErrorCount = 0 - } else { - $ErrorCount = 1 - } - $WarningCount = 0 - - # Basic retry loop to harden against server flakiness - $retryCount = 0 - while ($retryCount -lt $env:MaxRetries) { - try { - Invoke-RestMethod -Uri "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$env:Helix_WorkItemId/finish?errorCount=$ErrorCount&warningCount=$WarningCount" -Method Post -ContentType "application/json" -Body "" ` - -Headers @{ 'X-Helix-Job-Token'=$env:Helix_JobToken } - break - } - catch { - $statusCode = $_.Exception.Response.StatusCode.value__ - if ($statusCode -ge 400 -and $statusCode -le 499) { - Write-Host "##vso[task.logissue]error Failed to send telemetry to Helix (status code $statusCode); not retrying (4xx client error)" - Write-Host "##vso[task.logissue]error ", $_.Exception.GetType().FullName, $_.Exception.Message - exit 1 - } - Write-Host "Failed to send telemetry to Helix (status code $statusCode); waiting $env:RetryDelay seconds before retrying..." - $retryCount++ - sleep $env:RetryDelay - continue - } - } - - if ($retryCount -ge $env:MaxRetries) { - Write-Host "##vso[task.logissue]error Failed to send telemetry to Helix after $retryCount retries." - exit 1 - } - displayName: Send Windows Build End Telemetry - env: - # defined via VSTS variables in start-job.ps1 - Helix_JobToken: $(Helix_JobToken) - Helix_WorkItemId: $(Helix_WorkItemId) - MaxRetries: ${{ parameters.maxRetries }} - RetryDelay: ${{ parameters.retryDelay }} - condition: and(always(),eq(variables['Agent.Os'], 'Windows_NT')) diff --git a/eng/common/templates/steps/telemetry-start.yml b/eng/common/templates/steps/telemetry-start.yml deleted file mode 100644 index 32c01ef0b553b4..00000000000000 --- a/eng/common/templates/steps/telemetry-start.yml +++ /dev/null @@ -1,241 +0,0 @@ -parameters: - helixSource: 'undefined_defaulted_in_telemetry.yml' - helixType: 'undefined_defaulted_in_telemetry.yml' - buildConfig: '' - runAsPublic: false - maxRetries: 5 - retryDelay: 10 # in seconds - -steps: -- ${{ if and(eq(parameters.runAsPublic, 'false'), not(eq(variables['System.TeamProject'], 'public'))) }}: - - task: AzureKeyVault@1 - inputs: - azureSubscription: 'HelixProd_KeyVault' - KeyVaultName: HelixProdKV - SecretsFilter: 'HelixApiAccessToken' - condition: always() -- bash: | - # create a temporary file - jobInfo=`mktemp` - - # write job info content to temporary file - cat > $jobInfo <:-fsanitize-address-use-after-return=never>) - add_compile_options($<$:-fsanitize-address-use-after-return=never>) + add_compile_options($<$:-fsanitize-address-use-after-return=never>) + add_compile_options($<$:-fsanitize-address-use-after-return=never>) endif() endif() @@ -300,7 +301,13 @@ elseif(CLR_CMAKE_HOST_SUNOS) add_definitions(-D__EXTENSIONS__ -D_XPG4_2 -D_POSIX_PTHREAD_SEMANTICS) elseif(CLR_CMAKE_HOST_OSX AND NOT CLR_CMAKE_HOST_MACCATALYST AND NOT CLR_CMAKE_HOST_IOS AND NOT CLR_CMAKE_HOST_TVOS) add_definitions(-D_XOPEN_SOURCE) - add_linker_flag("-Wl,-bind_at_load") + + # the new linker in Xcode 15 (ld_new/ld_prime) deprecated the -bind_at_load flag for macOS which causes a warning + # that fails the build since we build with -Werror. Only pass the flag if we need it, i.e. older linkers. + check_linker_flag(C "-Wl,-bind_at_load,-fatal_warnings" LINKER_SUPPORTS_BIND_AT_LOAD_FLAG) + if(LINKER_SUPPORTS_BIND_AT_LOAD_FLAG) + add_linker_flag("-Wl,-bind_at_load") + endif() elseif(CLR_CMAKE_HOST_HAIKU) add_compile_options($<$:-Wa,--noexecstack>) add_linker_flag("-Wl,--no-undefined") @@ -662,11 +669,11 @@ if (CLR_CMAKE_HOST_UNIX) set(DISABLE_OVERRIDING_MIN_VERSION_ERROR -Wno-overriding-t-option) add_link_options(-Wno-overriding-t-option) if(CLR_CMAKE_HOST_ARCH_ARM64) - set(MACOS_VERSION_MIN_FLAGS "-target arm64-apple-ios14.2-macabi") - add_link_options(-target arm64-apple-ios14.2-macabi) + set(MACOS_VERSION_MIN_FLAGS "-target arm64-apple-ios15.0-macabi") + add_link_options(-target arm64-apple-ios15.0-macabi) elseif(CLR_CMAKE_HOST_ARCH_AMD64) - set(MACOS_VERSION_MIN_FLAGS "-target x86_64-apple-ios13.5-macabi") - add_link_options(-target x86_64-apple-ios13.5-macabi) + set(MACOS_VERSION_MIN_FLAGS "-target x86_64-apple-ios15.0-macabi") + add_link_options(-target x86_64-apple-ios15.0-macabi) else() clr_unknown_arch() endif() @@ -679,11 +686,10 @@ if (CLR_CMAKE_HOST_UNIX) set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} ${MACOS_VERSION_MIN_FLAGS} ${DISABLE_OVERRIDING_MIN_VERSION_ERROR}") set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} ${MACOS_VERSION_MIN_FLAGS} ${DISABLE_OVERRIDING_MIN_VERSION_ERROR}") elseif(CLR_CMAKE_HOST_OSX) + set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0") if(CLR_CMAKE_HOST_ARCH_ARM64) - set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0") add_compile_options(-arch arm64) elseif(CLR_CMAKE_HOST_ARCH_AMD64) - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15") add_compile_options(-arch x86_64) else() clr_unknown_arch() diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index c7c378ab0e41b3..20851f8617423d 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -429,7 +429,6 @@ endif(CLR_CMAKE_TARGET_OS STREQUAL haiku) if(CLR_CMAKE_TARGET_OS STREQUAL emscripten) set(CLR_CMAKE_TARGET_UNIX 1) - set(CLR_CMAKE_TARGET_LINUX 1) set(CLR_CMAKE_TARGET_BROWSER 1) endif(CLR_CMAKE_TARGET_OS STREQUAL emscripten) diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd index f67f17b8d47942..79db6bffae062d 100644 --- a/eng/native/gen-buildsys.cmd +++ b/eng/native/gen-buildsys.cmd @@ -62,7 +62,7 @@ if /i "%__Arch%" == "wasm" ( if /i "%__Os%" == "wasi" ( if "%WASI_SDK_PATH%" == "" ( if not exist "%__repoRoot%\src\mono\wasi\wasi-sdk" ( - echo Error: Should set WASI_SDK_PATH environment variable pointing to emsdk root. + echo Error: Should set WASI_SDK_PATH environment variable pointing to WASI SDK root. exit /B 1 ) diff --git a/eng/pipelines/common/evaluate-default-paths.yml b/eng/pipelines/common/evaluate-default-paths.yml index d954a1ddacbb57..975c18eb69d464 100644 --- a/eng/pipelines/common/evaluate-default-paths.yml +++ b/eng/pipelines/common/evaluate-default-paths.yml @@ -164,6 +164,10 @@ jobs: - src/tools/illink/* - global.json + - subset: tools_cdacreader + include: + - src/native/managed/cdacreader/* + - subset: installer include: exclude: diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 1812fc318bb2ee..8273417557052b 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -34,6 +34,7 @@ parameters: extraVariablesTemplates: [] preBuildSteps: [] templatePath: 'templates' + templateContext: '' jobs: - template: /eng/common/${{ parameters.templatePath }}/job/job.yml @@ -51,6 +52,9 @@ jobs: enablePublishTestResults: ${{ parameters.enablePublishTestResults }} testResultsFormat: ${{ parameters.testResultsFormat }} + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + artifacts: publish: logs: diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index cb3c8b2d0a65e2..2dc00a29da5d35 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -294,6 +294,25 @@ jobs: helixQueueGroup: ${{ parameters.helixQueueGroup }} ${{ insert }}: ${{ parameters.jobParameters }} +- ${{ if containsValue(parameters.platforms, 'linux_musl_x64_dev_innerloop') }}: + - template: xplat-setup.yml + parameters: + jobTemplate: ${{ parameters.jobTemplate }} + helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} + variables: ${{ parameters.variables }} + osGroup: linux + osSubgroup: _musl + archType: x64 + targetRid: linux-musl-x64 + platform: linux_musl_x64 + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} + container: linux_musl_x64_dev_innerloop + jobParameters: + runtimeFlavor: ${{ parameters.runtimeFlavor }} + buildConfig: ${{ parameters.buildConfig }} + helixQueueGroup: ${{ parameters.helixQueueGroup }} + ${{ insert }}: ${{ parameters.jobParameters }} + # GCC Linux x64 Build - ${{ if containsValue(parameters.platforms, 'gcc_linux_x64') }}: diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index b9db26f6cb151c..62f8434f8335c0 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -17,7 +17,7 @@ extends: containers: linux_arm: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-net8.0 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-net9.0 env: ROOTFS_DIR: /crossrootfs/arm @@ -33,17 +33,17 @@ extends: ROOTFS_DIR: /crossrootfs/arm64 linux_musl_x64: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-alpine-net8.0 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-alpine-net9.0 env: ROOTFS_DIR: /crossrootfs/x64 linux_musl_arm: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-alpine-net8.0 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-alpine-net9.0 env: ROOTFS_DIR: /crossrootfs/arm linux_musl_arm64: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm64-alpine-net8.0 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm64-alpine-net9.0 env: ROOTFS_DIR: /crossrootfs/arm64 @@ -56,18 +56,21 @@ extends: image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-android-docker linux_x64: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-net8.0 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-net9.0 env: ROOTFS_DIR: /crossrootfs/x64 linux_x86: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-x86-net8.0 + image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-x86-net9.0 env: ROOTFS_DIR: /crossrootfs/x86 linux_x64_dev_innerloop: image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04 + linux_musl_x64_dev_innerloop: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.19-WithNode + # We use a CentOS Stream 8 image here to test building from source on CentOS Stream 8. SourceBuild_centos_x64: image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8 @@ -77,12 +80,12 @@ extends: image: mcr.microsoft.com/dotnet-buildtools/prereqs:almalinux-8-source-build linux_s390x: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-s390x + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-s390x env: ROOTFS_DIR: /crossrootfs/s390x linux_ppc64le: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-ppc64le + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-ppc64le env: ROOTFS_DIR: /crossrootfs/ppc64le @@ -121,4 +124,4 @@ extends: image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-debpkg rpmpkg: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-fpm \ No newline at end of file + image: mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-fpm diff --git a/eng/pipelines/common/templates/publish-pipeline-artifacts.yml b/eng/pipelines/common/templates/publish-pipeline-artifacts.yml deleted file mode 100644 index 81f292ec5528ce..00000000000000 --- a/eng/pipelines/common/templates/publish-pipeline-artifacts.yml +++ /dev/null @@ -1,17 +0,0 @@ -parameters: -- name: displayName - type: string -- name: inputs - type: object -- name: isOfficialBuild - type: boolean - -steps: - - ${{ if parameters.isOfficialBuild }}: - - task: 1ES.PublishPipelineArtifact@1 - displayName: ${{ parameters.displayName }} - inputs: ${{ parameters.inputs }} - - ${{ else }}: - - task: PublishPipelineArtifact@1 - displayName: ${{ parameters.displayName }} - inputs: ${{ parameters.inputs }} \ No newline at end of file diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index d6404617a3e1ad..0899b32fe524d9 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -537,6 +537,7 @@ jobs: - jitosr_stress - jitpartialcompilation_pgo - jitoptrepeat + - jitrpolayout ${{ else }}: scenarios: - jitosr_stress @@ -549,6 +550,7 @@ jobs: - jitphysicalpromotion_full - jitrlcse - jitoptrepeat + - jitrpolayout ${{ if in(parameters.testGroup, 'jit-cfg') }}: scenarios: - jitcfg diff --git a/eng/pipelines/common/templates/wasm-library-aot-tests.yml b/eng/pipelines/common/templates/wasm-library-aot-tests.yml index 43b90a370450d1..2336f98401515a 100644 --- a/eng/pipelines/common/templates/wasm-library-aot-tests.yml +++ b/eng/pipelines/common/templates/wasm-library-aot-tests.yml @@ -1,7 +1,7 @@ parameters: alwaysRun: false extraBuildArgs: '' - extraHelixArgs: '' + extraHelixArguments: '' isExtraPlatformsBuild: false isWasmOnlyBuild: false buildAOTOnHelix: true @@ -26,7 +26,7 @@ jobs: isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }} isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }} extraBuildArgs: /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=${{ parameters.buildAOTOnHelix }} /p:RunAOTCompilation=${{ parameters.runAOT }} ${{ parameters.extraBuildArgs }} - extraHelixArgs: /p:NeedsToBuildWasmAppsOnHelix=true ${{ parameters.extraHelixArgs }} + extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true ${{ parameters.extraHelixArguments }} alwaysRun: ${{ parameters.alwaysRun }} shouldRunSmokeOnly: ${{ parameters.shouldRunSmokeOnly }} shouldContinueOnError: ${{ parameters.shouldContinueOnError }} diff --git a/eng/pipelines/common/templates/wasm-library-tests.yml b/eng/pipelines/common/templates/wasm-library-tests.yml index 4a1a5a79a30bfc..f015563fef00e3 100644 --- a/eng/pipelines/common/templates/wasm-library-tests.yml +++ b/eng/pipelines/common/templates/wasm-library-tests.yml @@ -1,7 +1,7 @@ parameters: alwaysRun: false extraBuildArgs: '' - extraHelixArgs: '' + extraHelixArguments: '' isExtraPlatformsBuild: false isWasmOnlyBuild: false nameSuffix: '' @@ -97,5 +97,5 @@ jobs: parameters: creator: dotnet-bot testRunNamePrefixSuffix: Mono_$(_BuildConfig) - extraHelixArguments: /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) ${{ parameters.extraHelixArgs }} + extraHelixArguments: /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) ${{ parameters.extraHelixArguments }} scenarios: ${{ parameters.scenarios }} diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index 743f6a42531bcc..f50a2db9e81ec5 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -188,7 +188,6 @@ jobs: name: $(DncEngPublicBuildPool) demands: ImageOverride -equals windows.vs2022.amd64.open - ${{ if eq(parameters.helixQueuesTemplate, '') }}: # macOS hosted pool machines are slower so we need to give a greater timeout than the 60 mins default. ${{ if and(eq(parameters.jobParameters.timeoutInMinutes, ''), in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'tvos')) }}: diff --git a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml index 94761028f48ab0..bc29a657c456ce 100644 --- a/eng/pipelines/coreclr/nativeaot-post-build-steps.yml +++ b/eng/pipelines/coreclr/nativeaot-post-build-steps.yml @@ -21,11 +21,3 @@ steps: nativeAotTest: true helixQueues: ${{ parameters.helixQueues }} liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }} - - # Can't run arm/arm64 tests on x64 build machines - - ${{ if and(ne(parameters.archType, 'arm'), ne(parameters.archType, 'arm64')) }}: - - # Publishing tooling doesn't support different configs between runtime and libs, so only run tests in Release config - - ${{ if eq(parameters.buildConfig, 'release') }}: - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) $(crossArg) $(_nativeSanitizersArg) /p:TestAssemblies=false /p:RunNativeAotTestApps=true $(_officialBuildParameter) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTests.binlog ${{ parameters.extraTestArgs }} - displayName: Run NativeAot Library Tests diff --git a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml index c48103af929c81..574728cfed7eae 100644 --- a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml +++ b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml @@ -306,7 +306,7 @@ jobs: runJobTemplate: /eng/pipelines/coreclr/templates/run-performance-job.yml logicalmachine: 'perfviper' - # run coreclr perfowl microbenchmarks perf gdv3 jobs + # run coreclr perfowl microbenchmarks perf rlcse jobs - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml @@ -322,9 +322,9 @@ jobs: runKind: micro runJobTemplate: /eng/pipelines/coreclr/templates/run-performance-job.yml logicalmachine: 'perfowl' - experimentName: 'gdv3' + experimentName: 'rlcse' - # run coreclr perfowl microbenchmarks perf rlcse jobs + # run coreclr perfowl microbenchmarks perf jitoptrepeat jobs - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml @@ -340,9 +340,9 @@ jobs: runKind: micro runJobTemplate: /eng/pipelines/coreclr/templates/run-performance-job.yml logicalmachine: 'perfowl' - experimentName: 'rlcse' + experimentName: 'jitoptrepeat' - # run coreclr perfowl microbenchmarks perf jitoptrepeat jobs + # run coreclr perfowl microbenchmarks perf rpolayout jobs - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml @@ -358,7 +358,7 @@ jobs: runKind: micro runJobTemplate: /eng/pipelines/coreclr/templates/run-performance-job.yml logicalmachine: 'perfowl' - experimentName: 'jitoptrepeat' + experimentName: 'rpolayout' # run coreclr crossgen perf job - template: /eng/pipelines/common/platform-matrix.yml diff --git a/eng/pipelines/coreclr/runtime-nativeaot-outerloop.yml b/eng/pipelines/coreclr/runtime-nativeaot-outerloop.yml index e8bfd86cd81dd2..494601a890df12 100644 --- a/eng/pipelines/coreclr/runtime-nativeaot-outerloop.yml +++ b/eng/pipelines/coreclr/runtime-nativeaot-outerloop.yml @@ -69,7 +69,7 @@ extends: testGroup: innerloop isSingleFile: true nameSuffix: NativeAOT_Libs - buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:ArchiveTests=true /p:IlcUseServerGc=false /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:ArchiveTests=true /p:IlcUseServerGc=false /p:RunAnalyzers=false timeoutInMinutes: 300 # doesn't normally take this long, but I've seen Helix queues backed up for 160 minutes includeAllPlatforms: true # extra steps, run tests @@ -95,7 +95,7 @@ extends: testGroup: innerloop isSingleFile: true nameSuffix: NativeAOT_Checked_Libs - buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:IlcUseServerGc=false /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:IlcUseServerGc=false /p:RunAnalyzers=false timeoutInMinutes: 360 # extra steps, run tests postBuildSteps: @@ -120,7 +120,7 @@ extends: testGroup: innerloop isSingleFile: true nameSuffix: NativeAOT_Checked_Libs_SizeOpt - buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:OptimizationPreference=Size /p:IlcUseServerGc=false /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:OptimizationPreference=Size /p:IlcUseServerGc=false /p:RunAnalyzers=false timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: @@ -145,7 +145,7 @@ extends: testGroup: innerloop isSingleFile: true nameSuffix: NativeAOT_Checked_Libs_SpeedOpt - buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:OptimizationPreference=Speed /p:IlcUseServerGc=false /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) -rc Checked /p:TestNativeAot=true /p:ArchiveTests=true /p:OptimizationPreference=Speed /p:IlcUseServerGc=false /p:RunAnalyzers=false timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: @@ -176,7 +176,7 @@ extends: jobParameters: timeoutInMinutes: 300 # doesn't normally take this long, but we have had Helix queues backed up for over an hour nameSuffix: NativeAOT_Pri0 - buildArgs: -s clr.aot+host.native+libs -rc $(_BuildConfig) -lc Release -hc Release /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs -rc $(_BuildConfig) -lc Release /p:RunAnalyzers=false postBuildSteps: - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml parameters: diff --git a/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml b/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml index 2c947a048e0550..a5c6cb414227d8 100644 --- a/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml +++ b/eng/pipelines/extra-platforms/runtime-extra-platforms-wasm.yml @@ -197,8 +197,8 @@ jobs: isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }} alwaysRun: true scenarios: - - WasmTestOnV8 - WasmTestOnChrome + - WasmTestOnFirefox - WasmTestOnNodeJS # Hybrid Globalization AOT tests @@ -214,7 +214,6 @@ jobs: isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }} alwaysRun: true scenarios: - - WasmTestOnV8 - WasmTestOnChrome - WasmTestOnNodeJS @@ -321,4 +320,4 @@ jobs: isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }} isWasmOnlyBuild: ${{ parameters.isWasmOnlyBuild }} scenarios: - - WasmTestOnV8 + - WasmTestOnWasmtime diff --git a/eng/pipelines/global-build.yml b/eng/pipelines/global-build.yml index 2e70a2448cd9d3..d7302fe253b6b9 100644 --- a/eng/pipelines/global-build.yml +++ b/eng/pipelines/global-build.yml @@ -1,6 +1,6 @@ -# The purpose of this pipeline is to exercise local developer workflow in the consolidated -# runtime repo. In particular, it is supposed to run the root "build" script just like any -# normal developer normally would and monitor regressions w.r.t. this fundamental scenario. +# The purpose of this pipeline is to exercise various developer workflows in the repo. +# Primarily, it is meant to cover local (non-cross) build scenarios and +# source-build scenarios that commonly cause build breaks. trigger: none @@ -41,28 +41,6 @@ extends: - stage: Build jobs: - # - # Build with Release config and Debug runtimeConfiguration - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: release - platforms: - - windows_x86 - - osx_x64 - - osx_arm64 - jobParameters: - testGroup: innerloop - nameSuffix: Runtime_Debug - buildArgs: -c release -runtimeConfiguration debug - timeoutInMinutes: 120 - condition: - or( - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), - eq(variables['isRollingBuild'], true)) - # # Build with Release config and runtimeConfiguration with MSBuild generator # @@ -83,26 +61,6 @@ extends: eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), eq(variables['isRollingBuild'], true)) - # - # Build with Debug config and Release runtimeConfiguration - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: debug - platforms: - - linux_x64_dev_innerloop - jobParameters: - testGroup: innerloop - nameSuffix: Runtime_Release - buildArgs: -c debug -runtimeConfiguration release - timeoutInMinutes: 120 - condition: - or( - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), - eq(variables['isRollingBuild'], true)) - # # Build with RuntimeFlavor only. This exercise code paths where only RuntimeFlavor is # specified. Catches cases where we depend on Configuration also being specified @@ -124,38 +82,37 @@ extends: eq(variables['isRollingBuild'], true)) # - # Build Mono + Libraries. This exercises the code path where we build libraries without - # first building CoreCLR + # Build Libraries AllConfigurations. This exercises the code path where we build libraries for all + # configurations on a non Windows operating system. # - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: debug platforms: - - windows_x64 + - linux_x64_dev_innerloop jobParameters: - testGroup: innerloop - nameSuffix: Mono_Libraries - buildArgs: -subset mono+libs /p:RuntimeFlavor=Mono + nameSuffix: Libraries_AllConfigurations + buildArgs: -subset libs -allconfigurations timeoutInMinutes: 120 condition: or( - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_wasm.containsChange'], true), + eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), eq(variables['isRollingBuild'], true)) # - # Build Libraries AllConfigurations. This exercises the code path where we build libraries for all - # configurations on a non Windows operating system. + # Build native assets on Alpine. This exercises more modern musl libc changes that have a tendendy to break source-build. + # We don't add this as a source-build job as the repo source-build infrastructure isn't set up to run on alpine effectively. # - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: debug + buildConfig: release platforms: - - linux_x64_dev_innerloop + - linux_musl_x64_dev_innerloop jobParameters: - nameSuffix: Libraries_AllConfigurations - buildArgs: -subset libs -allconfigurations + nameSuffix: Musl_Validation + buildArgs: -subset clr.native+libs.native+host.native -c $(_BuildConfig) timeoutInMinutes: 120 condition: or( diff --git a/eng/pipelines/libraries/execute-trimming-tests-steps.yml b/eng/pipelines/libraries/execute-trimming-tests-steps.yml index 567abab0bb984e..13778ee0ab63a5 100644 --- a/eng/pipelines/libraries/execute-trimming-tests-steps.yml +++ b/eng/pipelines/libraries/execute-trimming-tests-steps.yml @@ -1,8 +1,14 @@ parameters: archType: '' extraTestArgs: '' + runAotTests: true steps: # Execute tests - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) $(crossArg) /p:TestAssemblies=false /p:TestTrimming=true $(_officialBuildParameter) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/TrimmingTests.binlog ${{ parameters.extraTestArgs }} displayName: Run Trimming Tests + + # Execute AOT test app tests + - ${{ if eq(parameters.runAotTests, true) }}: + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -ci -arch ${{ parameters.archType }} $(_osParameter) -s libs.tests -c $(_BuildConfig) $(crossArg) /p:TestAssemblies=false /p:RunNativeAotTestApps=true $(_officialBuildParameter) /bl:$(Build.SourcesDirectory)/artifacts/log/$(buildConfigUpper)/NativeAotTestAppTests.binlog ${{ parameters.extraTestArgs }} + displayName: Run Native AOT Test App Tests diff --git a/eng/pipelines/mono/templates/generate-offsets.yml b/eng/pipelines/mono/templates/generate-offsets.yml deleted file mode 100644 index 8d8d781dd3262e..00000000000000 --- a/eng/pipelines/mono/templates/generate-offsets.yml +++ /dev/null @@ -1,88 +0,0 @@ -parameters: - buildConfig: 'Debug' - osGroup: '' - osSubGroup: '' - platform: '' - container: '' - timeoutInMinutes: '' - variables: {} - pool: '' - condition: true - isOfficialBuild: false - templatePath: 'templates' - -### Product build -jobs: -- template: /eng/pipelines/common/templates/runtimes/xplat-job.yml - parameters: - templatePath: ${{ parameters.templatePath }} - buildConfig: ${{ parameters.buildConfig }} - osGroup: ${{ parameters.osGroup }} - osSubGroup: ${{ parameters.osSubGroup }} - helixType: 'build/product/' - enableMicrobuild: true - pool: ${{ parameters.pool }} - condition: ${{ parameters.condition }} - dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths }} - logsName: 'BuildLogs_Attempt$(System.JobAttempt)_Mono_Offsets_$(osGroup)$(osSubGroup)' - - # Compute job name from template parameters - name: ${{ format('mono_{0}{1}_offsets', parameters.osGroup, parameters.osSubGroup) }} - displayName: ${{ format('Mono {0}{1} AOT offsets', parameters.osGroup, parameters.osSubGroup) }} - - # Run all steps in the container. - # Note that the containers are defined in platform-matrix.yml - container: ${{ parameters.container }} - - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - - gatherAssetManifests: true - variables: - - name: osGroup - value: ${{ parameters.osGroup }} - - name: osSubGroup - value: ${{ parameters.osSubGroup }} - - name: officialBuildIdArg - value: '' - - ${{ if eq(parameters.isOfficialBuild, true) }}: - - name: officialBuildIdArg - value: '/p:OfficialBuildId=$(Build.BuildNumber)' - - name: osOverride - value: -os linux - - name: archType - value: x64 - - ${{ parameters.variables }} - - steps: - - # Install native dependencies - # Linux builds use docker images with dependencies preinstalled, - # and FreeBSD builds use a build agent with dependencies - # preinstalled, so we only need this step for OSX and Windows. - - ${{ if in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator') }}: - - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh $(osGroup) - displayName: Install native dependencies - - # Build - - ${{ if ne(parameters.osGroup, 'windows') }}: - - script: ./build$(scriptExt) -subset mono.aotcross -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) /p:MonoGenerateOffsetsOSGroups=$(osGroup) - displayName: Generate AOT offsets - - ${{ if eq(parameters.osGroup, 'windows') }}: - - script: build$(scriptExt) -subset mono.aotcross -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) /p:MonoGenerateOffsetsOSGroups=$(osGroup) - displayName: Generate AOT offsets - - # Upload offset files - - task: CopyFiles@2 - displayName: Collect offset files - inputs: - sourceFolder: '$(Build.SourcesDirectory)/artifacts/obj/mono/' - contents: '**/offsets-*.h' - targetFolder: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles/' - - - template: /eng/pipelines/common/templates/publish-pipeline-artifacts.yml - parameters: - displayName: Upload offset files - isOfficialBuild: ${{ parameters.isOfficialBuild }} - inputs: - targetPath: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles' - artifactName: 'Mono_Offsets_$(osGroup)$(osSubGroup)' diff --git a/eng/pipelines/mono/templates/workloads-build.yml b/eng/pipelines/mono/templates/workloads-build.yml deleted file mode 100644 index 89404db6b29201..00000000000000 --- a/eng/pipelines/mono/templates/workloads-build.yml +++ /dev/null @@ -1,117 +0,0 @@ -parameters: - archType: '' - buildConfig: '' - container: '' - dependsOn: [] - isOfficialBuild: false - osGroup: '' - osSubgroup: '' - platform: '' - pool: '' - runtimeVariant: '' - testGroup: '' - timeoutInMinutes: '' - templatePath: 'templates' - variables: {} - -jobs: -- template: /eng/pipelines/common/templates/runtimes/xplat-job.yml - parameters: - templatePath: ${{ parameters.templatePath }} - archType: ${{ parameters.archType }} - buildConfig: ${{ parameters.buildConfig }} - container: ${{ parameters.container }} - condition: and(succeeded(), ${{ parameters.isOfficialBuild }}) - helixType: 'build/product/' - osGroup: ${{ parameters.osGroup }} - osSubgroup: ${{ parameters.osSubgroup }} - pool: ${{ parameters.pool }} - runtimeVariant: ${{ parameters.runtimeVariant }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - logsName: WorkloadLogs_Attempt$(System.JobAttempt) - - dependsOn: ${{ parameters.dependsOn }} - - name: workloadsbuild - displayName: Build Workloads - - variables: - - name: officialBuildIdArg - value: '' - - ${{ if eq(parameters.isOfficialBuild, true) }}: - - name: officialBuildIdArg - value: '/p:OfficialBuildId=$(Build.BuildNumber)' - - name: SignType - value: $[ coalesce(variables.OfficialSignType, 'real') ] - - name: workloadPackagesPath - value: $(Build.SourcesDirectory)/artifacts/workloadPackages - - name: workloadArtifactsPath - value: $(Build.SourcesDirectory)/artifacts/workloads - - ${{ parameters.variables }} - - steps: - - task: DownloadPipelineArtifact@2 - inputs: - artifact: 'IntermediateArtifacts' - path: $(workloadPackagesPath) - patterns: | - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-arm64.Cross.android-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.browser-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-arm64.Cross.browser-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.wasi-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-arm64.Cross.wasi-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.android-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.browser-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.ios-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.iossimulator-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.tvos-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.tvossimulator-*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.wasi-wasm*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.Current.Manifest*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.net6.Manifest*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.net7.Manifest*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.net8.Manifest*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoTargets.Sdk*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoAOTCompiler.Task*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Sdk*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Wasi*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Templates*.nupkg - IntermediateArtifacts/windows_arm64/Shipping/Microsoft.NETCore.App.Runtime.win-arm64*.nupkg - IntermediateArtifacts/windows_x64/Shipping/Microsoft.NETCore.App.Runtime.win-x64*.nupkg - IntermediateArtifacts/windows_x86/Shipping/Microsoft.NETCore.App.Runtime.win-x86*.nupkg - IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Sdk.WebAssembly.Pack*.nupkg - - - task: CopyFiles@2 - displayName: Flatten packages - inputs: - sourceFolder: $(workloadPackagesPath) - contents: '*/Shipping/*.nupkg' - cleanTargetFolder: false - targetFolder: $(workloadPackagesPath) - flattenFolders: true - - - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset mono.workloads -arch $(archType) -c $(buildConfig) $(officialBuildIdArg) -ci - displayName: Build workload artifacts - - # Upload packages wrapping msis - - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - parameters: - name: workloads - - # Delete wixpdb files before they are uploaded to artifacts - - task: DeleteFiles@1 - displayName: Delete wixpdb's - inputs: - SourceFolder: $(workloadArtifactsPath) - Contents: '*.wixpdb' - - # Upload artifacts to be used for generating VS components - - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - parameters: - name: workloads-vs - publishPackagesCondition: false - publishVSSetupCondition: true diff --git a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml index 24fd2df48d74be..eb25d311890a98 100644 --- a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml +++ b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml @@ -1,76 +1,65 @@ parameters: - dependsOn: [] PublishRidAgnosticPackagesFromPlatform: '' isOfficialBuild: false logArtifactName: 'Logs-PrepareSignedArtifacts_Attempt$(System.JobAttempt)' jobs: -- job: PrepareSignedArtifacts - displayName: Prepare Signed Artifacts - dependsOn: ${{ parameters.dependsOn }} - pool: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals 1es-windows-2022 - # Double the default timeout. - timeoutInMinutes: 240 - workspace: - clean: all +- template: /eng/common/templates-official/job/job.yml + parameters: + name: 'PrepareSignedArtifacts' + displayName: 'Prepare Signed Artifacts' - variables: - - name: SignType - value: $[ coalesce(variables.OfficialSignType, 'real') ] + pool: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals 1es-windows-2022 - templateContext: - outputs: - - output: pipelineArtifact - displayName: 'Publish BuildLogs' - condition: succeededOrFailed() - targetPath: '$(Build.StagingDirectory)\BuildLogs' - artifactName: ${{ parameters.logArtifactName }} + # Double the default timeout. + timeoutInMinutes: 240 - steps: - - checkout: self - clean: true - fetchDepth: 20 + workspace: + clean: all - - ${{ if eq(parameters.isOfficialBuild, true) }}: - - task: NuGetAuthenticate@1 + enableMicrobuild: true - - task: MicroBuildSigningPlugin@2 - displayName: Install MicroBuild plugin for Signing - inputs: - signType: $(SignType) - zipSources: false - feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - continueOnError: false - condition: and(succeeded(), - in(variables['SignType'], 'real', 'test')) - - - task: DownloadBuildArtifacts@0 - displayName: Download IntermediateArtifacts - inputs: - artifactName: IntermediateArtifacts - downloadPath: $(Build.SourcesDirectory)\artifacts\PackageDownload - checkDownloadedFiles: true - - - script: >- - build.cmd -ci - -subset publish - -configuration Release - /p:PublishRidAgnosticPackagesFromPlatform=${{ parameters.PublishRidAgnosticPackagesFromPlatform }} - /p:OfficialBuildId=$(Build.BuildNumber) - /p:SignType=$(SignType) - /p:DotNetSignType=$(SignType) - /bl:$(Build.SourcesDirectory)\prepare-artifacts.binlog - displayName: Prepare artifacts and upload to build - - - task: CopyFiles@2 - displayName: Copy Files to $(Build.StagingDirectory)\BuildLogs - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - **/*.log - **/*.binlog - TargetFolder: '$(Build.StagingDirectory)\BuildLogs' - continueOnError: true - condition: succeededOrFailed() \ No newline at end of file + variables: + - name: '_SignType' + value: $[ coalesce(variables.OfficialSignType, 'real') ] + + templateContext: + inputs: + - input: checkout + repository: self + clean: true + fetchDepth: 20 + - input: pipelineArtifact + artifactName: IntermediateArtifacts + targetPath: $(Build.SourcesDirectory)\artifacts\PackageDownload\IntermediateArtifacts + outputs: + - output: pipelineArtifact + displayName: 'Publish BuildLogs' + condition: succeededOrFailed() + targetPath: '$(Build.StagingDirectory)\BuildLogs' + artifactName: ${{ parameters.logArtifactName }} + + steps: + - script: >- + build.cmd -ci + -subset publish + -configuration Release + /p:PublishRidAgnosticPackagesFromPlatform=${{ parameters.PublishRidAgnosticPackagesFromPlatform }} + /p:OfficialBuildId=$(Build.BuildNumber) + /p:SignType=$(_SignType) + /p:DotNetSignType=$(_SignType) + /bl:$(Build.SourcesDirectory)\prepare-artifacts.binlog + displayName: Prepare artifacts and upload to build + + - task: CopyFiles@2 + displayName: Copy Files to $(Build.StagingDirectory)\BuildLogs + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/*.log + **/*.binlog + TargetFolder: '$(Build.StagingDirectory)\BuildLogs' + continueOnError: true + condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml index aec5e1057ac538..2b001b769f50f9 100644 --- a/eng/pipelines/runtime-linker-tests.yml +++ b/eng/pipelines/runtime-linker-tests.yml @@ -135,3 +135,4 @@ extends: - template: /eng/pipelines/libraries/execute-trimming-tests-steps.yml parameters: extraTestArgs: '/p:WasmBuildNative=false' + runAotTests: false diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 23f19405abea7c..cf856d94df6164 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -381,11 +381,12 @@ extends: parameters: name: MonoRuntimePacks + # Build Mono AOT offset headers once, for consumption elsewhere # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/mono/templates/generate-offsets.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: release platforms: - android_x64 @@ -394,9 +395,31 @@ extends: - tvos_arm64 - ios_arm64 - maccatalyst_x64 + variables: + - name: _osParameter + value: -os linux + - name: _archParameter + value: -arch x64 jobParameters: templatePath: 'templates-official' - isOfficialBuild: ${{ variables.isOfficialBuild }} + nameSuffix: MonoAOTOffsets + buildArgs: -s mono.aotcross -c $(_BuildConfig) /p:MonoGenerateOffsetsOSGroups=$(osGroup) + postBuildSteps: + # Upload offset files + - task: CopyFiles@2 + displayName: Collect offset files + inputs: + sourceFolder: '$(Build.SourcesDirectory)/artifacts/obj/mono/' + contents: '**/offsets-*.h' + targetFolder: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles/' + + templateContext: + outputs: + - output: pipelineArtifact + displayName: 'Publish Mono AOT offsets' + condition: succeeded() + targetPath: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles' + artifactName: 'Mono_Offsets_$(osGroup)$(osSubGroup)' # # Build Mono release AOT cross-compilers @@ -418,9 +441,9 @@ extends: nameSuffix: CrossAOT_Mono runtimeVariant: crossaot dependsOn: - - mono_android_offsets - - mono_browser_offsets - - mono_wasi_offsets + - build_android_x64_release_MonoAOTOffsets + - build_browser_wasm_linux_release_MonoAOTOffsets + - build_wasi_wasm_linux_release_MonoAOTOffsets monoCrossAOTTargetOS: - android - browser @@ -446,9 +469,9 @@ extends: nameSuffix: CrossAOT_Mono runtimeVariant: crossaot dependsOn: - - mono_android_offsets - - mono_browser_offsets - - mono_wasi_offsets + - build_android_x64_release_MonoAOTOffsets + - build_browser_wasm_linux_release_MonoAOTOffsets + - build_wasi_wasm_linux_release_MonoAOTOffsets monoCrossAOTTargetOS: - android - browser @@ -474,12 +497,12 @@ extends: nameSuffix: CrossAOT_Mono runtimeVariant: crossaot dependsOn: - - mono_android_offsets - - mono_browser_offsets - - mono_wasi_offsets - - mono_tvos_offsets - - mono_ios_offsets - - mono_maccatalyst_offsets + - build_android_x64_release_MonoAOTOffsets + - build_browser_wasm_linux_release_MonoAOTOffsets + - build_wasi_wasm_linux_release_MonoAOTOffsets + - build_tvos_arm64_release_MonoAOTOffsets + - build_ios_arm64_release_MonoAOTOffsets + - build_maccatalyst_x64_release_MonoAOTOffsets monoCrossAOTTargetOS: - android - browser @@ -599,12 +622,80 @@ extends: # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/mono/templates/workloads-build.yml + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: release platforms: - windows_x64 jobParameters: templatePath: 'templates-official' + nameSuffix: Workloads + preBuildSteps: + - task: DownloadPipelineArtifact@2 + inputs: + artifact: 'IntermediateArtifacts' + path: $(Build.SourcesDirectory)/artifacts/workloadPackages + patterns: | + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-arm64.Cross.android-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.browser-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-arm64.Cross.browser-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.wasi-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.AOT.win-arm64.Cross.wasi-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.android-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.browser-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.ios-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.iossimulator-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.tvos-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.tvossimulator-*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.Mono.wasi-wasm*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.Current.Manifest*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.net6.Manifest*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.net7.Manifest*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Workload.Mono.ToolChain.net8.Manifest*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoTargets.Sdk*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoAOTCompiler.Task*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Sdk*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Wasi*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Templates*.nupkg + IntermediateArtifacts/windows_arm64/Shipping/Microsoft.NETCore.App.Runtime.win-arm64*.nupkg + IntermediateArtifacts/windows_x64/Shipping/Microsoft.NETCore.App.Runtime.win-x64*.nupkg + IntermediateArtifacts/windows_x86/Shipping/Microsoft.NETCore.App.Runtime.win-x86*.nupkg + IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Sdk.WebAssembly.Pack*.nupkg + + - task: CopyFiles@2 + displayName: Flatten packages + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/workloadPackages + contents: '*/Shipping/*.nupkg' + cleanTargetFolder: false + targetFolder: $(Build.SourcesDirectory)/artifacts/workloadPackages + flattenFolders: true + + buildArgs: -s mono.workloads -c $(_BuildConfig) /p:PackageSource=$(Build.SourcesDirectory)/artifacts/workloadPackages /p:WorkloadOutputPath=$(Build.SourcesDirectory)/artifacts/workloads + + postBuildSteps: + # Upload packages wrapping msis + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: workloads + + # Delete wixpdb files before they are uploaded to artifacts + - task: DeleteFiles@1 + displayName: Delete wixpdb's + inputs: + SourceFolder: $(Build.SourcesDirectory)/artifacts/workloads + Contents: '*.wixpdb' + + # Upload artifacts to be used for generating VS components + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: workloads-vs + publishPackagesCondition: false + publishVSSetupCondition: always() + isOfficialBuild: ${{ variables.isOfficialBuild }} timeoutInMinutes: 120 dependsOn: diff --git a/eng/pipelines/runtime-sanitized.yml b/eng/pipelines/runtime-sanitized.yml index ed0334b61b3e9d..df461c03b7a70a 100644 --- a/eng/pipelines/runtime-sanitized.yml +++ b/eng/pipelines/runtime-sanitized.yml @@ -133,7 +133,7 @@ extends: testGroup: innerloop timeoutInMinutes: 120 nameSuffix: NativeAOT - buildArgs: -s clr.aot+host.native+libs -rc $(_BuildConfig) -lc Release -hc Release $(_nativeSanitizersArg) + buildArgs: -s clr.aot+libs -rc $(_BuildConfig) -lc Release $(_nativeSanitizersArg) postBuildSteps: - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml parameters: diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index b4ed2afd252d23..cb7aadde9fab6d 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -498,7 +498,7 @@ extends: jobParameters: testScope: innerloop nameSuffix: CoreCLR_NonPortable - buildArgs: -s clr.native+clr.tools+clr.corelib+clr.nativecorelib+clr.aot+clr.packages -c $(_BuildConfig) /p:PortableBuild=false + buildArgs: -s clr.native+clr.tools+clr.corelib+clr.nativecorelib+clr.aot+clr.packages --outputrid tizen.9.0.0-armel -c $(_BuildConfig) /p:PortableBuild=false timeoutInMinutes: 120 condition: >- or( @@ -567,7 +567,7 @@ extends: jobParameters: timeoutInMinutes: 120 nameSuffix: NativeAOT - buildArgs: -s clr.aot+host.native+libs -rc $(_BuildConfig) -lc Release -hc Release /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs -rc $(_BuildConfig) -lc Release /p:RunAnalyzers=false postBuildSteps: - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml parameters: @@ -606,7 +606,7 @@ extends: jobParameters: timeoutInMinutes: 180 nameSuffix: NativeAOT - buildArgs: -s clr.aot+host.native+libs.native+libs.sfx -rc $(_BuildConfig) -lc Release -hc Release /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs.native+libs.sfx -rc $(_BuildConfig) -lc Release /p:RunAnalyzers=false postBuildSteps: - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml parameters: @@ -651,7 +651,7 @@ extends: testGroup: innerloop timeoutInMinutes: 120 nameSuffix: NativeAOT - buildArgs: -s clr.aot+host.native+libs+tools.illink -c $(_BuildConfig) -rc $(_BuildConfig) -lc Release -hc Release /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs+tools.illink -c $(_BuildConfig) -rc $(_BuildConfig) -lc Release /p:RunAnalyzers=false postBuildSteps: - template: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml parameters: @@ -688,7 +688,7 @@ extends: testGroup: innerloop isSingleFile: true nameSuffix: NativeAOT_Libraries - buildArgs: -s clr.aot+host.native+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true /p:ArchiveTests=true /p:RunAnalyzers=false + buildArgs: -s clr.aot+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true /p:ArchiveTests=true /p:RunAnalyzers=false timeoutInMinutes: 240 # Doesn't actually take long, but we've seen the ARM64 Helix queue often get backlogged for 2+ hours # extra steps, run tests postBuildSteps: @@ -713,7 +713,7 @@ extends: jobParameters: timeoutInMinutes: 120 nameSuffix: CLR_Tools_Tests - buildArgs: -s clr.aot+clr.iltools+libs.sfx+clr.toolstests -c $(_BuildConfig) -test + buildArgs: -s clr.aot+clr.iltools+libs.sfx+clr.toolstests+tools.cdacreadertests -c $(_BuildConfig) -test enablePublishTestResults: true testResultsFormat: 'xunit' # We want to run AOT tests when illink changes because there's share code and tests from illink which are used by AOT @@ -721,6 +721,7 @@ extends: or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true), + eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_cdacreader.containsChange'], true), eq(variables['isRollingBuild'], true)) # # Build CrossDacs @@ -753,8 +754,7 @@ extends: # - template: /eng/pipelines/common/platform-matrix.yml parameters: - jobTemplate: /eng/pipelines/mono/templates/generate-offsets.yml - templatePath: 'templates' + jobTemplate: /eng/pipelines/common/global-build-job.yml buildConfig: release platforms: - android_x64 @@ -763,8 +763,26 @@ extends: - tvos_arm64 - ios_arm64 - maccatalyst_x64 + variables: + - name: _osParameter + value: -os linux + - name: _archParameter + value: -arch x64 jobParameters: - isOfficialBuild: false + nameSuffix: MonoAOTOffsets + buildArgs: -s mono.aotcross -c $(_BuildConfig) /p:MonoGenerateOffsetsOSGroups=$(osGroup) + postBuildSteps: + # Upload offset files + - task: CopyFiles@2 + displayName: Collect offset files + inputs: + sourceFolder: '$(Build.SourcesDirectory)/artifacts/obj/mono/' + contents: '**/offsets-*.h' + targetFolder: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles/' + + - publish: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles' + artifact: Mono_Offsets_$(osGroup)$(osSubGroup) + displayName: Upload offset files # needed by crossaot condition: >- or( @@ -825,6 +843,7 @@ extends: scenarios: - WasmTestOnV8 - WasmTestOnChrome + - WasmTestOnFirefox - template: /eng/pipelines/common/templates/wasm-library-tests.yml parameters: @@ -843,10 +862,12 @@ extends: #- browser_wasm_win nameSuffix: _Threading extraBuildArgs: /p:WasmEnableThreads=true /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS) + extraHelixArguments: /p:WasmEnableThreads=true alwaysRun: ${{ variables.isRollingBuild }} shouldRunSmokeOnly: onLibrariesAndIllinkChanges scenarios: - WasmTestOnChrome + - WasmTestOnFirefox #- WasmTestOnNodeJS - this is not supported yet, https://github.com/dotnet/runtime/issues/85592 # EAT Library tests - only run on linux @@ -867,7 +888,6 @@ extends: - browser_wasm - browser_wasm_win - wasi_wasm - - wasi_wasm_win nameSuffix: _Smoke_AOT runAOT: true shouldRunSmokeOnly: true @@ -1245,9 +1265,9 @@ extends: nameSuffix: CrossAOT_Mono runtimeVariant: crossaot dependsOn: - - mono_android_offsets - - mono_browser_offsets - - mono_wasi_offsets + - build_android_x64_release_MonoAOTOffsets + - build_browser_wasm_linux_release_MonoAOTOffsets + - build_wasi_wasm_linux_release_MonoAOTOffsets monoCrossAOTTargetOS: - android - browser @@ -1272,9 +1292,9 @@ extends: nameSuffix: CrossAOT_Mono runtimeVariant: crossaot dependsOn: - - mono_android_offsets - - mono_browser_offsets - - mono_wasi_offsets + - build_android_x64_release_MonoAOTOffsets + - build_browser_wasm_linux_release_MonoAOTOffsets + - build_wasi_wasm_linux_release_MonoAOTOffsets monoCrossAOTTargetOS: - android - browser @@ -1303,12 +1323,12 @@ extends: nameSuffix: CrossAOT_Mono runtimeVariant: crossaot dependsOn: - - mono_android_offsets - - mono_browser_offsets - - mono_wasi_offsets - - mono_tvos_offsets - - mono_ios_offsets - - mono_maccatalyst_offsets + - build_android_x64_release_MonoAOTOffsets + - build_browser_wasm_linux_release_MonoAOTOffsets + - build_wasi_wasm_linux_release_MonoAOTOffsets + - build_tvos_arm64_release_MonoAOTOffsets + - build_ios_arm64_release_MonoAOTOffsets + - build_maccatalyst_x64_release_MonoAOTOffsets monoCrossAOTTargetOS: - android - browser diff --git a/eng/pipelines/runtimelab-official.yml b/eng/pipelines/runtimelab-official.yml new file mode 100644 index 00000000000000..84a8bd69258d5c --- /dev/null +++ b/eng/pipelines/runtimelab-official.yml @@ -0,0 +1,78 @@ +trigger: + batch: true + branches: + include: + - feature/* + paths: + include: + - '*' + exclude: + - '**.md' + - eng/Version.Details.xml + - .devcontainer/* + - .github/* + - docs/* + - LICENSE.TXT + - PATENTS.TXT + - THIRD-PARTY-NOTICES.TXT + +variables: +- template: /eng/pipelines/common/variables.yml + parameters: + templatePath: 'templates-official' + +- ${{ if and(ne(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}: + - name: TeamName + value: dotnet-core +extends: + template: /eng/pipelines/common/templates/pipeline-with-resources.yml@self + parameters: + isOfficialBuild: true + stages: + - stage: Build + jobs: + # + # Build the whole product with Release CoreCLR + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: release + platforms: + - linux_x64 + - windows_x64 + jobParameters: + templatePath: 'templates-official' + isOfficialBuild: true + timeoutInMinutes: 180 + buildArgs: -s clr+libs+hosts+packs -c $(_BuildConfig) + postBuildSteps: + # Upload the results. + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: $(osGroup)$(osSubgroup)_$(archType) + + # + # Build libraries AllConfigurations for packages + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: Release + platforms: + - windows_x64 + jobParameters: + templatePath: 'templates-official' + buildArgs: -s tools+libs -allConfigurations -c $(_BuildConfig) /p:TestAssemblies=false /p:TestPackages=true + nameSuffix: Libraries_AllConfigurations + isOfficialBuild: true + postBuildSteps: + - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml + parameters: + name: Libraries_AllConfigurations + timeoutInMinutes: 95 + + - template: /eng/pipelines/official/stages/publish.yml + parameters: + isOfficialBuild: true diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml index 0fe01fd2816f73..7e0aaeab207216 100644 --- a/eng/pipelines/runtimelab.yml +++ b/eng/pipelines/runtimelab.yml @@ -49,103 +49,56 @@ extends: stages: - stage: Build jobs: - - ${{ if ne(variables.isOfficialBuild, true) }}: - # - # Build the whole product with Checked CoreCLR and run runtime tests - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml - buildConfig: checked - platforms: - - linux_x64 - - windows_x64 - jobParameters: - timeoutInMinutes: 200 - buildArgs: -s clr+libs+hosts+packs -c debug -rc $(_BuildConfig) - postBuildSteps: - - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml - parameters: - creator: dotnet-bot - testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) + # + # Build the whole product with Checked CoreCLR and run runtime tests + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + buildConfig: checked + platforms: + - linux_x64 + - windows_x64 + jobParameters: + timeoutInMinutes: 200 + buildArgs: -s clr+libs+hosts+packs -c debug -rc $(_BuildConfig) + postBuildSteps: + - template: /eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig) - # - # Build the whole product with Release CoreCLR and run libraries tests - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: release - platforms: - - linux_x64 - - windows_x64 - jobParameters: - timeoutInMinutes: 180 - buildArgs: -s clr+libs+libs.tests+hosts+packs -c $(_BuildConfig) /p:ArchiveTests=true - postBuildSteps: - - template: /eng/pipelines/libraries/helix.yml - parameters: - creator: dotnet-bot - testRunNamePrefixSuffix: Libraries_$(_BuildConfig) + # + # Build the whole product with Release CoreCLR and run libraries tests + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: release + platforms: + - linux_x64 + - windows_x64 + jobParameters: + timeoutInMinutes: 180 + buildArgs: -s clr+libs+libs.tests+hosts+packs -c $(_BuildConfig) /p:ArchiveTests=true + postBuildSteps: + - template: /eng/pipelines/libraries/helix.yml + parameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Libraries_$(_BuildConfig) - # - # Build and test libraries AllConfigurations - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} - platforms: - - windows_x64 - jobParameters: - buildArgs: -test -s tools+libs+libs.tests -allConfigurations -c $(_BuildConfig) /p:TestAssemblies=false /p:TestPackages=true - nameSuffix: Libraries_AllConfigurations - timeoutInMinutes: 150 - - - ${{ else }}: - # - # Build the whole product with Release CoreCLR - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml - buildConfig: release - platforms: - - linux_x64 - - windows_x64 - jobParameters: - isOfficialBuild: true - timeoutInMinutes: 180 - buildArgs: -s clr+libs+hosts+packs -c $(_BuildConfig) - postBuildSteps: - # Upload the results. - - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - parameters: - name: $(osGroup)$(osSubgroup)_$(archType) - - # - # Build libraries AllConfigurations for packages - # - - template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/global-build-job.yml - buildConfig: Release - platforms: - - windows_x64 - jobParameters: - buildArgs: -s tools+libs -allConfigurations -c $(_BuildConfig) /p:TestAssemblies=false /p:TestPackages=true - nameSuffix: Libraries_AllConfigurations - isOfficialBuild: true - postBuildSteps: - - template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml - parameters: - name: Libraries_AllConfigurations - timeoutInMinutes: 95 - - - ${{ if eq(variables.isOfficialBuild, true) }}: - - template: /eng/pipelines/official/stages/publish.yml - parameters: - isOfficialBuild: true \ No newline at end of file + # + # Build and test libraries AllConfigurations + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + platforms: + - windows_x64 + jobParameters: + buildArgs: -test -s tools+libs+libs.tests -allConfigurations -c $(_BuildConfig) /p:TestAssemblies=false /p:TestPackages=true + nameSuffix: Libraries_AllConfigurations + timeoutInMinutes: 150 diff --git a/eng/testing/BrowserVersions.props b/eng/testing/BrowserVersions.props index b1e85302a8ed3a..c66b61a6e44042 100644 --- a/eng/testing/BrowserVersions.props +++ b/eng/testing/BrowserVersions.props @@ -8,7 +8,9 @@ 1250580 https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1250586 12.3.219 - 124.0.2 + 125.0.1 0.34.0 + 125.0.1 + 0.34.0 diff --git a/eng/testing/WasmRunnerTemplate.cmd b/eng/testing/WasmRunnerTemplate.cmd index 0c7f3dc2195d26..e043ce7a34e9f5 100644 --- a/eng/testing/WasmRunnerTemplate.cmd +++ b/eng/testing/WasmRunnerTemplate.cmd @@ -30,7 +30,11 @@ if [%XHARNESS_COMMAND%] == [] ( if /I [%SCENARIO%]==[WasmTestOnChrome] ( set XHARNESS_COMMAND=test-browser ) else ( - set XHARNESS_COMMAND=test + if /I [%SCENARIO%]==[WasmTestOnFirefox] ( + set XHARNESS_COMMAND=test-browser + ) else ( + set XHARNESS_COMMAND=test + ) ) ) @@ -56,11 +60,25 @@ if /I [%XHARNESS_COMMAND%] == [test] ( ) ) ) else ( - if [%BROWSER_PATH%] == [] if not [%HELIX_CORRELATION_PAYLOAD%] == [] ( - set "BROWSER_PATH=--browser-path^=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe" - ) - if [%JS_ENGINE_ARGS%] == [] ( - set "JS_ENGINE_ARGS=--browser-arg^=--js-flags^=--stack-trace-limit^=1000" + if /I [%SCENARIO%] == [WasmTestOnChrome] ( + if [%BROWSER_PATH%] == [] if not [%HELIX_CORRELATION_PAYLOAD%] == [] ( + set "BROWSER_PATH=--browser-path^=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe" + ) + if [%JS_ENGINE_ARGS%] == [] ( + set "JS_ENGINE_ARGS=--browser-arg^=--js-flags^=--stack-trace-limit^=1000" + ) + ) else ( + if /I [%SCENARIO%] == [WasmTestOnFirefox] ( + if [%BROWSER_PATH%] == [] if not [%HELIX_CORRELATION_PAYLOAD%] == [] ( + set "BROWSER_PATH=--browser-path^=%HELIX_CORRELATION_PAYLOAD%\firefox\firefox.exe" + ) + if [%JS_ENGINE%] == [] ( + set "JS_ENGINE=--browser^=Firefox" + ) + if [%JS_ENGINE_ARGS%] == [] ( + set "JS_ENGINE_ARGS=--browser-arg^=-private-window" + ) + ) ) ) diff --git a/eng/testing/WasmRunnerTemplate.sh b/eng/testing/WasmRunnerTemplate.sh index bd7f1faadf3556..6cf4dc11d4beae 100644 --- a/eng/testing/WasmRunnerTemplate.sh +++ b/eng/testing/WasmRunnerTemplate.sh @@ -26,7 +26,9 @@ else fi if [[ -z "$XHARNESS_COMMAND" ]]; then - if [[ "$SCENARIO" == "WasmTestOnChrome" || "$SCENARIO" == "wasmtestonchrome" ]]; then + if [[ "$SCENARIO" == "WasmTestOnFirefox" || "$SCENARIO" == "wasmtestonfirefox" ]]; then + XHARNESS_COMMAND="test-browser" + elif [[ "$SCENARIO" == "WasmTestOnChrome" || "$SCENARIO" == "wasmtestonchrome" ]]; then XHARNESS_COMMAND="test-browser" else XHARNESS_COMMAND="test" @@ -59,8 +61,17 @@ if [[ "$XHARNESS_COMMAND" == "test" ]]; then fi fi else - if [[ -z "$JS_ENGINE_ARGS" ]]; then - JS_ENGINE_ARGS="--browser-arg=--js-flags=--stack-trace-limit=1000" + if [[ "$SCENARIO" == "WasmTestOnChrome" || "$SCENARIO" == "wasmtestonchrome" ]]; then + if [[ -z "$JS_ENGINE_ARGS" ]]; then + JS_ENGINE_ARGS="--browser-arg=--js-flags=--stack-trace-limit=1000" + fi + elif [[ "$SCENARIO" == "WasmTestOnFirefox" || "$SCENARIO" == "wasmtestonfirefox" ]]; then + if [[ -z "$JS_ENGINE" ]]; then + JS_ENGINE="--browser=Firefox" + fi + if [[ -z "$JS_ENGINE_ARGS" ]]; then + JS_ENGINE_ARGS="--browser-arg=-private-window" + fi fi fi diff --git a/eng/testing/linker/SupportFiles/Directory.Build.props b/eng/testing/linker/SupportFiles/Directory.Build.props index 5a54c83e569231..4e33801ab12837 100644 --- a/eng/testing/linker/SupportFiles/Directory.Build.props +++ b/eng/testing/linker/SupportFiles/Directory.Build.props @@ -11,6 +11,7 @@ false true + true $(NoWarn);IL2121 diff --git a/eng/testing/linker/trimmingTests.props b/eng/testing/linker/trimmingTests.props index b917cd5fe38268..b822294a93d04c 100644 --- a/eng/testing/linker/trimmingTests.props +++ b/eng/testing/linker/trimmingTests.props @@ -1,6 +1,8 @@ - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'trimmingTests')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'trimmingTests')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'aotTests')) + $([MSBuild]::NormalizeDirectory('$(TrimmingTestDir)', 'projects')) $(MSBuildThisFileDirectory)project.csproj.template true diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets index 926bafa52cfef4..d474e19b69accd 100644 --- a/eng/testing/linker/trimmingTests.targets +++ b/eng/testing/linker/trimmingTests.targets @@ -38,7 +38,13 @@ - + <_SkippedAppSourceFiles Include="@(TestConsoleAppSourceFiles)" Condition="$([System.String]::Copy('%(TestConsoleAppSourceFiles.SkipOnTestRuntimes)').Contains('$(PackageRID)'))" /> + + <_SkippedAppSourceFiles Include="@(TestConsoleAppSourceFiles)" Condition="'$(RunNativeAotTestApps)' == 'true' and '%(TestConsoleAppSourceFiles.NativeAotIncompatible)' == 'true'" /> + + <_AppSourceFiles Include="@(TestConsoleAppSourceFiles)" Exclude="@(_SkippedAppSourceFiles)" /> + + %(FullPath) @@ -81,6 +87,9 @@ <_additionalPropertiesString>@(_propertiesAsItems->'<%(Identity)>%(Value)</%(Identity)>', '%0a ') + + + + Properties="Configuration=$(Configuration);BuildProjectReferences=false;TargetOS=$(TargetOS);TargetArchitecture=$(TargetArchitecture);_IsPublishing=true" /> + WasmTestOnV8 @(_NodeNpmModuleStringTrimmed, ',') + + diff --git a/eng/testing/tests.wasi.targets b/eng/testing/tests.wasi.targets index d147fea218fe4a..e8f75ee3821bc5 100644 --- a/eng/testing/tests.wasi.targets +++ b/eng/testing/tests.wasi.targets @@ -46,7 +46,7 @@ <_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode) <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs) <_XHarnessArgs Condition="'$(WasmXHarnessTestsTimeout)' != ''" >$(_XHarnessArgs) "--timeout=$(WasmXHarnessTestsTimeout)" - <_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--max-wasm-stack=134217728 + <_XHarnessArgs >$(_XHarnessArgs) --engine-arg=-W --engine-arg=max-wasm-stack=134217728 <_XHarnessArgs Condition="'$(WasmXHarnessArgsCli)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgsCli) <_InvariantGlobalization Condition="'$(InvariantGlobalization)' == 'true'">--env=DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true @@ -147,6 +147,13 @@ + + WasmTestOnWasmtime + + + diff --git a/eng/testing/wasm-provisioning.targets b/eng/testing/wasm-provisioning.targets index 47076a23770dd3..540fcfb035fa21 100644 --- a/eng/testing/wasm-provisioning.targets +++ b/eng/testing/wasm-provisioning.targets @@ -21,18 +21,30 @@ - - https://ftp.mozilla.org/pub/firefox/releases/$(linux_FirefoxRevision)/linux-x86_64/en-US/firefox-$(linux_FirefoxRevision).tar.bz2 - https://github.com/mozilla/geckodriver/releases/download/v$(linux_GeckoDriverRevision)/geckodriver-v$(linux_GeckoDriverRevision)-linux64.tar.gz - firefox - geckodriver + $(ArtifactsBinDir)firefox\ firefox geckodriver $(ArtifactsBinDir)geckodriver\ + + + https://ftp.mozilla.org/pub/firefox/releases/$(linux_FirefoxRevision)/linux-x86_64/en-US/firefox-$(linux_FirefoxRevision).tar.bz2 + https://github.com/mozilla/geckodriver/releases/download/v$(linux_GeckoDriverRevision)/geckodriver-v$(linux_GeckoDriverRevision)-linux64.tar.gz + firefox + geckodriver $([MSBuild]::NormalizePath($(FirefoxDir), '.install-firefox-$(linux_FirefoxRevision).stamp')) $([MSBuild]::NormalizePath($(GeckoDriverDir), '.install-geckodriver-$(linux_GeckoDriverRevision).stamp')) + $([MSBuild]::NormalizePath($(FirefoxDir), $(FirefoxDirName), $(FirefoxBinaryName))) + $([MSBuild]::NormalizePath($(GeckoDriverDir), $(GeckoDriverDirName), $(GeckoDriverBinaryName))) + + + https://ftp.mozilla.org/pub/firefox/releases/$(win_FirefoxRevision)/win64/en-US/Firefox%20Setup%20$(win_FirefoxRevision).exe + https://github.com/mozilla/geckodriver/releases/download/v$(win_GeckoDriverRevision)/geckodriver-v$(win_GeckoDriverRevision)-win64.zip + firefox.exe + geckodriver.exe + $([MSBuild]::NormalizePath($(FirefoxDir), '.install-firefox-$(win_FirefoxRevision).stamp')) + $([MSBuild]::NormalizePath($(GeckoDriverDir), '.install-geckodriver-$(win_GeckoDriverRevision).stamp')) $([MSBuild]::NormalizePath($(FirefoxDir), $(FirefoxDirName), $(FirefoxBinaryName))) $([MSBuild]::NormalizePath($(GeckoDriverDir), $(GeckoDriverDirName), $(GeckoDriverBinaryName))) @@ -183,7 +195,7 @@ export __SCRIPT_DIR=%24( cd -- "%24( dirname -- "%24{BASH_SOURCE[0]}" )" &> + Condition="!Exists($(FirefoxStampFile)) and '$(InstallFirefoxForTests)' == 'true'"> <_StampFile Include="$(_BrowserStampDir).install-firefox*.stamp" /> @@ -197,24 +209,22 @@ export __SCRIPT_DIR=%24( cd -- "%24( dirname -- "%24{BASH_SOURCE[0]}" )" &> - - - - - <_FirefoxBinaryPath>$([MSBuild]::NormalizePath($(FirefoxDir), $(FirefoxBinaryName))) - + + + + - + - + + Condition="!Exists($(GeckoDriverStampFile)) and '$(InstallFirefoxForTests)' == 'true'"> <_StampFile Include="$(_BrowserStampDir).install-geckodriver*.stamp" /> @@ -228,18 +238,15 @@ export __SCRIPT_DIR=%24( cd -- "%24( dirname -- "%24{BASH_SOURCE[0]}" )" &> - - - - - - <_GeckoDriverBinaryPath>$([MSBuild]::NormalizePath($(GeckoDriverDir), $(GeckoDriverBinaryName))) - + + + + - + - + diff --git a/global.json b/global.json index 4348e778e29b42..a62f147f01c51e 100644 --- a/global.json +++ b/global.json @@ -8,11 +8,11 @@ "dotnet": "9.0.100-preview.3.24204.13" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24217.1", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24217.1", - "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24217.1", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24253.1", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24253.1", + "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24253.1", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", - "Microsoft.NET.Sdk.IL": "9.0.0-preview.4.24215.1" + "Microsoft.NET.Sdk.IL": "9.0.0-preview.4.24229.1" } } diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt index aaf4005aa7394b..7ed0d509212cc4 100644 --- a/src/coreclr/CMakeLists.txt +++ b/src/coreclr/CMakeLists.txt @@ -206,6 +206,7 @@ if(CLR_CMAKE_HOST_UNIX) # warnings and errors to be suppressed. # Suppress these warnings here to avoid breaking the build. add_compile_options($<$:-Wno-null-arithmetic>) + add_compile_options($<$:-Wno-sync-alignment>) add_compile_options($<$:-Wno-conversion-null>) add_compile_options($<$:-Wno-pointer-arith>) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs index de7b3021c458fe..74e07398481681 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs @@ -694,7 +694,7 @@ public ArrayInitializeCache(RuntimeType arrayType) // it for type and executes it. // // The "T" will reflect the interface used to invoke the method. The actual runtime "this" will be - // array that is castable to "T[]" (i.e. for primitivs and valuetypes, it will be exactly + // array that is castable to "T[]" (i.e. for primitives and valuetypes, it will be exactly // "T[]" - for orefs, it may be a "U[]" where U derives from T.) //---------------------------------------------------------------------------------------- internal sealed class SZArrayHelper diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs index d1944cbbf77ceb..6f74dde91fe7e0 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs @@ -171,39 +171,42 @@ public static bool IsTokenOfType(int token, params MetadataTokenType[] types) public override string ToString() => string.Create(CultureInfo.InvariantCulture, stackalloc char[64], $"0x{Value:x8}"); } - internal unsafe struct MetadataEnumResult + internal ref struct MetadataEnumResult { - // Keep the definition in sync with vm\ManagedMdImport.hpp - private int[] largeResult; - private int length; - private fixed int smallResult[16]; + internal int _length; + + internal const int SmallIntArrayLength = 16; + + [InlineArray(SmallIntArrayLength)] + internal struct SmallIntArray + { + public int e; + } + internal SmallIntArray _smallResult; + internal int[]? _largeResult; - public int Length => length; + public int Length => _length; public int this[int index] { get { Debug.Assert(0 <= index && index < Length); - if (largeResult != null) - return largeResult[index]; + if (_largeResult != null) + return _largeResult[index]; - fixed (int* p = smallResult) - return p[index]; + return _smallResult[index]; } } } #pragma warning disable CA1066 // IEquatable interface implementation isn't used - internal readonly struct MetadataImport + internal readonly partial struct MetadataImport #pragma warning restore CA1067 { private readonly IntPtr m_metadataImport2; - private readonly object? m_keepalive; #region Override methods from Object - internal static readonly MetadataImport EmptyImport = new MetadataImport((IntPtr)0, null); - public override int GetHashCode() { return HashCode.Combine(m_metadataImport2); @@ -225,47 +228,104 @@ private bool Equals(MetadataImport import) #region Static Members [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetMarshalAs(IntPtr pNativeType, int cNativeType, out int unmanagedType, out int safeArraySubType, out string? safeArrayUserDefinedSubType, - out int arraySubType, out int sizeParamIndex, out int sizeConst, out string? marshalType, out string? marshalCookie, + private static extern unsafe bool GetMarshalAs( + IntPtr pNativeType, + int cNativeType, + out int unmanagedType, + out int safeArraySubType, + out byte* safeArrayUserDefinedSubType, + out int arraySubType, + out int sizeParamIndex, + out int sizeConst, + out byte* marshalType, + out byte* marshalCookie, out int iidParamIndex); - internal static void GetMarshalAs(ConstArray nativeType, - out UnmanagedType unmanagedType, out VarEnum safeArraySubType, out string? safeArrayUserDefinedSubType, - out UnmanagedType arraySubType, out int sizeParamIndex, out int sizeConst, out string? marshalType, out string? marshalCookie, - out int iidParamIndex) - { - _GetMarshalAs(nativeType.Signature, (int)nativeType.Length, - out int _unmanagedType, out int _safeArraySubType, out safeArrayUserDefinedSubType, - out int _arraySubType, out sizeParamIndex, out sizeConst, out marshalType, out marshalCookie, - out iidParamIndex); - unmanagedType = (UnmanagedType)_unmanagedType; - safeArraySubType = (VarEnum)_safeArraySubType; - arraySubType = (UnmanagedType)_arraySubType; - } - #endregion + internal static unsafe MarshalAsAttribute GetMarshalAs(ConstArray nativeType, RuntimeModule scope) + { + if (!GetMarshalAs( + nativeType.Signature, + nativeType.Length, + out int unmanagedTypeRaw, + out int safeArraySubTypeRaw, + out byte* safeArrayUserDefinedSubTypeRaw, + out int arraySubTypeRaw, + out int sizeParamIndex, + out int sizeConst, + out byte* marshalTypeRaw, + out byte* marshalCookieRaw, + out int iidParamIndex)) + { + throw new BadImageFormatException(); + } - #region Internal Static Members - internal static void ThrowError(int hResult) - { - throw new MetadataException(hResult); + string? safeArrayUserDefinedTypeName = safeArrayUserDefinedSubTypeRaw == null + ? null + : Text.Encoding.UTF8.GetString(MemoryMarshal.CreateReadOnlySpanFromNullTerminated(safeArrayUserDefinedSubTypeRaw)); + string? marshalTypeName = marshalTypeRaw == null + ? null + : Text.Encoding.UTF8.GetString(MemoryMarshal.CreateReadOnlySpanFromNullTerminated(marshalTypeRaw)); + string? marshalCookie = marshalCookieRaw == null + ? null + : Text.Encoding.UTF8.GetString(MemoryMarshal.CreateReadOnlySpanFromNullTerminated(marshalCookieRaw)); + + RuntimeType? safeArrayUserDefinedType = string.IsNullOrEmpty(safeArrayUserDefinedTypeName) ? null : + TypeNameParser.GetTypeReferencedByCustomAttribute(safeArrayUserDefinedTypeName, scope); + RuntimeType? marshalTypeRef = null; + + try + { + marshalTypeRef = marshalTypeName is null ? null : TypeNameParser.GetTypeReferencedByCustomAttribute(marshalTypeName, scope); + } + catch (TypeLoadException) + { + // The user may have supplied a bad type name string causing this TypeLoadException + // Regardless, we return the bad type name + Debug.Assert(marshalTypeName is not null); + } + + MarshalAsAttribute attribute = new MarshalAsAttribute((UnmanagedType)unmanagedTypeRaw); + + attribute.SafeArraySubType = (VarEnum)safeArraySubTypeRaw; + attribute.SafeArrayUserDefinedSubType = safeArrayUserDefinedType; + attribute.IidParameterIndex = iidParamIndex; + attribute.ArraySubType = (UnmanagedType)arraySubTypeRaw; + attribute.SizeParamIndex = (short)sizeParamIndex; + attribute.SizeConst = sizeConst; + attribute.MarshalType = marshalTypeName; + attribute.MarshalTypeRef = marshalTypeRef; + attribute.MarshalCookie = marshalCookie; + + return attribute; } #endregion #region Constructor - internal MetadataImport(IntPtr metadataImport2, object? keepalive) + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern unsafe IntPtr GetMetadataImport(RuntimeModule module); + + internal MetadataImport(RuntimeModule module) { - m_metadataImport2 = metadataImport2; - m_keepalive = keepalive; + ArgumentNullException.ThrowIfNull(module); + + // The MetadataImport instance needs to be acquired in this manner + // since the instance can be replaced during HotReload and EnC scenarios. + m_metadataImport2 = GetMetadataImport(module); } #endregion - #region FCalls - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _Enum(IntPtr scope, int type, int parent, out MetadataEnumResult result); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MetadataImport_Enum")] + private static unsafe partial void Enum(IntPtr scope, int type, int parent, ref int length, int* shortResult, ObjectHandleOnStack longResult); - public void Enum(MetadataTokenType type, int parent, out MetadataEnumResult result) + public unsafe void Enum(MetadataTokenType type, int parent, out MetadataEnumResult result) { - _Enum(m_metadataImport2, (int)type, parent, out result); + result = default; + int length = MetadataEnumResult.SmallIntArrayLength; + fixed (int* p = &result._smallResult.e) + { + Enum(m_metadataImport2, (int)type, parent, ref length, p, ObjectHandleOnStack.Create(ref result._largeResult)); + } + result._length = length; } public void EnumNestedTypes(int mdTypeDef, out MetadataEnumResult result) @@ -298,117 +358,131 @@ public void EnumEvents(int mdTypeDef, out MetadataEnumResult result) Enum(MetadataTokenType.Event, mdTypeDef, out result); } + private static unsafe string? ConvertMetadataStringPermitInvalidContent(char* stringMetadataEncoding, int length) + { + Debug.Assert(stringMetadataEncoding != null); + // Metadata encoding is always UTF-16LE, but user strings can be leveraged to encode invalid surrogates. + // This means we rely on the string's constructor rather than the stricter Encoding.Unicode API. + return new string(stringMetadataEncoding, 0, length); + } + + #region FCalls [MethodImpl(MethodImplOptions.InternalCall)] - private static extern string? _GetDefaultValue(IntPtr scope, int mdToken, out long value, out int length, out int corElementType); - public string? GetDefaultValue(int mdToken, out long value, out int length, out CorElementType corElementType) + private static extern unsafe int GetDefaultValue( + IntPtr scope, + int mdToken, + out long value, + out char* stringMetadataEncoding, + out int length, + out int corElementType); + + public unsafe string? GetDefaultValue(int mdToken, out long value, out int length, out CorElementType corElementType) { - string? stringVal = _GetDefaultValue(m_metadataImport2, mdToken, out value, out length, out int _corElementType); - corElementType = (CorElementType)_corElementType; - return stringVal; + ThrowBadImageExceptionForHR(GetDefaultValue(m_metadataImport2, mdToken, out value, out char* stringMetadataEncoding, out length, out int corElementTypeRaw)); + + corElementType = (CorElementType)corElementTypeRaw; + + if (corElementType is CorElementType.ELEMENT_TYPE_STRING + && stringMetadataEncoding != null) + { + return ConvertMetadataStringPermitInvalidContent(stringMetadataEncoding, length); + } + + return null; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe void _GetUserString(IntPtr scope, int mdToken, void** name, out int length); + private static extern unsafe int GetUserString(IntPtr scope, int mdToken, out char* stringMetadataEncoding, out int length); + public unsafe string? GetUserString(int mdToken) { - void* name; - _GetUserString(m_metadataImport2, mdToken, &name, out int length); + ThrowBadImageExceptionForHR(GetUserString(m_metadataImport2, mdToken, out char* stringMetadataEncoding, out int length)); - return name != null ? - new string((char*)name, 0, length) : + return stringMetadataEncoding != null ? + ConvertMetadataStringPermitInvalidContent(stringMetadataEncoding, length) : null; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe void _GetName(IntPtr scope, int mdToken, void** name); + private static extern unsafe int GetName(IntPtr scope, int mdToken, out byte* name); + public unsafe MdUtf8String GetName(int mdToken) { - void* name; - _GetName(m_metadataImport2, mdToken, &name); - + ThrowBadImageExceptionForHR(GetName(m_metadataImport2, mdToken, out byte* name)); return new MdUtf8String(name); } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe void _GetNamespace(IntPtr scope, int mdToken, void** namesp); + private static extern unsafe int GetNamespace(IntPtr scope, int mdToken, out byte* namesp); + public unsafe MdUtf8String GetNamespace(int mdToken) { - void* namesp; - _GetNamespace(m_metadataImport2, mdToken, &namesp); - + ThrowBadImageExceptionForHR(GetNamespace(m_metadataImport2, mdToken, out byte* namesp)); return new MdUtf8String(namesp); } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe void _GetEventProps(IntPtr scope, int mdToken, void** name, out int eventAttributes); + private static extern unsafe int GetEventProps(IntPtr scope, int mdToken, out void* name, out int eventAttributes); + public unsafe void GetEventProps(int mdToken, out void* name, out EventAttributes eventAttributes) { - void* _name; - _GetEventProps(m_metadataImport2, mdToken, &_name, out int _eventAttributes); - name = _name; - eventAttributes = (EventAttributes)_eventAttributes; + ThrowBadImageExceptionForHR(GetEventProps(m_metadataImport2, mdToken, out name, out int eventAttributesRaw)); + eventAttributes = (EventAttributes)eventAttributesRaw; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetFieldDefProps(IntPtr scope, int mdToken, out int fieldAttributes); + private static extern int GetFieldDefProps(IntPtr scope, int mdToken, out int fieldAttributes); + public void GetFieldDefProps(int mdToken, out FieldAttributes fieldAttributes) { - _GetFieldDefProps(m_metadataImport2, mdToken, out int _fieldAttributes); - fieldAttributes = (FieldAttributes)_fieldAttributes; + ThrowBadImageExceptionForHR(GetFieldDefProps(m_metadataImport2, mdToken, out int fieldAttributesRaw)); + fieldAttributes = (FieldAttributes)fieldAttributesRaw; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe void _GetPropertyProps(IntPtr scope, - int mdToken, void** name, out int propertyAttributes, out ConstArray signature); + private static extern unsafe int GetPropertyProps(IntPtr scope, int mdToken, out void* name, out int propertyAttributes, out ConstArray signature); + public unsafe void GetPropertyProps(int mdToken, out void* name, out PropertyAttributes propertyAttributes, out ConstArray signature) { - void* _name; - _GetPropertyProps(m_metadataImport2, mdToken, &_name, out int _propertyAttributes, out signature); - name = _name; - propertyAttributes = (PropertyAttributes)_propertyAttributes; + ThrowBadImageExceptionForHR(GetPropertyProps(m_metadataImport2, mdToken, out name, out int propertyAttributesRaw, out signature)); + propertyAttributes = (PropertyAttributes)propertyAttributesRaw; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetParentToken(IntPtr scope, - int mdToken, out int tkParent); + private static extern int GetParentToken(IntPtr scope, int mdToken, out int tkParent); + public int GetParentToken(int tkToken) { - _GetParentToken(m_metadataImport2, tkToken, out int tkParent); + ThrowBadImageExceptionForHR(GetParentToken(m_metadataImport2, tkToken, out int tkParent)); return tkParent; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetParamDefProps(IntPtr scope, - int parameterToken, out int sequence, out int attributes); + private static extern int GetParamDefProps(IntPtr scope, int parameterToken, out int sequence, out int attributes); + public void GetParamDefProps(int parameterToken, out int sequence, out ParameterAttributes attributes) { - - _GetParamDefProps(m_metadataImport2, parameterToken, out sequence, out int _attributes); - - attributes = (ParameterAttributes)_attributes; + ThrowBadImageExceptionForHR(GetParamDefProps(m_metadataImport2, parameterToken, out sequence, out int attributesRaw)); + attributes = (ParameterAttributes)attributesRaw; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetGenericParamProps(IntPtr scope, - int genericParameter, - out int flags); + private static extern int GetGenericParamProps(IntPtr scope, int genericParameter, out int flags); public void GetGenericParamProps( int genericParameter, out GenericParameterAttributes attributes) { - _GetGenericParamProps(m_metadataImport2, genericParameter, out int _attributes); - attributes = (GenericParameterAttributes)_attributes; + ThrowBadImageExceptionForHR(GetGenericParamProps(m_metadataImport2, genericParameter, out int attributesRaw)); + attributes = (GenericParameterAttributes)attributesRaw; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetScopeProps(IntPtr scope, - out Guid mvid); + private static extern int GetScopeProps(IntPtr scope, out Guid mvid); - public void GetScopeProps( - out Guid mvid) + public void GetScopeProps(out Guid mvid) { - _GetScopeProps(m_metadataImport2, out mvid); + ThrowBadImageExceptionForHR(GetScopeProps(m_metadataImport2, out mvid)); } public ConstArray GetMethodSignature(MetadataToken token) @@ -420,47 +494,36 @@ public ConstArray GetMethodSignature(MetadataToken token) } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetSigOfMethodDef(IntPtr scope, - int methodToken, - ref ConstArray signature); + private static extern int GetSigOfMethodDef(IntPtr scope, int methodToken, ref ConstArray signature); public ConstArray GetSigOfMethodDef(int methodToken) { ConstArray signature = default; - - _GetSigOfMethodDef(m_metadataImport2, methodToken, ref signature); - + ThrowBadImageExceptionForHR(GetSigOfMethodDef(m_metadataImport2, methodToken, ref signature)); return signature; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetSignatureFromToken(IntPtr scope, - int methodToken, - ref ConstArray signature); + private static extern int GetSignatureFromToken(IntPtr scope, int methodToken, ref ConstArray signature); public ConstArray GetSignatureFromToken(int token) { ConstArray signature = default; - - _GetSignatureFromToken(m_metadataImport2, token, ref signature); - + ThrowBadImageExceptionForHR(GetSignatureFromToken(m_metadataImport2, token, ref signature)); return signature; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetMemberRefProps(IntPtr scope, - int memberTokenRef, - out ConstArray signature); + private static extern int GetMemberRefProps(IntPtr scope, int memberTokenRef, out ConstArray signature); public ConstArray GetMemberRefProps(int memberTokenRef) { - _GetMemberRefProps(m_metadataImport2, memberTokenRef, out ConstArray signature); - + ThrowBadImageExceptionForHR(GetMemberRefProps(m_metadataImport2, memberTokenRef, out ConstArray signature)); return signature; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetCustomAttributeProps(IntPtr scope, + private static extern int GetCustomAttributeProps(IntPtr scope, int customAttributeToken, out int constructorToken, out ConstArray signature); @@ -470,66 +533,62 @@ public void GetCustomAttributeProps( out int constructorToken, out ConstArray signature) { - _GetCustomAttributeProps(m_metadataImport2, customAttributeToken, - out constructorToken, out signature); + ThrowBadImageExceptionForHR(GetCustomAttributeProps(m_metadataImport2, customAttributeToken, out constructorToken, out signature)); } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetClassLayout(IntPtr scope, - int typeTokenDef, out int packSize, out int classSize); + private static extern int GetClassLayout(IntPtr scope, int typeTokenDef, out int packSize, out int classSize); + public void GetClassLayout( int typeTokenDef, out int packSize, out int classSize) { - _GetClassLayout(m_metadataImport2, typeTokenDef, out packSize, out classSize); + ThrowBadImageExceptionForHR(GetClassLayout(m_metadataImport2, typeTokenDef, out packSize, out classSize)); } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern bool _GetFieldOffset(IntPtr scope, - int typeTokenDef, int fieldTokenDef, out int offset); + private static extern int GetFieldOffset(IntPtr scope, int typeTokenDef, int fieldTokenDef, out int offset, out bool found); + public bool GetFieldOffset( int typeTokenDef, int fieldTokenDef, out int offset) { - return _GetFieldOffset(m_metadataImport2, typeTokenDef, fieldTokenDef, out offset); + int hr = GetFieldOffset(m_metadataImport2, typeTokenDef, fieldTokenDef, out offset, out bool found); + if (!found && hr < 0) + { + throw new BadImageFormatException(); + } + return found; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetSigOfFieldDef(IntPtr scope, - int fieldToken, - ref ConstArray fieldMarshal); + private static extern int GetSigOfFieldDef(IntPtr scope, int fieldToken, ref ConstArray fieldMarshal); public ConstArray GetSigOfFieldDef(int fieldToken) { - ConstArray fieldMarshal = default; - - _GetSigOfFieldDef(m_metadataImport2, fieldToken, ref fieldMarshal); - - return fieldMarshal; + ConstArray sig = default; + ThrowBadImageExceptionForHR(GetSigOfFieldDef(m_metadataImport2, fieldToken, ref sig)); + return sig; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void _GetFieldMarshal(IntPtr scope, - int fieldToken, - ref ConstArray fieldMarshal); + private static extern int GetFieldMarshal(IntPtr scope, int fieldToken, ref ConstArray fieldMarshal); public ConstArray GetFieldMarshal(int fieldToken) { ConstArray fieldMarshal = default; - - _GetFieldMarshal(m_metadataImport2, fieldToken, ref fieldMarshal); - + ThrowBadImageExceptionForHR(GetFieldMarshal(m_metadataImport2, fieldToken, ref fieldMarshal)); return fieldMarshal; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe void _GetPInvokeMap(IntPtr scope, + private static extern unsafe int GetPInvokeMap(IntPtr scope, int token, out int attributes, - void** importName, - void** importDll); + out byte* importName, + out byte* importDll); public unsafe void GetPInvokeMap( int token, @@ -537,28 +596,28 @@ public unsafe void GetPInvokeMap( out string importName, out string importDll) { - void* _importName, _importDll; - _GetPInvokeMap(m_metadataImport2, token, out int _attributes, &_importName, &_importDll); - importName = new MdUtf8String(_importName).ToString(); - importDll = new MdUtf8String(_importDll).ToString(); + ThrowBadImageExceptionForHR(GetPInvokeMap(m_metadataImport2, token, out int attributesRaw, out byte* importNameRaw, out byte* importDllRaw)); - attributes = (PInvokeAttributes)_attributes; + importName = Text.Encoding.UTF8.GetString(MemoryMarshal.CreateReadOnlySpanFromNullTerminated(importNameRaw)); + importDll = Text.Encoding.UTF8.GetString(MemoryMarshal.CreateReadOnlySpanFromNullTerminated(importDllRaw)); + attributes = (PInvokeAttributes)attributesRaw; } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern bool _IsValidToken(IntPtr scope, int token); + private static extern bool IsValidToken(IntPtr scope, int token); + public bool IsValidToken(int token) { - return _IsValidToken(m_metadataImport2, token); + return IsValidToken(m_metadataImport2, token); } #endregion - } - - internal sealed class MetadataException : Exception - { - private readonly int m_hr; - internal MetadataException(int hr) { m_hr = hr; } - public override string ToString() => $"{nameof(MetadataException)} HResult = {m_hr:x}."; + private static void ThrowBadImageExceptionForHR(int hr) + { + if (hr < 0) + { + throw new BadImageFormatException(); + } + } } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs index dd0b5cf897f4d0..38663e57cde246 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs @@ -215,6 +215,7 @@ internal static CustomAttributeRecord[] GetCustomAttributeRecords(RuntimeModule scope.GetCustomAttributeProps(tkCustomAttributeTokens[i], out records[i].tkCtor.Value, out records[i].blob); } + GC.KeepAlive(module); return records; } @@ -250,13 +251,13 @@ internal static CustomAttributeTypedArgument Filter(IList a private RuntimeCustomAttributeData(RuntimeModule scope, MetadataToken caCtorToken, in ConstArray blob) { m_scope = scope; - m_ctor = (RuntimeConstructorInfo)RuntimeType.GetMethodBase(scope, caCtorToken)!; + m_ctor = (RuntimeConstructorInfo)RuntimeType.GetMethodBase(m_scope, caCtorToken)!; if (m_ctor!.DeclaringType!.IsGenericType) { - MetadataImport metadataScope = scope.MetadataImport; - Type attributeType = scope.ResolveType(metadataScope.GetParentToken(caCtorToken), null, null)!; - m_ctor = (RuntimeConstructorInfo)scope.ResolveMethod(caCtorToken, attributeType.GenericTypeArguments, null)!.MethodHandle.GetMethodInfo(); + MetadataImport metadataScope = m_scope.MetadataImport; + Type attributeType = m_scope.ResolveType(metadataScope.GetParentToken(caCtorToken), null, null)!; + m_ctor = (RuntimeConstructorInfo)m_scope.ResolveMethod(caCtorToken, attributeType.GenericTypeArguments, null)!.MethodHandle.GetMethodInfo(); } ReadOnlySpan parameters = m_ctor.GetParametersAsSpan(); @@ -1466,6 +1467,7 @@ private static bool IsCustomAttributeDefined( } } } + GC.KeepAlive(decoratedModule); return false; } @@ -1615,6 +1617,7 @@ private static void AddCustomAttributes( attributes.Add(attribute); } + GC.KeepAlive(decoratedModule); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", @@ -2194,10 +2197,11 @@ internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType? caType) if ((method.Attributes & MethodAttributes.PinvokeImpl) == 0) return null; - MetadataImport scope = ModuleHandle.GetMetadataImport(method.Module.ModuleHandle.GetRuntimeModule()); + RuntimeModule module = method.Module.ModuleHandle.GetRuntimeModule(); + MetadataImport scope = module.MetadataImport; int token = method.MetadataToken; - scope.GetPInvokeMap(token, out PInvokeAttributes flags, out string entryPoint, out string dllName); + GC.KeepAlive(module); CharSet charSet = CharSet.None; @@ -2252,51 +2256,25 @@ internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType? caType) private static MarshalAsAttribute? GetMarshalAsCustomAttribute(int token, RuntimeModule scope) { - ConstArray nativeType = ModuleHandle.GetMetadataImport(scope).GetFieldMarshal(token); + ConstArray nativeType = scope.MetadataImport.GetFieldMarshal(token); if (nativeType.Length == 0) return null; - MetadataImport.GetMarshalAs(nativeType, - out UnmanagedType unmanagedType, out VarEnum safeArraySubType, out string? safeArrayUserDefinedTypeName, out UnmanagedType arraySubType, out int sizeParamIndex, - out int sizeConst, out string? marshalTypeName, out string? marshalCookie, out int iidParamIndex); - - RuntimeType? safeArrayUserDefinedType = string.IsNullOrEmpty(safeArrayUserDefinedTypeName) ? null : - TypeNameParser.GetTypeReferencedByCustomAttribute(safeArrayUserDefinedTypeName, scope); - RuntimeType? marshalTypeRef = null; - - try - { - marshalTypeRef = marshalTypeName is null ? null : TypeNameParser.GetTypeReferencedByCustomAttribute(marshalTypeName, scope); - } - catch (TypeLoadException) - { - // The user may have supplied a bad type name string causing this TypeLoadException - // Regardless, we return the bad type name - Debug.Assert(marshalTypeName is not null); - } - - MarshalAsAttribute attribute = new MarshalAsAttribute(unmanagedType); - - attribute.SafeArraySubType = safeArraySubType; - attribute.SafeArrayUserDefinedSubType = safeArrayUserDefinedType; - attribute.IidParameterIndex = iidParamIndex; - attribute.ArraySubType = arraySubType; - attribute.SizeParamIndex = (short)sizeParamIndex; - attribute.SizeConst = sizeConst; - attribute.MarshalType = marshalTypeName; - attribute.MarshalTypeRef = marshalTypeRef; - attribute.MarshalCookie = marshalCookie; - - return attribute; + return MetadataImport.GetMarshalAs(nativeType, scope); } private static FieldOffsetAttribute? GetFieldOffsetCustomAttribute(RuntimeFieldInfo field) { - if (field.DeclaringType is not null && - field.GetRuntimeModule().MetadataImport.GetFieldOffset(field.DeclaringType.MetadataToken, field.MetadataToken, out int fieldOffset)) - return new FieldOffsetAttribute(fieldOffset); - + if (field.DeclaringType is not null) + { + RuntimeModule module = field.GetRuntimeModule(); + if (module.MetadataImport.GetFieldOffset(field.DeclaringType.MetadataToken, field.MetadataToken, out int fieldOffset)) + { + return new FieldOffsetAttribute(fieldOffset); + } + GC.KeepAlive(module); + } return null; } @@ -2322,7 +2300,9 @@ internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType? caType) case TypeAttributes.UnicodeClass: charSet = CharSet.Unicode; break; default: Debug.Fail("Unreachable code"); break; } - type.GetRuntimeModule().MetadataImport.GetClassLayout(type.MetadataToken, out int pack, out int size); + RuntimeModule module = type.GetRuntimeModule(); + module.MetadataImport.GetClassLayout(type.MetadataToken, out int pack, out int size); + GC.KeepAlive(module); StructLayoutAttribute attribute = new StructLayoutAttribute(layoutKind); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs index 8e7e4a05c73dde..4e9a4dffeb209a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs @@ -202,7 +202,7 @@ public override byte[] ResolveSignature(int metadataToken) if (declaringType.IsGenericType || declaringType.IsArray) { - int tkDeclaringType = ModuleHandle.GetMetadataImport(this).GetParentToken(metadataToken); + int tkDeclaringType = MetadataImport.GetParentToken(metadataToken); declaringType = (RuntimeType)ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments); } @@ -353,7 +353,7 @@ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFile #region Internal Members internal RuntimeType RuntimeType => m_runtimeType ??= ModuleHandle.GetModuleType(this); - internal MetadataImport MetadataImport => ModuleHandle.GetMetadataImport(this); + internal MetadataImport MetadataImport => new MetadataImport(this); #endregion #region ICustomAttributeProvider Members diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs index 5af77b790f49c3..24dd89c2113172 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs @@ -29,6 +29,11 @@ internal static ParameterInfo GetReturnParameter(IRuntimeMethodInfo method, Memb private static ParameterInfo[] GetParameters( IRuntimeMethodInfo methodHandle, MemberInfo member, Signature sig, out ParameterInfo? returnParameter, bool fetchReturnParameter) { + // The lifetime rules for MetadataImport expect these two objects to be the same instance. + // See the lifetime of MetadataImport, acquired through IRuntimeMethodInfo, but extended + // through the MemberInfo instance. + Debug.Assert(ReferenceEquals(methodHandle, member)); + returnParameter = null; int sigArgCount = sig.Arguments.Length; ParameterInfo[] args = @@ -43,7 +48,7 @@ private static ParameterInfo[] GetParameters( // are generated on the fly by the runtime. if (!MdToken.IsNullToken(tkMethodDef)) { - MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(RuntimeMethodHandle.GetDeclaringType(methodHandle)); + MetadataImport scope = RuntimeMethodHandle.GetDeclaringType(methodHandle).GetRuntimeModule().MetadataImport; scope.EnumParams(tkMethodDef, out MetadataEnumResult tkParamDefs); @@ -73,7 +78,7 @@ private static ParameterInfo[] GetParameters( } else if (!fetchReturnParameter && position >= 0) { - // position beyong sigArgCount? + // position beyond sigArgCount? if (position >= sigArgCount) throw new BadImageFormatException(SR.BadImageFormat_ParameterSignatureMismatch); @@ -86,7 +91,7 @@ private static ParameterInfo[] GetParameters( // Fill in empty ParameterInfos for those without tokens if (fetchReturnParameter) { - returnParameter ??= new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, -1, (ParameterAttributes)0, member); + returnParameter ??= new RuntimeParameterInfo(sig, default, 0, -1, (ParameterAttributes)0, member); } else { @@ -97,7 +102,7 @@ private static ParameterInfo[] GetParameters( if (args[i] != null) continue; - args[i] = new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, i, (ParameterAttributes)0, member); + args[i] = new RuntimeParameterInfo(sig, default, 0, i, (ParameterAttributes)0, member); } } } @@ -165,7 +170,7 @@ private RuntimeParameterInfo(RuntimeParameterInfo accessor, MemberInfo member) PositionImpl = accessor.Position; AttrsImpl = accessor.Attributes; - // Strictly speeking, property's don't contain parameter tokens + // Strictly speaking, properties don't contain parameter tokens // However we need this to make ca's work... oh well... m_tkParamDef = MdToken.IsNullToken(accessor.MetadataToken) ? (int)MetadataTokenType.ParamDef : accessor.MetadataToken; m_scope = accessor.m_scope; @@ -176,7 +181,7 @@ private RuntimeParameterInfo( int position, ParameterAttributes attributes, MemberInfo member) { Debug.Assert(member != null); - Debug.Assert(MdToken.IsNullToken(tkParamDef) == scope.Equals(MetadataImport.EmptyImport)); + Debug.Assert(MdToken.IsNullToken(tkParamDef) == scope.Equals((MetadataImport)default)); Debug.Assert(MdToken.IsNullToken(tkParamDef) || MdToken.IsTokenOfType(tkParamDef, MetadataTokenType.ParamDef)); PositionImpl = position; @@ -201,7 +206,7 @@ internal RuntimeParameterInfo(MethodInfo owner, string? name, Type parameterType PositionImpl = position; AttrsImpl = ParameterAttributes.None; m_tkParamDef = (int)MetadataTokenType.ParamDef; - m_scope = MetadataImport.EmptyImport; + m_scope = default; } #endregion @@ -239,6 +244,7 @@ public override string? Name if (!MdToken.IsNullToken(m_tkParamDef)) { string name = m_scope.GetName(m_tkParamDef).ToString(); + GC.KeepAlive(this); NameImpl = name; } @@ -339,6 +345,7 @@ private bool TryGetDefaultValueInternal(bool raw, out object? defaultValue) #region Look for a default value in metadata // This will return DBNull.Value if no constant value is defined on m_tkParamDef in the metadata. defaultValue = MdConstant.GetValue(m_scope, m_tkParamDef, ParameterType.TypeHandle, raw); + GC.KeepAlive(this); // If default value is not specified in metadata, look for it in custom attributes if (defaultValue == DBNull.Value) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs index 933e05d0bf7854..d49ac821e684d9 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs @@ -35,7 +35,8 @@ internal RuntimePropertyInfo( Debug.Assert(reflectedTypeCache != null); Debug.Assert(!reflectedTypeCache.IsGlobal); - MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport; + RuntimeModule module = declaredType.GetRuntimeModule(); + MetadataImport scope = module.MetadataImport; m_token = tkProperty; m_reflectedTypeCache = reflectedTypeCache; @@ -47,6 +48,7 @@ internal RuntimePropertyInfo( out _, out _, out _, out m_getterMethod, out m_setterMethod, out m_otherMethod, out isPrivate, out m_bindingFlags); + GC.KeepAlive(module); } #endregion @@ -65,9 +67,9 @@ internal Signature Signature { if (m_signature == null) { - GetRuntimeModule().MetadataImport.GetPropertyProps( m_token, out _, out _, out ConstArray sig); + GC.KeepAlive(this); m_signature = new Signature(sig.Signature.ToPointer(), sig.Length, m_declaringType); } @@ -210,6 +212,7 @@ public override Type[] GetOptionalCustomModifiers() internal object GetConstantValue(bool raw) { object? defaultValue = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_token, PropertyType.TypeHandle, raw); + GC.KeepAlive(this); if (defaultValue == DBNull.Value) // Arg_EnumLitValueNotFound -> "Literal value was not found." diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/TypeNameParser.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/TypeNameParser.CoreCLR.cs index 2af4bb792d4588..35fa0b5718e387 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/TypeNameParser.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/TypeNameParser.CoreCLR.cs @@ -4,11 +4,9 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Loader; -using System.Text; using System.Threading; namespace System.Reflection @@ -57,7 +55,13 @@ internal partial struct TypeNameParser return null; } - return new TypeNameParser(typeName) + Metadata.TypeName? parsed = Metadata.TypeNameParser.Parse(typeName, throwOnError: throwOnError); + if (parsed is null) + { + return null; + } + + return new TypeNameParser() { _assemblyResolver = assemblyResolver, _typeResolver = typeResolver, @@ -65,7 +69,7 @@ internal partial struct TypeNameParser _ignoreCase = ignoreCase, _extensibleParser = extensibleParser, _requestingAssembly = requestingAssembly - }.Parse(); + }.Resolve(parsed); } [RequiresUnreferencedCode("The type might be removed")] @@ -75,13 +79,24 @@ internal partial struct TypeNameParser bool ignoreCase, Assembly topLevelAssembly) { - return new TypeNameParser(typeName) + Metadata.TypeName? parsed = Metadata.TypeNameParser.Parse(typeName, throwOnError); + + if (parsed is null) + { + return null; + } + else if (topLevelAssembly is not null && parsed.AssemblyName is not null) + { + return throwOnError ? throw new ArgumentException(SR.Argument_AssemblyGetTypeCannotSpecifyAssembly) : null; + } + + return new TypeNameParser() { _throwOnError = throwOnError, _ignoreCase = ignoreCase, _topLevelAssembly = topLevelAssembly, _requestingAssembly = topLevelAssembly - }.Parse(); + }.Resolve(parsed); } // Resolve type name referenced by a custom attribute metadata. @@ -95,12 +110,13 @@ internal static RuntimeType GetTypeReferencedByCustomAttribute(string typeName, RuntimeAssembly requestingAssembly = scope.GetRuntimeAssembly(); - RuntimeType? type = (RuntimeType?)new TypeNameParser(typeName) + Metadata.TypeName parsed = Metadata.TypeName.Parse(typeName); + RuntimeType? type = (RuntimeType?)new TypeNameParser() { _throwOnError = true, _suppressContextualReflectionContext = true, _requestingAssembly = requestingAssembly - }.Parse(); + }.Resolve(parsed); Debug.Assert(type != null); @@ -124,13 +140,19 @@ internal static RuntimeType GetTypeReferencedByCustomAttribute(string typeName, return null; } - RuntimeType? type = (RuntimeType?)new TypeNameParser(typeName) + Metadata.TypeName? parsed = Metadata.TypeNameParser.Parse(typeName, throwOnError); + if (parsed is null) + { + return null; + } + + RuntimeType? type = (RuntimeType?)new TypeNameParser() { _requestingAssembly = requestingAssembly, _throwOnError = throwOnError, _suppressContextualReflectionContext = true, _requireAssemblyQualifiedName = requireAssemblyQualifiedName, - }.Parse(); + }.Resolve(parsed); if (type != null) RuntimeTypeHandle.RegisterCollectibleTypeDependency(type, requestingAssembly); @@ -138,23 +160,12 @@ internal static RuntimeType GetTypeReferencedByCustomAttribute(string typeName, return type; } - private bool CheckTopLevelAssemblyQualifiedName() - { - if (_topLevelAssembly is not null) - { - if (_throwOnError) - throw new ArgumentException(SR.Argument_AssemblyGetTypeCannotSpecifyAssembly); - return false; - } - return true; - } - - private Assembly? ResolveAssembly(string assemblyName) + private Assembly? ResolveAssembly(AssemblyName assemblyName) { Assembly? assembly; if (_assemblyResolver is not null) { - assembly = _assemblyResolver(new AssemblyName(assemblyName)); + assembly = _assemblyResolver(assemblyName); if (assembly is null && _throwOnError) { throw new FileNotFoundException(SR.Format(SR.FileNotFound_ResolveAssembly, assemblyName)); @@ -162,7 +173,7 @@ private bool CheckTopLevelAssemblyQualifiedName() } else { - assembly = RuntimeAssembly.InternalLoad(new AssemblyName(assemblyName), ref Unsafe.NullRef(), + assembly = RuntimeAssembly.InternalLoad(assemblyName, ref Unsafe.NullRef(), _suppressContextualReflectionContext ? null : AssemblyLoadContext.CurrentContextualReflectionContext, requestingAssembly: (RuntimeAssembly?)_requestingAssembly, throwOnFileNotFound: _throwOnError); } @@ -173,13 +184,14 @@ private bool CheckTopLevelAssemblyQualifiedName() Justification = "TypeNameParser.GetType is marked as RequiresUnreferencedCode.")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", Justification = "TypeNameParser.GetType is marked as RequiresUnreferencedCode.")] - private Type? GetType(string typeName, ReadOnlySpan nestedTypeNames, string? assemblyNameIfAny) + private Type? GetType(string escapedTypeName, // For nested types, it's Name. For other types it's FullName + ReadOnlySpan nestedTypeNames, Metadata.TypeName parsedName) { Assembly? assembly; - if (assemblyNameIfAny is not null) + if (parsedName.AssemblyName is not null) { - assembly = ResolveAssembly(assemblyNameIfAny); + assembly = ResolveAssembly(parsedName.AssemblyName.ToAssemblyName()); if (assembly is null) return null; } @@ -193,8 +205,6 @@ private bool CheckTopLevelAssemblyQualifiedName() // Resolve the top level type. if (_typeResolver is not null) { - string escapedTypeName = EscapeTypeName(typeName); - type = _typeResolver(assembly, escapedTypeName, _ignoreCase); if (type is null) @@ -216,28 +226,29 @@ private bool CheckTopLevelAssemblyQualifiedName() { if (_throwOnError) { - throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveType, EscapeTypeName(typeName))); + throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveType, escapedTypeName)); } return null; } - return GetTypeFromDefaultAssemblies(typeName, nestedTypeNames); + return GetTypeFromDefaultAssemblies(UnescapeTypeName(escapedTypeName), nestedTypeNames, parsedName); } if (assembly is RuntimeAssembly runtimeAssembly) { + string unescapedTypeName = UnescapeTypeName(escapedTypeName); // Compat: Non-extensible parser allows ambiguous matches with ignore case lookup if (!_extensibleParser || !_ignoreCase) { - return runtimeAssembly.GetTypeCore(typeName, nestedTypeNames, throwOnError: _throwOnError, ignoreCase: _ignoreCase); + return runtimeAssembly.GetTypeCore(unescapedTypeName, nestedTypeNames, throwOnError: _throwOnError, ignoreCase: _ignoreCase); } - type = runtimeAssembly.GetTypeCore(typeName, default, throwOnError: _throwOnError, ignoreCase: _ignoreCase); + type = runtimeAssembly.GetTypeCore(unescapedTypeName, default, throwOnError: _throwOnError, ignoreCase: _ignoreCase); } else { // This is a third-party Assembly object. Emulate GetTypeCore() by calling the public GetType() // method. This is wasteful because it'll probably reparse a type string that we've already parsed // but it can't be helped. - type = assembly.GetType(EscapeTypeName(typeName), throwOnError: _throwOnError, ignoreCase: _ignoreCase); + type = assembly.GetType(escapedTypeName, throwOnError: _throwOnError, ignoreCase: _ignoreCase); } if (type is null) @@ -257,7 +268,7 @@ private bool CheckTopLevelAssemblyQualifiedName() if (_throwOnError) { throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveNestedType, - nestedTypeNames[i], (i > 0) ? nestedTypeNames[i - 1] : typeName)); + nestedTypeNames[i], (i > 0) ? nestedTypeNames[i - 1] : escapedTypeName)); } return null; } @@ -266,12 +277,12 @@ private bool CheckTopLevelAssemblyQualifiedName() return type; } - private Type? GetTypeFromDefaultAssemblies(string typeName, ReadOnlySpan nestedTypeNames) + private Type? GetTypeFromDefaultAssemblies(string typeName, ReadOnlySpan nestedTypeNames, Metadata.TypeName parsedName) { RuntimeAssembly? requestingAssembly = (RuntimeAssembly?)_requestingAssembly; if (requestingAssembly is not null) { - Type? type = ((RuntimeAssembly)requestingAssembly).GetTypeCore(typeName, nestedTypeNames, throwOnError: false, ignoreCase: _ignoreCase); + Type? type = requestingAssembly.GetTypeCore(typeName, nestedTypeNames, throwOnError: false, ignoreCase: _ignoreCase); if (type is not null) return type; } @@ -279,12 +290,12 @@ private bool CheckTopLevelAssemblyQualifiedName() RuntimeAssembly coreLib = (RuntimeAssembly)typeof(object).Assembly; if (requestingAssembly != coreLib) { - Type? type = ((RuntimeAssembly)coreLib).GetTypeCore(typeName, nestedTypeNames, throwOnError: false, ignoreCase: _ignoreCase); + Type? type = coreLib.GetTypeCore(typeName, nestedTypeNames, throwOnError: false, ignoreCase: _ignoreCase); if (type is not null) return type; } - RuntimeAssembly? resolvedAssembly = AssemblyLoadContext.OnTypeResolve(requestingAssembly, EscapeTypeName(typeName, nestedTypeNames)); + RuntimeAssembly? resolvedAssembly = AssemblyLoadContext.OnTypeResolve(requestingAssembly, parsedName.FullName); if (resolvedAssembly is not null) { Type? type = resolvedAssembly.GetTypeCore(typeName, nestedTypeNames, throwOnError: false, ignoreCase: _ignoreCase); @@ -293,7 +304,7 @@ private bool CheckTopLevelAssemblyQualifiedName() } if (_throwOnError) - throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveTypeFromAssembly, EscapeTypeName(typeName), (requestingAssembly ?? coreLib).FullName)); + throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveTypeFromAssembly, parsedName.FullName, (requestingAssembly ?? coreLib).FullName)); return null; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 001a9fcdfee6a8..380981993451e9 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -650,14 +650,6 @@ internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[]? } } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern IntPtr _GetMetadataImport(RuntimeType type); - - internal static MetadataImport GetMetadataImport(RuntimeType type) - { - return new MetadataImport(_GetMetadataImport(type), type); - } - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_RegisterCollectibleTypeDependency")] private static partial void RegisterCollectibleTypeDependency(QCallTypeHandle type, QCallAssembly assembly); @@ -1247,8 +1239,6 @@ internal ModuleHandle(RuntimeModule module) } #endregion - #region Internal FCalls - internal RuntimeModule GetRuntimeModule() { return m_ptr; @@ -1278,6 +1268,7 @@ public bool Equals(ModuleHandle handle) public static bool operator !=(ModuleHandle left, ModuleHandle right) => !left.Equals(right); + #region Internal FCalls [MethodImpl(MethodImplOptions.InternalCall)] internal static extern IRuntimeMethodInfo GetDynamicMethod(Reflection.Emit.DynamicMethod method, RuntimeModule module, string name, byte[] sig, Resolver resolver); @@ -1336,7 +1327,7 @@ public RuntimeTypeHandle ResolveTypeHandle(int typeToken, RuntimeTypeHandle[]? t } catch (Exception) { - if (!GetMetadataImport(module).IsValidToken(typeToken)) + if (!module.MetadataImport.IsValidToken(typeToken)) throw new ArgumentOutOfRangeException(nameof(typeToken), SR.Format(SR.Argument_InvalidToken, typeToken, new ModuleHandle(module))); throw; @@ -1389,7 +1380,7 @@ internal static RuntimeMethodHandleInternal ResolveMethodHandleInternal(RuntimeM } catch (Exception) { - if (!GetMetadataImport(module).IsValidToken(methodToken)) + if (!module.MetadataImport.IsValidToken(methodToken)) throw new ArgumentOutOfRangeException(nameof(methodToken), SR.Format(SR.Argument_InvalidToken, methodToken, new ModuleHandle(module))); throw; @@ -1442,7 +1433,7 @@ public RuntimeFieldHandle ResolveFieldHandle(int fieldToken, RuntimeTypeHandle[] } catch (Exception) { - if (!GetMetadataImport(module).IsValidToken(fieldToken)) + if (!module.MetadataImport.IsValidToken(fieldToken)) throw new ArgumentOutOfRangeException(nameof(fieldToken), SR.Format(SR.Argument_InvalidToken, fieldToken, new ModuleHandle(module))); throw; @@ -1485,14 +1476,6 @@ internal static void GetPEKind(RuntimeModule module, out PortableExecutableKinds internal static extern int GetMDStreamVersion(RuntimeModule module); public int MDStreamVersion => GetMDStreamVersion(GetRuntimeModule()); - - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern IntPtr _GetMetadataImport(RuntimeModule module); - - internal static MetadataImport GetMetadataImport(RuntimeModule module) - { - return new MetadataImport(_GetMetadataImport(module), module); - } #endregion } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index 56ff2e26850ccc..c6ea76fde9b85f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -932,7 +932,8 @@ private void PopulateLiteralFields(Filter filter, RuntimeType declaringType, ref if (MdToken.IsNullToken(tkDeclaringType)) return; - MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType); + RuntimeModule module = declaringType.GetRuntimeModule(); + MetadataImport scope = module.MetadataImport; scope.EnumFields(tkDeclaringType, out MetadataEnumResult tkFields); @@ -976,6 +977,7 @@ private void PopulateLiteralFields(Filter filter, RuntimeType declaringType, ref list.Add(runtimeFieldInfo); } } + GC.KeepAlive(module); } private void AddSpecialInterface( @@ -1102,7 +1104,7 @@ private RuntimeType[] PopulateNestedClasses(Filter filter) ListBuilder list = default; ModuleHandle moduleHandle = new ModuleHandle(RuntimeTypeHandle.GetModule(declaringType)); - MetadataImport scope = ModuleHandle.GetMetadataImport(moduleHandle.GetRuntimeModule()); + MetadataImport scope = moduleHandle.GetRuntimeModule().MetadataImport; scope.EnumNestedTypes(tkEnclosingType, out MetadataEnumResult tkNestedClasses); @@ -1174,7 +1176,8 @@ private void PopulateEvents( if (MdToken.IsNullToken(tkDeclaringType)) return; - MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType); + RuntimeModule module = declaringType.GetRuntimeModule(); + MetadataImport scope = module.MetadataImport; scope.EnumEvents(tkDeclaringType, out MetadataEnumResult tkEvents); @@ -1220,6 +1223,7 @@ private void PopulateEvents( list.Add(eventInfo); } + GC.KeepAlive(module); } private RuntimePropertyInfo[] PopulateProperties(Filter filter) @@ -1286,7 +1290,8 @@ private void PopulateProperties( if (MdToken.IsNullToken(tkDeclaringType)) return; - MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType); + RuntimeModule module = declaringType.GetRuntimeModule(); + MetadataImport scope = module.MetadataImport; scope.EnumProperties(tkDeclaringType, out MetadataEnumResult tkProperties); @@ -1304,7 +1309,7 @@ private void PopulateProperties( if (filter.RequiresStringComparison()) { - MdUtf8String name = declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty); + MdUtf8String name = scope.GetName(tkProperty); if (!filter.Match(name)) continue; @@ -1399,6 +1404,7 @@ private void PopulateProperties( list.Add(propertyInfo); } + GC.KeepAlive(module); } #endregion @@ -1571,7 +1577,9 @@ internal Type[] FunctionPointerReturnAndParameterTypes while (type.IsNested) type = type.DeclaringType!; - m_namespace = RuntimeTypeHandle.GetMetadataImport((RuntimeType)type).GetNamespace(type.MetadataToken).ToString(); + RuntimeModule module = ((RuntimeType)type).GetRuntimeModule(); + m_namespace = module.MetadataImport.GetNamespace(type.MetadataToken).ToString(); + GC.KeepAlive(module); } return m_namespace; @@ -3499,8 +3507,9 @@ public override GenericParameterAttributes GenericParameterAttributes if (!IsGenericParameter) throw new InvalidOperationException(SR.Arg_NotGenericParameter); - - RuntimeTypeHandle.GetMetadataImport(this).GetGenericParamProps(MetadataToken, out GenericParameterAttributes attributes); + RuntimeModule module = GetRuntimeModule(); + module.MetadataImport.GetGenericParamProps(MetadataToken, out GenericParameterAttributes attributes); + GC.KeepAlive(module); return attributes; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs index 03a92b709eb1a5..81caecb09c99aa 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs @@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; -using System.Runtime.Versioning; using System.Security; using StackCrawlMark = System.Threading.StackCrawlMark; diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 4201c06692eeb5..1970b6c33c7544 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -16,6 +16,7 @@ elseif (CLR_CMAKE_TARGET_ARCH_ARM) add_definitions(-DFEATURE_EMULATE_SINGLESTEP) elseif (CLR_CMAKE_TARGET_ARCH_RISCV64) add_definitions(-DFEATURE_EMULATE_SINGLESTEP) + add_compile_definitions($<$>>:FEATURE_MULTIREG_RETURN>) endif (CLR_CMAKE_TARGET_ARCH_ARM64) if (CLR_CMAKE_TARGET_UNIX) diff --git a/src/coreclr/debug/daccess/cdac.cpp b/src/coreclr/debug/daccess/cdac.cpp index 78625bf67f2d72..b7bb7585e6bcf7 100644 --- a/src/coreclr/debug/daccess/cdac.cpp +++ b/src/coreclr/debug/daccess/cdac.cpp @@ -28,8 +28,12 @@ namespace int ReadFromTargetCallback(uint64_t addr, uint8_t* dest, uint32_t count, void* context) { - CDAC* cdac = reinterpret_cast(context); - return cdac->ReadFromTarget(addr, dest, count); + ICorDebugDataTarget* target = reinterpret_cast(context); + HRESULT hr = ReadFromDataTarget(target, addr, dest, count); + if (FAILED(hr)) + return hr; + + return S_OK; } } @@ -37,32 +41,37 @@ CDAC CDAC::Create(uint64_t descriptorAddr, ICorDebugDataTarget* target) { HMODULE cdacLib; if (!TryLoadCDACLibrary(&cdacLib)) - return CDAC::Invalid(); + return {}; + + decltype(&cdac_reader_init) init = reinterpret_cast(::GetProcAddress(cdacLib, "cdac_reader_init")); + _ASSERTE(init != nullptr); + + intptr_t handle; + if (init(descriptorAddr, &ReadFromTargetCallback, target, &handle) != 0) + { + ::FreeLibrary(cdacLib); + return {}; + } - return CDAC{cdacLib, descriptorAddr, target}; + return CDAC{cdacLib, handle, target}; } -CDAC::CDAC(HMODULE module, uint64_t descriptorAddr, ICorDebugDataTarget* target) - : m_module(module) +CDAC::CDAC(HMODULE module, intptr_t handle, ICorDebugDataTarget* target) + : m_module{module} + , m_cdac_handle{handle} , m_target{target} { - if (m_module == NULL) - { - m_cdac_handle = NULL; - return; - } + _ASSERTE(m_module != NULL && m_cdac_handle != 0 && m_target != NULL); - decltype(&cdac_reader_init) init = reinterpret_cast(::GetProcAddress(m_module, "cdac_reader_init")); + m_target->AddRef(); decltype(&cdac_reader_get_sos_interface) getSosInterface = reinterpret_cast(::GetProcAddress(m_module, "cdac_reader_get_sos_interface")); - _ASSERTE(init != nullptr && getSosInterface != nullptr); - - init(descriptorAddr, &ReadFromTargetCallback, this, &m_cdac_handle); + _ASSERTE(getSosInterface != nullptr); getSosInterface(m_cdac_handle, &m_sos); } CDAC::~CDAC() { - if (m_cdac_handle != NULL) + if (m_cdac_handle) { decltype(&cdac_reader_free) free = reinterpret_cast(::GetProcAddress(m_module, "cdac_reader_free")); _ASSERTE(free != nullptr); @@ -77,12 +86,3 @@ IUnknown* CDAC::SosInterface() { return m_sos; } - -int CDAC::ReadFromTarget(uint64_t addr, uint8_t* dest, uint32_t count) -{ - HRESULT hr = ReadFromDataTarget(m_target, addr, dest, count); - if (FAILED(hr)) - return hr; - - return S_OK; -} diff --git a/src/coreclr/debug/daccess/cdac.h b/src/coreclr/debug/daccess/cdac.h index 54418dc549f1f0..51078ffcf2e46b 100644 --- a/src/coreclr/debug/daccess/cdac.h +++ b/src/coreclr/debug/daccess/cdac.h @@ -9,19 +9,16 @@ class CDAC final public: // static static CDAC Create(uint64_t descriptorAddr, ICorDebugDataTarget *pDataTarget); - static CDAC Invalid() - { - return CDAC{nullptr, 0, nullptr}; - } - public: + CDAC() = default; + CDAC(const CDAC&) = delete; CDAC& operator=(const CDAC&) = delete; CDAC(CDAC&& other) : m_module{ other.m_module } , m_cdac_handle{ other.m_cdac_handle } - , m_target{ other.m_target } + , m_target{ other.m_target.Extract() } , m_sos{ other.m_sos.Extract() } { other.m_module = NULL; @@ -34,7 +31,7 @@ class CDAC final { m_module = other.m_module; m_cdac_handle = other.m_cdac_handle; - m_target = other.m_target; + m_target = other.m_target.Extract(); m_sos = other.m_sos.Extract(); other.m_module = NULL; @@ -54,15 +51,14 @@ class CDAC final // This does not AddRef the returned interface IUnknown* SosInterface(); - int ReadFromTarget(uint64_t addr, uint8_t* dest, uint32_t count); private: - CDAC(HMODULE module, uint64_t descriptorAddr, ICorDebugDataTarget* target); + CDAC(HMODULE module, intptr_t handle, ICorDebugDataTarget* target); private: HMODULE m_module; intptr_t m_cdac_handle; - ICorDebugDataTarget* m_target; + NonVMComHolder m_target; NonVMComHolder m_sos; }; diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 2f08750bc5c61b..37e7d37edd9f9c 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -30,6 +30,8 @@ #include #else extern "C" bool TryGetSymbol(ICorDebugDataTarget* dataTarget, uint64_t baseAddress, const char* symbolName, uint64_t* symbolAddress); +// cDAC depends on symbol lookup to find the contract descriptor +#define CAN_USE_CDAC #endif #include "dwbucketmanager.hpp" @@ -3036,7 +3038,7 @@ class DacStreamManager //---------------------------------------------------------------------------- ClrDataAccess::ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget/*=0*/) - : m_cdac{CDAC::Invalid()} + : m_cdac{} { SUPPORTS_DAC_HOST_ONLY; // ctor does no marshalling - don't check with DacCop @@ -5493,15 +5495,16 @@ ClrDataAccess::Initialize(void) IfFailRet(GetDacGlobalValues()); IfFailRet(DacGetHostVtPtrs()); +// TODO: [cdac] TryGetSymbol is only implemented for Linux, OSX, and Windows. +#ifdef CAN_USE_CDAC CLRConfigNoCache enable = CLRConfigNoCache::Get("ENABLE_CDAC"); if (enable.IsSet()) { DWORD val; if (enable.TryAsInteger(10, val) && val == 1) { - // TODO: [cdac] Get contract descriptor from exported symbol uint64_t contractDescriptorAddr = 0; - //if (TryGetSymbol(m_pTarget, m_globalBase, "DotNetRuntimeContractDescriptor", &contractDescriptorAddr)) + if (TryGetSymbol(m_pTarget, m_globalBase, "DotNetRuntimeContractDescriptor", &contractDescriptorAddr)) { m_cdac = CDAC::Create(contractDescriptorAddr, m_pTarget); if (m_cdac.IsValid()) @@ -5514,6 +5517,7 @@ ClrDataAccess::Initialize(void) } } } +#endif // // DAC is now setup and ready to use @@ -6946,7 +6950,7 @@ GetDacTableAddress(ICorDebugDataTarget* dataTarget, ULONG64 baseAddress, PULONG6 return E_INVALIDARG; } #endif - // On MacOS, FreeBSD or NetBSD use the RVA include file + // On FreeBSD, NetBSD, or SunOS use the RVA include file *dacTableAddress = baseAddress + DAC_TABLE_RVA; #else // Otherwise, try to get the dac table address via the export symbol diff --git a/src/coreclr/debug/di/divalue.cpp b/src/coreclr/debug/di/divalue.cpp index 285da47437ebc3..853bac550e4554 100644 --- a/src/coreclr/debug/di/divalue.cpp +++ b/src/coreclr/debug/di/divalue.cpp @@ -1840,6 +1840,10 @@ HRESULT CordbObjectValue::QueryInterface(REFIID id, void **pInterface) { *pInterface = static_cast(static_cast(this)); } + else if (id == IID_ICorDebugExceptionObjectValue2 && m_fIsExceptionObject) + { + *pInterface = static_cast(static_cast(this)); + } else if (id == IID_ICorDebugComObjectValue && m_fIsRcw) { *pInterface = static_cast(this); @@ -2489,6 +2493,41 @@ HRESULT CordbObjectValue::EnumerateExceptionCallStack(ICorDebugExceptionObjectCa return hr; } +HRESULT CordbObjectValue::ForceCatchHandlerFoundEvents(BOOL enableEvents) +{ + PUBLIC_API_ENTRY(this); + FAIL_IF_NEUTERED(this); + ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); + + HRESULT hr = S_OK; + + EX_TRY + { + CordbProcess * pProcess = GetProcess(); + + CORDB_ADDRESS objAddr = m_valueHome.GetAddress(); + + IDacDbiInterface* pDAC = GetProcess()->GetDAC(); + VMPTR_Object vmObj = pDAC->GetObject(objAddr); + + DebuggerIPCEvent event; + CordbAppDomain * pAppDomain = GetAppDomain(); + _ASSERTE (pAppDomain != NULL); + + pProcess->InitIPCEvent(&event, DB_IPCE_FORCE_CATCH_HANDLER_FOUND, true, pAppDomain->GetADToken()); + event.ForceCatchHandlerFoundData.enableEvents = enableEvents; + event.ForceCatchHandlerFoundData.vmObj = vmObj; + + hr = pProcess->m_cordb->SendIPCEvent(pProcess, &event, sizeof(DebuggerIPCEvent)); + + _ASSERTE(event.type == DB_IPCE_CATCH_HANDLER_FOUND_RESULT); + + hr = event.hr; + } + EX_CATCH_HRESULT(hr); + return hr; +} + HRESULT CordbObjectValue::IsExceptionObject() { HRESULT hr = S_OK; diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 9920ed2dce0146..67f1a963a53d52 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -10734,6 +10734,7 @@ HRESULT CordbRCEventThread::WaitForIPCEventFromProcess(CordbProcess * pProcess, CordbAppDomain * pAppDomain, DebuggerIPCEvent * pEvent) { + CORDBRequireProcessStateOKAndSync(pProcess, pAppDomain); DWORD dwStatus; diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 4b3fff25ce69b2..9c6a98776d1cca 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -9170,6 +9170,7 @@ class CordbObjectValue : public CordbValue, public ICorDebugHeapValue3, public ICorDebugHeapValue4, public ICorDebugExceptionObjectValue, + public ICorDebugExceptionObjectValue2, public ICorDebugComObjectValue, public ICorDebugDelegateObjectValue { @@ -9292,6 +9293,11 @@ class CordbObjectValue : public CordbValue, //----------------------------------------------------------- COM_METHOD EnumerateExceptionCallStack(ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum); + //----------------------------------------------------------- + // ICorDebugExceptionObjectValue2 + //----------------------------------------------------------- + COM_METHOD ForceCatchHandlerFoundEvents(BOOL enableEvents); + //----------------------------------------------------------- // ICorDebugComObjectValue //----------------------------------------------------------- diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 7a5028e1fc2018..3723ab2c90354e 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -915,6 +915,7 @@ Debugger::Debugger() m_unrecoverableError(FALSE), m_ignoreThreadDetach(FALSE), m_pMethodInfos(NULL), + m_pForceCatchHandlerFoundEventsTable(NULL), m_mutex(CrstDebuggerMutex, (CrstFlags)(CRST_UNSAFE_ANYMODE | CRST_REENTRANCY | CRST_DEBUGGER_THREAD)), #ifdef _DEBUG m_mutexOwner(0), @@ -956,8 +957,7 @@ Debugger::Debugger() m_processId = GetCurrentProcessId(); - // Initialize these in ctor because we free them in dtor. - // And we can't set them to some safe uninited value (like NULL). + m_pForceCatchHandlerFoundEventsTable = new ForceCatchHandlerFoundTable(); @@ -7448,8 +7448,8 @@ void Debugger::SendExceptionEventsWorker( g_pDebugger->IncThreadsAtUnsafePlaces(); } } // end of GCX_CCOP_EEINTERFACE(); - } //end if (m_sendExceptionsOutsideOfJMC && !SentDebugFirstChance()) + } //end if (m_sendExceptionsOutsideOfJMC && !SentDebugFirstChance()) // // If this is a JMC function, then we send a USER's first chance as well. // @@ -7846,11 +7846,14 @@ void Debugger::FirstChanceManagedExceptionCatcherFound(Thread *pThread, } } + BOOL forceSendCatchHandlerFound = FALSE; + { + GCX_COOP_EEINTERFACE(); + forceSendCatchHandlerFound = ShouldSendCatchHandlerFound(pThread); + } // Here we check if debugger opted-out of receiving exception related events from outside of JMC methods // or this exception ever crossed JMC frame (in this case we have already sent user first chance event) - if (m_sendExceptionsOutsideOfJMC || - isInJMCFunction || - pThread->GetExceptionState()->GetFlags()->SentDebugUserFirstChance()) + if (isInJMCFunction || forceSendCatchHandlerFound) { if (pDebugJitInfo != NULL) { @@ -7979,9 +7982,15 @@ LONG Debugger::NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID p pExceptionPointers); } + BOOL forceSendCatchHandlerFound = FALSE; + { + GCX_COOP_EEINTERFACE(); + forceSendCatchHandlerFound = ShouldSendCatchHandlerFound(pThread); + } + // Here we check if debugger opted-out of receiving exception related events from outside of JMC methods // or this exception ever crossed JMC frame (in this case we have already sent user first chance event) - if (m_sendExceptionsOutsideOfJMC || pExState->GetFlags()->SentDebugUserFirstChance()) + if (forceSendCatchHandlerFound) { SendCatchHandlerFound(pThread, fp, offset, dwFlags); } @@ -8008,6 +8017,34 @@ LONG Debugger::NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID p return EXCEPTION_CONTINUE_SEARCH; } +BOOL Debugger::ShouldSendCatchHandlerFound(Thread* pThread) +{ + CONTRACTL + { + THROWS; + GC_NOTRIGGER; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + ThreadExceptionState* pExState = pThread->GetExceptionState(); + if (m_sendExceptionsOutsideOfJMC || pExState->GetFlags()->SentDebugUserFirstChance()) + { + return TRUE; + } + else + { + BOOL forceSendCatchHandlerFound = FALSE; + OBJECTHANDLE objHandle = pThread->GetThrowableAsHandle(); + OBJECTHANDLE retrievedHandle = m_pForceCatchHandlerFoundEventsTable->Lookup(objHandle); //destroy handle + if (retrievedHandle != NULL) + { + forceSendCatchHandlerFound = TRUE; + } + return forceSendCatchHandlerFound; + } +} + // Actually send the catch handler found event. // This can be used to send CHF for both regular managed catchers as well @@ -10427,6 +10464,27 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent) } break; + case DB_IPCE_FORCE_CATCH_HANDLER_FOUND: + { + BOOL enableEvents = pEvent->ForceCatchHandlerFoundData.enableEvents; + AppDomain *pAppDomain = pEvent->vmAppDomain.GetRawPtr(); + OBJECTREF exObj = ObjectToOBJECTREF(pEvent->ForceCatchHandlerFoundData.vmObj.GetRawPtr()); + HRESULT hr = E_INVALIDARG; + + hr = UpdateForceCatchHandlerFoundTable(enableEvents, exObj, pAppDomain); + + DebuggerIPCEvent * pIPCResult = m_pRCThread->GetIPCEventReceiveBuffer(); + InitIPCEvent(pIPCResult, + DB_IPCE_CATCH_HANDLER_FOUND_RESULT, + g_pEEInterface->GetThread(), + pEvent->vmAppDomain); + + pIPCResult->hr = hr; + + m_pRCThread->SendIPCReply(); + } + break; + case DB_IPCE_BREAKPOINT_ADD: { @@ -12350,6 +12408,44 @@ HRESULT Debugger::IsMethodDeoptimized(Module *pModule, mdMethodDef methodDef, BO return S_OK; } +HRESULT Debugger::UpdateForceCatchHandlerFoundTable(BOOL enableEvents, OBJECTREF exObj, AppDomain *pAppDomain) +{ + CONTRACTL + { + THROWS; + CAN_TAKE_LOCK; + GC_NOTRIGGER; + } + CONTRACTL_END; + + OBJECTHANDLE objHandle = pAppDomain->CreateLongWeakHandle(exObj); + if (objHandle == NULL) + { + return E_INVALIDARG; + } + if (enableEvents) + { + OBJECTHANDLE objHandleFound = m_pForceCatchHandlerFoundEventsTable->Lookup(objHandle); + if (objHandleFound == NULL) + { + m_pForceCatchHandlerFoundEventsTable->Add(objHandle); + } + else + { + DestroyLongWeakHandle(objHandle); + } + } + else + { + if (m_pForceCatchHandlerFoundEventsTable->Lookup(objHandle) != NULL) + { + m_pForceCatchHandlerFoundEventsTable->Remove(objHandle); + } + DestroyLongWeakHandle(objHandle); + } + return S_OK; +} + // // UnrecoverableError causes the Left Side to enter a state where no more // debugging can occur and we leave around enough information for the diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h index 38bbb73d2932e4..d66307fb146422 100644 --- a/src/coreclr/debug/ee/debugger.h +++ b/src/coreclr/debug/ee/debugger.h @@ -535,6 +535,61 @@ struct DebuggerPendingFuncEval typedef DPTR(struct DebuggerPendingFuncEval) PTR_DebuggerPendingFuncEval; +/* ------------------------------------------------------------------------ * + * SHash to hold weak object handles of exceptions with ForceCatchHandlerFound equal to true + * ------------------------------------------------------------------------ */ +#ifndef DACCESS_COMPILE +class EMPTY_BASES_DECL ForceCatchHandlerFoundSHashTraits : public DefaultSHashTraits +{ + public: + typedef OBJECTHANDLE element_t; + typedef OBJECTHANDLE key_t; + static const bool s_supports_autoremove = true; + static const bool s_NoThrow = false; + static const bool s_RemovePerEntryCleanupAction = true; + + static BOOL Equals(const OBJECTHANDLE &e, const OBJECTHANDLE &f) + { + return ObjectFromHandle(e) == ObjectFromHandle(f); + } + static OBJECTHANDLE GetKey(const OBJECTHANDLE &e) + { + return e; + } + static INT32 Hash(const OBJECTHANDLE &e) + { + return ObjectFromHandle(e)->GetHashCodeEx(); + } + static bool ShouldDelete(const OBJECTHANDLE &e) + { + return ObjectHandleIsNull(e); + } + static OBJECTHANDLE Null() + { + OBJECTHANDLE e = (OBJECTHANDLE)(TADDR)0; + return e; + } + static bool IsNull(const OBJECTHANDLE &e) + { + return e == (OBJECTHANDLE)(TADDR)0; + } + static OBJECTHANDLE Deleted() + { + OBJECTHANDLE e = (OBJECTHANDLE)(TADDR)-1; + return e; + } + static bool IsDeleted(const OBJECTHANDLE &e) + { + return e == (OBJECTHANDLE)(TADDR)-1; + } + static void OnRemovePerEntryCleanupAction(const OBJECTHANDLE &e) + { + DestroyLongWeakHandle(e); + } +}; +typedef SHash ForceCatchHandlerFoundTable; +#endif + /* ------------------------------------------------------------------------ * * DebuggerRCThread class -- the Runtime Controller thread. * ------------------------------------------------------------------------ */ @@ -1917,6 +1972,8 @@ class Debugger : public DebugInterface Module *classModule, BOOL fIsLoadEvent); + BOOL ShouldSendCatchHandlerFound(Thread* pThread); + void SendCatchHandlerFound(Thread *pThread, FramePointer fp, SIZE_T nOffset, @@ -2218,6 +2275,7 @@ class Debugger : public DebugInterface HRESULT DeoptimizeMethod(Module* pModule, mdMethodDef methodDef); #endif //DACCESS_COMPILE HRESULT IsMethodDeoptimized(Module *pModule, mdMethodDef methodDef, BOOL *pResult); + HRESULT UpdateForceCatchHandlerFoundTable(BOOL enableEvents, OBJECTREF exObj, AppDomain *pAppDomain); // // The debugger mutex is used to protect any "global" Left Side @@ -2806,6 +2864,11 @@ class Debugger : public DebugInterface BOOL m_unrecoverableError; BOOL m_ignoreThreadDetach; PTR_DebuggerMethodInfoTable m_pMethodInfos; + #ifdef DACCESS_COMPILE + VOID * m_pForceCatchHandlerFoundEventsTable; + #else + ForceCatchHandlerFoundTable *m_pForceCatchHandlerFoundEventsTable; + #endif // This is the main debugger lock. It is a large lock and used to synchronize complex operations @@ -3550,7 +3613,7 @@ inline void * __cdecl operator new[](size_t n, const InteropSafe&) return result; } -inline void * __cdecl operator new(size_t n, const InteropSafe&, const NoThrow&) throw() +inline void * __cdecl operator new(size_t n, const InteropSafe&, const std::nothrow_t&) noexcept { CONTRACTL { @@ -3569,7 +3632,7 @@ inline void * __cdecl operator new(size_t n, const InteropSafe&, const NoThrow&) return result; } -inline void * __cdecl operator new[](size_t n, const InteropSafe&, const NoThrow&) throw() +inline void * __cdecl operator new[](size_t n, const InteropSafe&, const std::nothrow_t&) noexcept { CONTRACTL { diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h index 68f18192c24ab4..661fcfdd334786 100644 --- a/src/coreclr/debug/inc/dbgipcevents.h +++ b/src/coreclr/debug/inc/dbgipcevents.h @@ -2054,6 +2054,12 @@ struct MSLAYOUT DebuggerIPCEvent VMPTR_Module pModule; } DisableOptData; + struct MSLAYOUT + { + BOOL enableEvents; + VMPTR_Object vmObj; + } ForceCatchHandlerFoundData; + struct MSLAYOUT { LSPTR_BREAKPOINT breakpointToken; diff --git a/src/coreclr/debug/inc/dbgipceventtypes.h b/src/coreclr/debug/inc/dbgipceventtypes.h index 9c3a09afcf9b41..650156fdda0613 100644 --- a/src/coreclr/debug/inc/dbgipceventtypes.h +++ b/src/coreclr/debug/inc/dbgipceventtypes.h @@ -93,7 +93,8 @@ IPC_EVENT_TYPE1(DB_IPCE_DATA_BREAKPOINT ,0x0160) IPC_EVENT_TYPE1(DB_IPCE_BEFORE_GARBAGE_COLLECTION ,0x0161) IPC_EVENT_TYPE1(DB_IPCE_AFTER_GARBAGE_COLLECTION ,0x0162) IPC_EVENT_TYPE1(DB_IPCE_DISABLE_OPTS_RESULT ,0x0163) -IPC_EVENT_TYPE0(DB_IPCE_RUNTIME_LAST ,0x0165) // The last event from runtime +IPC_EVENT_TYPE1(DB_IPCE_CATCH_HANDLER_FOUND_RESULT ,0x0165) +IPC_EVENT_TYPE0(DB_IPCE_RUNTIME_LAST ,0x0166) // The last event from runtime @@ -143,5 +144,6 @@ IPC_EVENT_TYPE2(DB_IPCE_GET_GCHANDLE_INFO ,0x0251) IPC_EVENT_TYPE2(DB_IPCE_RESOLVE_UPDATE_METADATA_1 ,0x0256) IPC_EVENT_TYPE2(DB_IPCE_RESOLVE_UPDATE_METADATA_2 ,0x0257) IPC_EVENT_TYPE2(DB_IPCE_DISABLE_OPTS ,0x0258) -IPC_EVENT_TYPE0(DB_IPCE_DEBUGGER_LAST ,0x025A) // The last event from the debugger +IPC_EVENT_TYPE2(DB_IPCE_FORCE_CATCH_HANDLER_FOUND ,0x025A) +IPC_EVENT_TYPE0(DB_IPCE_DEBUGGER_LAST ,0x025B) // The last event from the debugger diff --git a/src/coreclr/debug/runtimeinfo/CMakeLists.txt b/src/coreclr/debug/runtimeinfo/CMakeLists.txt index e6d45ada120131..77ecf9a4dd9bad 100644 --- a/src/coreclr/debug/runtimeinfo/CMakeLists.txt +++ b/src/coreclr/debug/runtimeinfo/CMakeLists.txt @@ -37,3 +37,58 @@ endif() # publish runtimeinfo lib install_clr(TARGETS runtimeinfo DESTINATIONS lib COMPONENT runtime) + + +# cDAC contract descriptor + +if (NOT CDAC_BUILD_TOOL_BINARY_PATH) + # if CDAC_BUILD_TOOL_BINARY_PATH is unspecified (for example for a build without a .NET SDK or msbuild), + # link a stub contract descriptor into the runtime + add_library_clr(cdac_contract_descriptor OBJECT contractdescriptorstub.c) + message(STATUS "Using a stub cDAC contract descriptor") +else() + # generate a contract descriptor using cdac-build-tool from a data descriptor and contract json file + + add_library(cdac_data_descriptor OBJECT datadescriptor.cpp) + # don't build the data descriptor before the VM (and any of its dependencies' generated headers) + add_dependencies(cdac_data_descriptor cee_wks_core) + if(CLR_CMAKE_TARGET_WIN32) + # turn off whole program optimization: + # 1. it creates object files that cdac-build-tool can't read + # 2. we never link cdac_data_descriptor into the final product - it's only job is to be scraped + target_compile_options(cdac_data_descriptor PRIVATE /GL-) + endif() + target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR}) + target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) + target_include_directories(cdac_data_descriptor PRIVATE ${CLR_DIR}/interop/inc) + + set(GENERATED_CDAC_DESCRIPTOR_DIR "${CMAKE_CURRENT_BINARY_DIR}/cdac") + set(CONTRACT_DESCRIPTOR_OUTPUT "${GENERATED_CDAC_DESCRIPTOR_DIR}/contract-descriptor.c") + if(NOT EXISTS "${CDAC_BUILD_TOOL_BINARY_PATH}") + message(FATAL_ERROR "${CDAC_BUILD_TOOL_BINARY_PATH} does not exist") + endif() + + 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}" $ + DEPENDS cdac_data_descriptor cee_wks_core $ "${CONTRACT_FILE}" + USES_TERMINAL + ) + + # It is important that cdac_contract_descriptor is an object library; + # if it was static, linking it into the final dll would not export + # DotNetRuntimeContractDescriptor since it is not referenced anywhere. + add_library_clr(cdac_contract_descriptor OBJECT + "${CONTRACT_DESCRIPTOR_OUTPUT}" + contractpointerdata.cpp + ) + target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR}) + target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) + target_include_directories(cdac_contract_descriptor PRIVATE ${CLR_DIR}/interop/inc) + add_dependencies(cdac_contract_descriptor cdac_data_descriptor cee_wks_core) +endif() diff --git a/src/coreclr/debug/runtimeinfo/contractdescriptorstub.c b/src/coreclr/debug/runtimeinfo/contractdescriptorstub.c new file mode 100644 index 00000000000000..59421a6692d2a7 --- /dev/null +++ b/src/coreclr/debug/runtimeinfo/contractdescriptorstub.c @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include + +#ifdef _MSC_VER +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT __attribute__((visibility("default"))) +#endif + +struct DotNetRuntimeContractDescriptor +{ + uint64_t magic; + uint32_t flags; + const uint32_t descriptor_size; + const char *descriptor; + const uint32_t pointer_data_count; + uint32_t pad0; + const uintptr_t *pointer_data; +}; + +extern const uintptr_t contractDescriptorPointerData[]; + +// just the placeholder pointer +const uintptr_t contractDescriptorPointerData[] = { (uintptr_t)0 }; + +DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor; + +#define STUB_DESCRIPTOR "{\"version\":0,\"baseline\":\"empty\",\"contracts\":{},\"types\":{},\"globals\":{}}" + +DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor = { + .magic = 0x0043414443434e44ull, // "DNCCDAC\0" + .flags = 0x1u & (sizeof(void*) == 4 ? 0x02u : 0x00u), + .descriptor_size = sizeof(STUB_DESCRIPTOR), + .descriptor = STUB_DESCRIPTOR, + .pointer_data_count = 1, + .pointer_data = &contractDescriptorPointerData[0], +}; diff --git a/src/coreclr/debug/runtimeinfo/contractpointerdata.cpp b/src/coreclr/debug/runtimeinfo/contractpointerdata.cpp new file mode 100644 index 00000000000000..ae1440af4219a2 --- /dev/null +++ b/src/coreclr/debug/runtimeinfo/contractpointerdata.cpp @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" + +#include +#include + +#include "threads.h" + +extern "C" +{ + +// without an extern declaration, clang does not emit this global into the object file +extern const uintptr_t contractDescriptorPointerData[]; + +const uintptr_t contractDescriptorPointerData[] = { + (uintptr_t)0, // placeholder +#define CDAC_GLOBAL_POINTER(name,value) (uintptr_t)(value), +#include "datadescriptor.h" +}; + +} diff --git a/src/coreclr/debug/runtimeinfo/contracts.jsonc b/src/coreclr/debug/runtimeinfo/contracts.jsonc new file mode 100644 index 00000000000000..186230d5c68d6f --- /dev/null +++ b/src/coreclr/debug/runtimeinfo/contracts.jsonc @@ -0,0 +1,14 @@ +//algorithmic contracts for coreclr +// The format of this file is: JSON with comments +// { +// "CONTRACT NAME": VERSION, +// ... +// } +// CONTRACT NAME is an arbitrary string, VERSION is an integer +// +// cdac-build-tool can take multiple "-c contract_file" arguments +// so to conditionally include contracts, put additional contracts in a separate file +{ + "SOSBreakingChangeVersion": 1 // example contract: "runtime exports an SOS breaking change version global" +} + diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.cpp b/src/coreclr/debug/runtimeinfo/datadescriptor.cpp new file mode 100644 index 00000000000000..99fe1cca7eeca7 --- /dev/null +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.cpp @@ -0,0 +1,297 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "common.h" + +#include +#include + +#include "static_assert.h" + +#include +#include "threads.h" + +// begin blob definition + +extern "C" +{ + +struct TypeSpec +{ + uint32_t Name; + uint32_t Fields; + uint16_t Size; // note: C++ fragile no designated initializers - Size must come after Name and Fields +}; + +struct FieldSpec +{ + uint32_t Name; + uint32_t TypeName; + uint16_t FieldOffset; +}; + +struct GlobalLiteralSpec +{ + uint32_t Name; + uint32_t TypeName; + uint64_t Value; +}; + +struct GlobalPointerSpec +{ + uint32_t Name; + uint32_t PointerDataIndex; +}; + +#define CONCAT(token1,token2) token1 ## token2 +#define CONCAT4(token1, token2, token3, token4) token1 ## token2 ## token3 ## token4 + +#define MAKE_TYPELEN_NAME(tyname) CONCAT(cdac_string_pool_typename__, tyname) +#define MAKE_FIELDLEN_NAME(tyname,membername) CONCAT4(cdac_string_pool_membername__, tyname, __, membername) +#define MAKE_FIELDTYPELEN_NAME(tyname,membername) CONCAT4(cdac_string_pool_membertypename__, tyname, __, membername) +#define MAKE_GLOBALLEN_NAME(globalname) CONCAT(cdac_string_pool_globalname__, globalname) +#define MAKE_GLOBALTYPELEN_NAME(globalname) CONCAT(cdac_string_pool_globaltypename__, globalname) + +// define a struct where the size of each field is the length of some string. we will use offsetof to get +// the offset of each struct element, which will be equal to the offset of the beginning of that string in the +// string pool. +struct CDacStringPoolSizes +{ + char cdac_string_pool_nil; // make the first real string start at offset 1 +#define DECL_LEN(membername,len) char membername[(len)]; +#define CDAC_BASELINE(name) DECL_LEN(cdac_string_pool_baseline_, (sizeof(name))) +#define CDAC_TYPE_BEGIN(name) DECL_LEN(MAKE_TYPELEN_NAME(name), sizeof(#name)) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) DECL_LEN(MAKE_FIELDLEN_NAME(tyname,membername), sizeof(#membername)) \ + DECL_LEN(MAKE_FIELDTYPELEN_NAME(tyname,membername), sizeof(#membertyname)) +#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) +#define CDAC_GLOBAL(name,tyname,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) \ + DECL_LEN(MAKE_GLOBALTYPELEN_NAME(name), sizeof(#tyname)) +#include "datadescriptor.h" + char cdac_string_pool_trailing_nil; +#undef DECL_LEN +}; + +#define GET_TYPE_NAME(name) offsetof(struct CDacStringPoolSizes, MAKE_TYPELEN_NAME(name)) +#define GET_FIELD_NAME(tyname,membername) offsetof(struct CDacStringPoolSizes, MAKE_FIELDLEN_NAME(tyname,membername)) +#define GET_FIELDTYPE_NAME(tyname,membername) offsetof(struct CDacStringPoolSizes, MAKE_FIELDTYPELEN_NAME(tyname,membername)) +#define GET_GLOBAL_NAME(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALLEN_NAME(globalname)) +#define GET_GLOBALTYPE_NAME(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALTYPELEN_NAME(globalname)) + +// count the types +enum +{ + CDacBlobTypesCount = +#define CDAC_TYPES_BEGIN() 0 +#define CDAC_TYPE_BEGIN(name) + 1 +#include "datadescriptor.h" +}; + +// count the field pool size. +// there's 1 placeholder element at the start, and 1 endmarker after each type +enum +{ + CDacBlobFieldsPoolCount = +#define CDAC_TYPES_BEGIN() 1 +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) + 1 +#define CDAC_TYPE_END(name) + 1 +#include "datadescriptor.h" +}; + +// count the literal globals +enum +{ + CDacBlobGlobalLiteralsCount = +#define CDAC_GLOBALS_BEGIN() 0 +#define CDAC_GLOBAL(name,tyname,value) + 1 +#include "datadescriptor.h" +}; + +// count the aux vector globals +enum +{ + CDacBlobGlobalPointersCount = +#define CDAC_GLOBALS_BEGIN() 0 +#define CDAC_GLOBAL_POINTER(name,value) + 1 +#include "datadescriptor.h" +}; + + +#define MAKE_TYPEFIELDS_TYNAME(tyname) CONCAT(CDacFieldsPoolTypeStart__, tyname) + +// index of each run of fields. +// we make a struct containing one 1-byte field for each field in the run, and then take the offset of the +// struct to get the index of the run of fields. +// this looks like +// +// struct CDacFieldsPoolSizes { +// char cdac_fields_pool_start_placeholder__; +// struct CDacFieldsPoolTypeStart__MethodTable { +// char cdac_fields_pool_member__MethodTable__GCHandle; +// char cdac_fields_pool_member__MethodTable_endmarker; +// } CDacFieldsPoolTypeStart__MethodTable; +// ... +// }; +// +// so that offsetof(struct CDacFieldsPoolSizes, CDacFieldsPoolTypeStart__MethodTable) will give the offset of the +// method table field descriptors in the run of fields +struct CDacFieldsPoolSizes +{ +#define DECL_LEN(membername) char membername; +#define CDAC_TYPES_BEGIN() DECL_LEN(cdac_fields_pool_start_placeholder__) +#define CDAC_TYPE_BEGIN(name) struct MAKE_TYPEFIELDS_TYNAME(name) { +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, __, membername)) +#define CDAC_TYPE_END(name) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, _, endmarker)) \ + } MAKE_TYPEFIELDS_TYNAME(name); +#include "datadescriptor.h" +#undef DECL_LEN +}; + +#define GET_TYPE_FIELDS(tyname) offsetof(struct CDacFieldsPoolSizes, MAKE_TYPEFIELDS_TYNAME(tyname)) + +// index of each global pointer +// +// struct CDacGlobalPointerIndex +// { +// char placeholder; +// char firstGlobalPointerName; +// char secondGlobalPointerName; +// ... +//} +// +// offsetof (CDACGlobalPointerIndex, NAME) returns the index of the global +struct CDacGlobalPointerIndex +{ +#define DECL_LEN(membername) char membername; +#define CDAC_GLOBALS_BEGIN() DECL_LEN(cdac_global_pointer_index_start_placeholder__) +#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(CONCAT(cdac_global_pointer_index__, name)) +#include "datadescriptor.h" +#undef DECL_LEN +}; + +#define GET_GLOBAL_POINTER_INDEX(name) offsetof(struct CDacGlobalPointerIndex, CONCAT(cdac_global_pointer_index__, name)) + +struct BinaryBlobDataDescriptor +{ + // The blob begins with a directory that gives the relative offsets of the `Baseline`, `Types`, + // `FieldsPool`, `GlobalLiteralValues`, `GlobalPointerValues` and `Names` fields of the blob. + // The number of elements of each of the arrays is next. This is followed by the sizes of the + // spec structs. Since `BinaryBlobDataDescriptor` is created via macros, we want to embed the + // `offsetof` and `sizeof` of the components of the blob into the blob itself without having to + // account for any padding that the C/C++ compiler may introduce to enforce alignment. + // Additionally the `Directory` tries to follow a common C/C++ alignment rule (we don't want + // padding introduced in the directory itself): N-byte members are aligned to start on N-byte + // boundaries. + struct Directory { + uint32_t FlagsAndBaselineStart; + uint32_t TypesStart; + + uint32_t FieldsPoolStart; + uint32_t GlobalLiteralValuesStart; + + uint32_t GlobalPointersStart; + uint32_t NamesPoolStart; + + uint32_t TypeCount; + uint32_t FieldsPoolCount; + + uint32_t GlobalLiteralValuesCount; + uint32_t GlobalPointerValuesCount; + + uint32_t NamesPoolCount; + + uint8_t TypeSpecSize; + uint8_t FieldSpecSize; + uint8_t GlobalLiteralSpecSize; + uint8_t GlobalPointerSpecSize; + } Directory; + uint32_t PlatformFlags; + uint32_t BaselineName; + struct TypeSpec Types[CDacBlobTypesCount]; + struct FieldSpec FieldsPool[CDacBlobFieldsPoolCount]; + struct GlobalLiteralSpec GlobalLiteralValues[CDacBlobGlobalLiteralsCount]; + struct GlobalPointerSpec GlobalPointerValues[CDacBlobGlobalPointersCount]; + uint8_t NamesPool[sizeof(struct CDacStringPoolSizes)]; + uint8_t EndMagic[4]; +}; + +struct MagicAndBlob { + uint64_t magic; + struct BinaryBlobDataDescriptor Blob; +}; + +// we only support 32-bit and 64-bit right now +static_assert_no_msg(sizeof(void*) == 4 || sizeof(void*) == 8); + +// C-style designated initializers are a C++20 feature. Have to use plain old aggregate initialization instead. + +DLLEXPORT +struct MagicAndBlob BlobDataDescriptor = { + /*.magic = */ 0x00424F4C42434144ull,// "DACBLOB", + /*.Blob =*/ { + /*.Directory =*/ { + /* .FlagsAndBaselineStart = */ offsetof(struct BinaryBlobDataDescriptor, PlatformFlags), + /* .TypesStart = */ offsetof(struct BinaryBlobDataDescriptor, Types), + /* .FieldsPoolStart = */ offsetof(struct BinaryBlobDataDescriptor, FieldsPool), + /* .GlobalLiteralValuesStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalLiteralValues), + /* .GlobalPointersStart = */ offsetof(struct BinaryBlobDataDescriptor, GlobalPointerValues), + /* .NamesPoolStart = */ offsetof(struct BinaryBlobDataDescriptor, NamesPool), + /* .TypeCount = */ CDacBlobTypesCount, + /* .FieldsPoolCount = */ CDacBlobFieldsPoolCount, + /* .GlobalLiteralValuesCount = */ CDacBlobGlobalLiteralsCount, + /* .GlobalPointerValuesCount = */ CDacBlobGlobalPointersCount, + /* .NamesPoolCount = */ sizeof(struct CDacStringPoolSizes), + /* .TypeSpecSize = */ sizeof(struct TypeSpec), + /* .FieldSpecSize = */ sizeof(struct FieldSpec), + /* .GlobalLiteralSpecSize = */ sizeof(struct GlobalLiteralSpec), + /* .GlobalPointerSpecSize = */ sizeof(struct GlobalPointerSpec), + }, + /* .PlatformFlags = */ (sizeof(void*) == 4 ? 0x02 : 0) | 0x01, + /* .BaselineName = */ offsetof(struct CDacStringPoolSizes, cdac_string_pool_baseline_), + + /* .Types = */ { +#define CDAC_TYPE_BEGIN(name) { \ + /* .Name = */ GET_TYPE_NAME(name), \ + /* .Fields = */ GET_TYPE_FIELDS(name), +#define CDAC_TYPE_INDETERMINATE(name) /*.Size = */ 0, +#define CDAC_TYPE_SIZE(size) /* .Size = */ size, +#define CDAC_TYPE_END(name) }, +#include "datadescriptor.h" + }, + + /* .FieldsPool = */ { +#define CDAC_TYPES_BEGIN() {0,}, +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) { \ + /* .Name = */ GET_FIELD_NAME(tyname,membername), \ + /* .TypeName = */ GET_FIELDTYPE_NAME(tyname,membername), \ + /* .FieldOffset = */ offset, \ +}, +#define CDAC_TYPE_END(name) { 0, }, +#include "datadescriptor.h" + }, + + /* .GlobalLiteralValues = */ { +#define CDAC_GLOBAL(name,tyname,value) { /*.Name = */ GET_GLOBAL_NAME(name), /* .TypeName = */ GET_GLOBALTYPE_NAME(name), /* .Value = */ value }, +#include "datadescriptor.h" + }, + + /* .GlobalPointerValues = */ { +#define CDAC_GLOBAL_POINTER(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .PointerDataIndex = */ GET_GLOBAL_POINTER_INDEX(name) }, +#include "datadescriptor.h" + }, + + /* .NamesPool = */ ("\0" // starts with a nul +#define CDAC_BASELINE(name) name "\0" +#define CDAC_TYPE_BEGIN(name) #name "\0" +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) #membername "\0" #membertyname "\0" +#define CDAC_GLOBAL_POINTER(name,value) #name "\0" +#define CDAC_GLOBAL(name,tyname,value) #name "\0" #tyname "\0" +#include "datadescriptor.h" + ), + + /* .EndMagic = */ { 0x01, 0x02, 0x03, 0x04 }, + } +}; + +// end blob definition + +} // extern "C" diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h new file mode 100644 index 00000000000000..b5ab51774e1215 --- /dev/null +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -0,0 +1,139 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// No include guards. This file is included multiple times. + +// The format is: +// CDAC_BASELINE("string") baseline data contract that the runtime should follow. "empty" is reasonable +// CDAC_TYPES_BEGIN() +// ... ... +// CDAC_TYPES_END() +// CDAC_GLOBALS_BEGIN() +// ... ... +// CDAC_GLOBALS_END() +// +// In the format is: +// CDAC_TYPE_BEGIN(cdacTypeIdentifier) // defined a new data descriptor named cdacIdentifier +// +// CDAC_TYPE_SIZE(k) -or- CDAC_TYPE_INDETERMINATE(cdacTypeIdentifier) specifies that the type has +// size k (bytes - usually sizeof(SomeNativeType)) or specify that the type's size is not provided +// It is important that CDAC_TYPE_SIZE or CDAC_TYPE_INDETERMINATE immediately follows +// CDAC_TYPE_BEGIN +// +// CDAC_TYPE_FIELD(cdacTypeIdentifier, cdacFieldTypeIdentifier, cdacFieldName, k) specifies the +// field of "cdacTypeIdentifier" that has name cdacFieldName and has the type +// "cdacFieldtypeIdentifier" located at offset k in the type layout. k is usually +// offsetof(SomeClass, m_FieldName) if the field is public +// +// if the field is private, the convention is that SomeClass declares a friend struct +// cdac_offsets and provides a specialization of cdac_offsets with a public constexpr +// size_t member that holds the offset: +// +// class MyClass { +// private: +// void* m_myField; +// friend template cdac_offsets; +// }; +// template<> struct cdac_offsets { +// static constexpr size_t MyField = offsetof(MyClass, m_myField); +// }; +// +// then the field layout can be specified as +// CDAC_TYPE_FIELD(MyClassLayout, pointer, MyField, cdac_offsets::MyField) +// There can be zero or more CDAC_TYPE_FIELD entries per type layout +// +// CDAC_TYPE_END(cdacTypeIdentifier) specifies the end of the type layout for cdacTypeIdentifier +// +// In the format is: +// +// CDAC_GLOBAL(cdacGlobalName, cdacTypeIdentifier, value) +// or +// CDAC_GLOBAL_POINTER(cdacGlobalName, cdacTypeIdentifier, address) +// +// Zero or more globals can be defined +// +// if a global is given with CDAC_GLOBAL(), `value` should be a constexpr uint64_t (or convertible +// to uint64_t) for example, it can be a literal constant or a preprocessor definition +// +// if a global is a CDAC_GLOBAL_POINTER(), address should be a constexpr pointer or a constexpr +// uintptr_t +// +// +// +// This file is compiled using the target architecture. Preprocessor defines for the target +// platform will be available. It is ok to use `#ifdef`. + +#ifndef CDAC_BASELINE +#define CDAC_BASELINE(identifier) +#endif +#ifndef CDAC_TYPES_BEGIN +#define CDAC_TYPES_BEGIN() +#endif +#ifndef CDAC_TYPE_BEGIN +#define CDAC_TYPE_BEGIN(tyname) +#endif +#ifndef CDAC_TYPE_SIZE +#define CDAC_TYPE_SIZE(k) +#endif +#ifndef CDAC_TYPE_INDETERMINATE +#define CDAC_TYPE_INDETERMINATE(tyname) +#endif +#ifndef CDAC_TYPE_FIELD +#define CDAC_TYPE_FIELD(tyname,fieldtyname,fieldname,off) +#endif +#ifndef CDAC_TYPE_END +#define CDAC_TYPE_END(tyname) +#endif +#ifndef CDAC_TYPES_END +#define CDAC_TYPES_END() +#endif +#ifndef CDAC_GLOBALS_BEGIN +#define CDAC_GLOBALS_BEGIN() +#endif +#ifndef CDAC_GLOBAL +#define CDAC_GLOBAL(globalname,tyname,val) +#endif +#ifndef CDAC_GLOBAL_POINTER +#define CDAC_GLOBAL_POINTER(globalname,addr) +#endif +#ifndef CDAC_GLOBALS_END +#define CDAC_GLOBALS_END() +#endif + +CDAC_BASELINE("empty") +CDAC_TYPES_BEGIN() + +CDAC_TYPE_BEGIN(ManagedThread) +CDAC_TYPE_INDETERMINATE(ManagedThread) +CDAC_TYPE_FIELD(ManagedThread, GCHandle, GCHandle, cdac_offsets::ExposedObject) +CDAC_TYPE_FIELD(ManagedThread, pointer, LinkNext, cdac_offsets::Link) +CDAC_TYPE_END(ManagedThread) + +CDAC_TYPE_BEGIN(GCHandle) +CDAC_TYPE_SIZE(sizeof(OBJECTHANDLE)) +CDAC_TYPE_END(GCHandle) + +CDAC_TYPES_END() + +CDAC_GLOBALS_BEGIN() +CDAC_GLOBAL_POINTER(ManagedThreadStore, &ThreadStore::s_pThreadStore) +#if FEATURE_EH_FUNCLETS +CDAC_GLOBAL(FeatureEHFunclets, uint8, 1) +#else +CDAC_GLOBAL(FeatureEHFunclets, uint8, 0) +#endif +CDAC_GLOBAL(SOSBreakingChangeVersion, uint8, SOS_BREAKING_CHANGE_VERSION) +CDAC_GLOBALS_END() + +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef CDAC_TYPES_END +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBALS_END diff --git a/src/coreclr/debug/shared/dbgtransportsession.cpp b/src/coreclr/debug/shared/dbgtransportsession.cpp index 3bebb8282aed7d..f03a62c62ea994 100644 --- a/src/coreclr/debug/shared/dbgtransportsession.cpp +++ b/src/coreclr/debug/shared/dbgtransportsession.cpp @@ -2203,6 +2203,7 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) case DB_IPCE_BEFORE_GARBAGE_COLLECTION: case DB_IPCE_AFTER_GARBAGE_COLLECTION: case DB_IPCE_DISABLE_OPTS_RESULT: + case DB_IPCE_CATCH_HANDLER_FOUND_RESULT: cbAdditionalSize = 0; break; @@ -2501,6 +2502,9 @@ DWORD DbgTransportSession::GetEventSize(DebuggerIPCEvent *pEvent) case DB_IPCE_DISABLE_OPTS: cbAdditionalSize = sizeof(pEvent->DisableOptData); break; + case DB_IPCE_FORCE_CATCH_HANDLER_FOUND: + cbAdditionalSize = sizeof(pEvent->ForceCatchHandlerFoundData); + break; default: STRESS_LOG1(LF_CORDB, LL_INFO1000, "Unknown debugger event type: 0x%x\n", (pEvent->type & DB_IPCE_TYPE_MASK)); diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index c600af1fb6aada..7ba58d0297f9a9 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -109,6 +109,7 @@ set(CORECLR_LIBRARIES interop coreclrminipal gc_pal + cdac_contract_descriptor ) if(CLR_CMAKE_TARGET_ARCH_AMD64) diff --git a/src/coreclr/dlls/mscoree/mscorwks_ntdef.src b/src/coreclr/dlls/mscoree/mscorwks_ntdef.src index 0ac421b63e0718..a2076bd62433c9 100644 --- a/src/coreclr/dlls/mscoree/mscorwks_ntdef.src +++ b/src/coreclr/dlls/mscoree/mscorwks_ntdef.src @@ -28,3 +28,6 @@ EXPORTS ; Used by profilers MetaDataGetDispenser + + ; cDAC contract descriptor + DotNetRuntimeContractDescriptor diff --git a/src/coreclr/dlls/mscoree/mscorwks_unixexports.src b/src/coreclr/dlls/mscoree/mscorwks_unixexports.src index a35a59c095604a..3eacb7fa484856 100644 --- a/src/coreclr/dlls/mscoree/mscorwks_unixexports.src +++ b/src/coreclr/dlls/mscoree/mscorwks_unixexports.src @@ -14,3 +14,6 @@ g_dacTable ; Used by profilers MetaDataGetDispenser + +; cDAC contract descriptor +DotNetRuntimeContractDescriptor diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index e43047cf6e113a..9b6f5515e37a5e 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -388,7 +388,7 @@ int relative_index_power2_free_space (size_t power2) #ifdef BACKGROUND_GC uint32_t bgc_alloc_spin_count = 140; -uint32_t bgc_alloc_spin_count_loh = 16; +uint32_t bgc_alloc_spin_count_uoh = 16; uint32_t bgc_alloc_spin = 2; inline @@ -2657,13 +2657,10 @@ size_t gc_heap::end_loh_size = 0; size_t gc_heap::bgc_begin_poh_size = 0; size_t gc_heap::end_poh_size = 0; +size_t gc_heap::uoh_a_no_bgc[uoh_generation_count] = {}; +size_t gc_heap::uoh_a_bgc_marking[uoh_generation_count] = {}; +size_t gc_heap::uoh_a_bgc_planning[uoh_generation_count] = {}; #ifdef BGC_SERVO_TUNING -uint64_t gc_heap::loh_a_no_bgc = 0; - -uint64_t gc_heap::loh_a_bgc_marking = 0; - -uint64_t gc_heap::loh_a_bgc_planning = 0; - size_t gc_heap::bgc_maxgen_end_fl_size = 0; #endif //BGC_SERVO_TUNING @@ -2794,9 +2791,9 @@ FinalizerWorkItem* gc_heap::finalizer_work; BOOL gc_heap::proceed_with_gc_p = FALSE; GCSpinLock gc_heap::gc_lock; -#ifdef BGC_SERVO_TUNING -uint64_t gc_heap::total_loh_a_last_bgc = 0; -#endif //BGC_SERVO_TUNING +#ifdef BACKGROUND_GC +uint64_t gc_heap::total_uoh_a_last_bgc = 0; +#endif //BACKGROUND_GC #ifdef USE_REGIONS region_free_list gc_heap::global_regions_to_decommit[count_free_region_kinds]; @@ -15039,10 +15036,13 @@ gc_heap::init_gc_heap (int h_number) make_mark_stack(arr); #ifdef BACKGROUND_GC + for (int i = uoh_start_generation; i < total_generation_count; i++) + { + uoh_a_no_bgc[i - uoh_start_generation] = 0; + uoh_a_bgc_marking[i - uoh_start_generation] = 0; + uoh_a_bgc_planning[i - uoh_start_generation] = 0; + } #ifdef BGC_SERVO_TUNING - loh_a_no_bgc = 0; - loh_a_bgc_marking = 0; - loh_a_bgc_planning = 0; bgc_maxgen_end_fl_size = 0; #endif //BGC_SERVO_TUNING freeable_soh_segment = 0; @@ -18424,6 +18424,29 @@ bool gc_heap::should_retry_other_heap (int gen_number, size_t size) } } +void gc_heap::bgc_record_uoh_allocation(int gen_number, size_t size) +{ + assert((gen_number >= uoh_start_generation) && (gen_number < total_generation_count)); + + if (gc_heap::background_running_p()) + { + background_uoh_alloc_count++; + + if (current_c_gc_state == c_gc_state_planning) + { + uoh_a_bgc_planning[gen_number - uoh_start_generation] += size; + } + else + { + uoh_a_bgc_marking[gen_number - uoh_start_generation] += size; + } + } + else + { + uoh_a_no_bgc[gen_number - uoh_start_generation] += size; + } +} + allocation_state gc_heap::allocate_uoh (int gen_number, size_t size, alloc_context* acontext, @@ -18446,26 +18469,12 @@ allocation_state gc_heap::allocate_uoh (int gen_number, #endif //RECORD_LOH_STATE #ifdef BACKGROUND_GC + bgc_record_uoh_allocation(gen_number, size); + if (gc_heap::background_running_p()) { -#ifdef BGC_SERVO_TUNING - bool planning_p = (current_c_gc_state == c_gc_state_planning); -#endif //BGC_SERVO_TUNING - - background_uoh_alloc_count++; - //if ((background_loh_alloc_count % bgc_alloc_spin_count_loh) == 0) + //if ((background_uoh_alloc_count % bgc_alloc_spin_count_uoh) == 0) { -#ifdef BGC_SERVO_TUNING - if (planning_p) - { - loh_a_bgc_planning += size; - } - else - { - loh_a_bgc_marking += size; - } -#endif //BGC_SERVO_TUNING - int spin_for_allocation = (gen_number == loh_generation) ? bgc_loh_allocate_spin() : bgc_poh_allocate_spin(); @@ -18491,12 +18500,6 @@ allocation_state gc_heap::allocate_uoh (int gen_number, } } } -#ifdef BGC_SERVO_TUNING - else - { - loh_a_no_bgc += size; - } -#endif //BGC_SERVO_TUNING #endif //BACKGROUND_GC gc_reason gr = reason_oos_loh; @@ -29966,7 +29969,7 @@ void gc_heap::mark_phase (int condemned_gen_number) #endif //MULTIPLE_HEAPS { #ifdef FEATURE_EVENT_TRACE - record_mark_time (gc_time_info[time_plan - 1], current_mark_time, last_mark_time); + record_mark_time (gc_time_info[time_mark_long_weak], current_mark_time, last_mark_time); gc_time_info[time_plan] = last_mark_time; #endif //FEATURE_EVENT_TRACE @@ -33964,26 +33967,12 @@ void gc_heap::plan_phase (int condemned_gen_number) if (gc_t_join.joined()) #endif //MULTIPLE_HEAPS { -#ifdef FEATURE_EVENT_TRACE - if (informational_event_enabled_p) - { - uint64_t current_time = GetHighPrecisionTimeStamp(); - gc_time_info[time_compact] = current_time - gc_time_info[time_compact]; - } -#endif //FEATURE_EVENT_TRACE - #ifdef MULTIPLE_HEAPS for (int i = 0; i < n_heaps; i++) { -#ifdef USE_REGIONS - g_heaps [i]->rearrange_uoh_segments(); -#endif //USE_REGIONS g_heaps [i]->rearrange_heap_segments (TRUE); } #else //MULTIPLE_HEAPS -#ifdef USE_REGIONS - rearrange_uoh_segments(); -#endif //USE_REGIONS rearrange_heap_segments (TRUE); #endif //MULTIPLE_HEAPS @@ -34018,7 +34007,7 @@ void gc_heap::plan_phase (int condemned_gen_number) #endif //MULTIPLE_HEAPS #ifdef FEATURE_EVENT_TRACE - if (informational_event_enabled_p && (condemned_gen_number < (max_generation -1))) + if (informational_event_enabled_p) { uint64_t current_time = GetHighPrecisionTimeStamp(); gc_time_info[time_compact] = current_time - gc_time_info[time_compact]; @@ -40638,7 +40627,7 @@ void gc_heap::bgc_tuning::record_and_adjust_bgc_end() calculate_tuning (max_generation, true); - if (total_loh_a_last_bgc > 0) + if (total_uoh_a_last_bgc > 0) { calculate_tuning (loh_generation, true); } @@ -45835,9 +45824,6 @@ void gc_heap::background_sweep() concurrent_print_time_delta ("Sw"); dprintf (2, ("---- (GC%zu)Background Sweep Phase ----", VolatileLoad(&settings.gc_index))); - //block concurrent allocation for large objects - dprintf (3, ("lh state: planning")); - for (int i = 0; i <= max_generation; i++) { generation* gen_to_reset = generation_of (i); @@ -45886,6 +45872,9 @@ void gc_heap::background_sweep() sweep_ro_segments(); #endif //FEATURE_BASICFREEZE + dprintf (3, ("lh state: planning")); + + // Multiple threads may reach here. This conditional partially avoids multiple volatile writes. if (current_c_gc_state != c_gc_state_planning) { current_c_gc_state = c_gc_state_planning; @@ -45916,9 +45905,7 @@ void gc_heap::background_sweep() if (heap_number == 0) { -#ifdef BGC_SERVO_TUNING - get_and_reset_loh_alloc_info(); -#endif //BGC_SERVO_TUNING + get_and_reset_uoh_alloc_info(); uint64_t suspended_end_ts = GetHighPrecisionTimeStamp(); last_bgc_info[last_bgc_info_index].pause_durations[1] = (size_t)(suspended_end_ts - suspended_start_time); total_suspended_time += last_bgc_info[last_bgc_info_index].pause_durations[1]; @@ -46247,6 +46234,7 @@ void gc_heap::background_sweep() concurrent_print_time_delta ("Swe SOH"); FIRE_EVENT(BGC1stSweepEnd, 0); + //block concurrent allocation for UOH objects enter_spin_lock (&more_space_lock_uoh); add_saved_spinlock_info (true, me_acquire, mt_bgc_uoh_sweep, msl_entered); @@ -46302,6 +46290,15 @@ void gc_heap::background_sweep() // be accurate. compute_new_dynamic_data (max_generation); + // We also need to adjust size_before for UOH allocations that occurred during sweeping. + gc_history_per_heap* current_gc_data_per_heap = get_gc_data_per_heap(); + for (int i = uoh_start_generation; i < total_generation_count; i++) + { + assert(uoh_a_bgc_marking[i - uoh_start_generation] == 0); + assert(uoh_a_no_bgc[i - uoh_start_generation] == 0); + current_gc_data_per_heap->gen_data[i].size_before += uoh_a_bgc_planning[i - uoh_start_generation]; + } + #ifdef DOUBLY_LINKED_FL current_bgc_state = bgc_not_in_process; @@ -50271,17 +50268,15 @@ void gc_heap::check_and_adjust_bgc_tuning (int gen_number, size_t physical_size, } } } +#endif //BGC_SERVO_TUNING -void gc_heap::get_and_reset_loh_alloc_info() +void gc_heap::get_and_reset_uoh_alloc_info() { - if (!bgc_tuning::enable_fl_tuning) - return; + total_uoh_a_last_bgc = 0; - total_loh_a_last_bgc = 0; - - uint64_t total_loh_a_no_bgc = 0; - uint64_t total_loh_a_bgc_marking = 0; - uint64_t total_loh_a_bgc_planning = 0; + uint64_t total_uoh_a_no_bgc = 0; + uint64_t total_uoh_a_bgc_marking = 0; + uint64_t total_uoh_a_bgc_planning = 0; #ifdef MULTIPLE_HEAPS for (int i = 0; i < gc_heap::n_heaps; i++) { @@ -50290,21 +50285,32 @@ void gc_heap::get_and_reset_loh_alloc_info() { gc_heap* hp = pGenGCHeap; #endif //MULTIPLE_HEAPS - total_loh_a_no_bgc += hp->loh_a_no_bgc; - hp->loh_a_no_bgc = 0; - total_loh_a_bgc_marking += hp->loh_a_bgc_marking; - hp->loh_a_bgc_marking = 0; - total_loh_a_bgc_planning += hp->loh_a_bgc_planning; - hp->loh_a_bgc_planning = 0; + + // We need to adjust size_before for UOH allocations that occurred during marking + // before we lose the values here. + gc_history_per_heap* current_gc_data_per_heap = hp->get_gc_data_per_heap(); + // loh/poh_a_bgc_planning should be the same as they were when init_records set size_before. + for (int i = uoh_start_generation; i < total_generation_count; i++) + { + current_gc_data_per_heap->gen_data[i].size_before += hp->uoh_a_bgc_marking[i - uoh_start_generation]; + + total_uoh_a_no_bgc += hp->uoh_a_no_bgc[i - uoh_start_generation]; + hp->uoh_a_no_bgc[i - uoh_start_generation] = 0; + + total_uoh_a_bgc_marking += hp->uoh_a_bgc_marking[i - uoh_start_generation]; + hp->uoh_a_bgc_marking[i - uoh_start_generation] = 0; + + total_uoh_a_bgc_planning += hp->uoh_a_bgc_planning[i - uoh_start_generation]; + hp->uoh_a_bgc_planning[i - uoh_start_generation] = 0; + } } dprintf (2, ("LOH alloc: outside bgc: %zd; bm: %zd; bp: %zd", - total_loh_a_no_bgc, - total_loh_a_bgc_marking, - total_loh_a_bgc_planning)); + total_uoh_a_no_bgc, + total_uoh_a_bgc_marking, + total_uoh_a_bgc_planning)); - total_loh_a_last_bgc = total_loh_a_no_bgc + total_loh_a_bgc_marking + total_loh_a_bgc_planning; + total_uoh_a_last_bgc = total_uoh_a_no_bgc + total_uoh_a_bgc_marking + total_uoh_a_bgc_planning; } -#endif //BGC_SERVO_TUNING bool gc_heap::is_pm_ratio_exceeded() { diff --git a/src/coreclr/gc/gc.h b/src/coreclr/gc/gc.h index a1093b5e76ceca..e80853489a2410 100644 --- a/src/coreclr/gc/gc.h +++ b/src/coreclr/gc/gc.h @@ -124,7 +124,10 @@ enum gc_generation_num ephemeral_generation_count = max_generation, // number of all generations - total_generation_count = poh_generation + 1 + total_generation_count = poh_generation + 1, + + // number of uoh generations + uoh_generation_count = total_generation_count - uoh_start_generation }; #ifdef GC_CONFIG_DRIVEN diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 6db2e06d04c004..757f816c639fd3 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -140,10 +140,10 @@ inline void FATAL_GC_ERROR() // // This means any empty regions can be freely used for any generation. For // Server GC we will balance regions between heaps. -// For now disable regions for StandAlone GC, NativeAOT and MacOS builds +// For now disable regions for standalone GC and macOS builds #if defined (HOST_64BIT) && !defined (BUILD_AS_STANDALONE) && !defined(__APPLE__) #define USE_REGIONS -#endif //HOST_64BIT && BUILD_AS_STANDALONE +#endif //HOST_64BIT && BUILD_AS_STANDALONE && !__APPLE__ //#define SPINLOCK_HISTORY //#define RECORD_LOH_STATE @@ -1752,6 +1752,8 @@ class gc_heap PER_HEAP_ISOLATED_METHOD void add_to_history(); + PER_HEAP_ISOLATED_METHOD void get_and_reset_uoh_alloc_info(); + #ifdef BGC_SERVO_TUNING // Currently BGC servo tuning is an experimental feature. class bgc_tuning @@ -1997,7 +1999,6 @@ class gc_heap }; PER_HEAP_ISOLATED_METHOD void check_and_adjust_bgc_tuning (int gen_number, size_t physical_size, ptrdiff_t virtual_fl_size); - PER_HEAP_ISOLATED_METHOD void get_and_reset_loh_alloc_info(); #endif //BGC_SERVO_TUNING #ifndef USE_REGIONS @@ -2230,6 +2231,8 @@ class gc_heap PER_HEAP_METHOD BOOL bgc_loh_allocate_spin(); PER_HEAP_METHOD BOOL bgc_poh_allocate_spin(); + + PER_HEAP_METHOD void bgc_record_uoh_allocation(int gen_number, size_t size); #endif //BACKGROUND_GC PER_HEAP_METHOD void add_saved_spinlock_info ( @@ -3436,6 +3439,11 @@ class gc_heap PER_HEAP_FIELD_SINGLE_GC uint8_t* next_sweep_obj; PER_HEAP_FIELD_SINGLE_GC uint8_t* current_sweep_pos; + + PER_HEAP_FIELD_SINGLE_GC size_t uoh_a_no_bgc[uoh_generation_count]; + PER_HEAP_FIELD_SINGLE_GC size_t uoh_a_bgc_marking[uoh_generation_count]; + PER_HEAP_FIELD_SINGLE_GC size_t uoh_a_bgc_planning[uoh_generation_count]; + #ifdef DOUBLY_LINKED_FL PER_HEAP_FIELD_SINGLE_GC heap_segment* current_sweep_seg; #endif //DOUBLY_LINKED_FL @@ -3461,9 +3469,6 @@ class gc_heap #endif //SNOOP_STATS #ifdef BGC_SERVO_TUNING - PER_HEAP_FIELD_SINGLE_GC uint64_t loh_a_no_bgc; - PER_HEAP_FIELD_SINGLE_GC uint64_t loh_a_bgc_marking; - PER_HEAP_FIELD_SINGLE_GC uint64_t loh_a_bgc_planning; PER_HEAP_FIELD_SINGLE_GC size_t bgc_maxgen_end_fl_size; #endif //BGC_SERVO_TUNING #endif //BACKGROUND_GC @@ -4097,11 +4102,9 @@ class gc_heap PER_HEAP_ISOLATED_FIELD_SINGLE_GC GCEvent bgc_start_event; -#ifdef BGC_SERVO_TUNING // Total allocated last BGC's plan + between last and this bgc + // this bgc's mark - PER_HEAP_ISOLATED_FIELD_SINGLE_GC uint64_t total_loh_a_last_bgc; -#endif //BGC_SERVO_TUNING + PER_HEAP_ISOLATED_FIELD_SINGLE_GC uint64_t total_uoh_a_last_bgc; #endif //BACKGROUND_GC #ifdef USE_REGIONS diff --git a/src/coreclr/ildasm/dis.cpp b/src/coreclr/ildasm/dis.cpp index 2ad1ecd2d200a1..aae2e7ab472773 100644 --- a/src/coreclr/ildasm/dis.cpp +++ b/src/coreclr/ildasm/dis.cpp @@ -727,8 +727,7 @@ void OpenScope(ISymUnmanagedScope *pIScope, char* DumpUnicodeString(void* GUICookie, __inout __nullterminated char* szString, _In_reads_(cbString) WCHAR* pszString, - ULONG cbString, - bool SwapString ) + ULONG cbString) { unsigned i,L; char* szStr=NULL, *szRet = NULL; @@ -750,8 +749,7 @@ char* DumpUnicodeString(void* GUICookie, #endif #if BIGENDIAN - if (SwapString) - SwapStringLength(pszString, cbString); + SwapStringLength(pszString, cbString); #endif // first, check for embedded zeros: @@ -782,7 +780,7 @@ char* DumpUnicodeString(void* GUICookie, strcat_s(szString,SZSTRING_SIZE," ("); #if BIGENDIAN - SwapStringLength(pszString, cbString); + SwapStringLength(pszString, cbString); #endif DumpByteArray(szString,(BYTE*)pszString,cbString*sizeof(WCHAR),GUICookie); szRet = &szString[strlen(szString)]; @@ -2546,7 +2544,7 @@ void PrettyPrintToken(__inout __nullterminated char* szString, mdToken tk, IMDIn } if (pszString != NULL) { - DumpUnicodeString(GUICookie,szString,(WCHAR *)pszString,cbString, true); + DumpUnicodeString(GUICookie,szString,(WCHAR *)pszString,cbString); } else { diff --git a/src/coreclr/ildasm/dis.h b/src/coreclr/ildasm/dis.h index 6aef96aefcfaea..1b60192a60b82e 100644 --- a/src/coreclr/ildasm/dis.h +++ b/src/coreclr/ildasm/dis.h @@ -78,8 +78,7 @@ void DumpVtable(void* GUICookie); char* DumpUnicodeString(void* GUICookie, __inout __nullterminated char* szString, _In_reads_(cbString) WCHAR* pszString, - ULONG cbString, - bool SwapString = false); + ULONG cbString); void TokenSigInit(IMDInternalImport *pImport); void TokenSigDelete(); diff --git a/src/coreclr/inc/cordebug.idl b/src/coreclr/inc/cordebug.idl index 2e06651c9249aa..077d811cd45b9a 100644 --- a/src/coreclr/inc/cordebug.idl +++ b/src/coreclr/inc/cordebug.idl @@ -7781,6 +7781,17 @@ interface ICorDebugExceptionObjectValue : IUnknown HRESULT EnumerateExceptionCallStack([out] ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum); }; +[ + object, + local, + uuid(e3b2f332-cc46-4f1e-ab4e-5400e332195e), + pointer_default(unique) +] +interface ICorDebugExceptionObjectValue2 : IUnknown +{ + HRESULT ForceCatchHandlerFoundEvents([in] BOOL enableEvents); +}; + /* ------------------------------------------------------------------------- * * Library definition * ------------------------------------------------------------------------- */ diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index ff82759f6aab64..2d526105164b6b 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -496,7 +496,7 @@ enum CorInfoHelpFunc CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP, // Do the store, and ensure that the target was not in the heap. CORINFO_HELP_ASSIGN_BYREF, - CORINFO_HELP_ASSIGN_STRUCT, + CORINFO_HELP_BULK_WRITEBARRIER, /* Accessing fields */ diff --git a/src/coreclr/inc/corjit.h b/src/coreclr/inc/corjit.h index 4c012a7b263bf7..18a5be23fdde2d 100644 --- a/src/coreclr/inc/corjit.h +++ b/src/coreclr/inc/corjit.h @@ -452,7 +452,8 @@ class ICorJitInfo : public ICorDynamicInfo uint32_t * pCountSchemaItems, // OUT: pointer to the count of schema items in `pSchema` array. uint8_t ** pInstrumentationData, // OUT: `*pInstrumentationData` is set to the address of the instrumentation data // (pointer will not remain valid after jit completes). - PgoSource * pPgoSource // OUT: value describing source of pgo data + PgoSource * pPgoSource, // OUT: value describing source of pgo data + bool * pDynamicPgo // OUT: dynamic PGO is enabled (valid even when return value is failure) ) = 0; // Allocate a profile buffer for use in the current process diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 98b47dced2beb0..5572a044b9b0aa 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -711,7 +711,8 @@ JITINTERFACE_HRESULT getPgoInstrumentationResults( ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t** pInstrumentationData, - ICorJitInfo::PgoSource* pgoSource) override; + ICorJitInfo::PgoSource* pPgoSource, + bool* pDynamicPgo) override; JITINTERFACE_HRESULT allocPgoInstrumentationBySchema( CORINFO_METHOD_HANDLE ftnHnd, diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 743abdaff86aea..122906341d00b4 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 8f046bcb-ca5f-4692-9277-898b71cb7938 */ - 0x8f046bcb, - 0xca5f, - 0x4692, - {0x92, 0x77, 0x89, 0x8b, 0x71, 0xcb, 0x79, 0x38} +constexpr GUID JITEEVersionIdentifier = { /* bd8c41d4-8531-49c1-a600-0ae9bfe05de1 */ + 0xbd8c41d4, + 0x8531, + 0x49c1, + {0xa6, 0x00, 0x0a, 0xe9, 0xbf, 0xe0, 0x5d, 0xe1} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/inc/jithelpers.h b/src/coreclr/inc/jithelpers.h index f1711a9acfd9b2..2ee49994538592 100644 --- a/src/coreclr/inc/jithelpers.h +++ b/src/coreclr/inc/jithelpers.h @@ -153,8 +153,7 @@ JITHELPER(CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP, JIT_WriteBarrierEnsureNonHeapTarget,CORINFO_HELP_SIG_REG_ONLY) DYNAMICJITHELPER(CORINFO_HELP_ASSIGN_BYREF, JIT_ByRefWriteBarrier,CORINFO_HELP_SIG_NO_ALIGN_STUB) - - JITHELPER(CORINFO_HELP_ASSIGN_STRUCT, JIT_StructWriteBarrier,CORINFO_HELP_SIG_4_STACK) + DYNAMICJITHELPER(CORINFO_HELP_BULK_WRITEBARRIER, NULL, CORINFO_HELP_SIG_REG_ONLY) // Accessing fields JITHELPER(CORINFO_HELP_GETFIELD8, JIT_GetField8,CORINFO_HELP_SIG_REG_ONLY) diff --git a/src/coreclr/inc/metadata.h b/src/coreclr/inc/metadata.h index 766893bea17b8a..65ac907421c244 100644 --- a/src/coreclr/inc/metadata.h +++ b/src/coreclr/inc/metadata.h @@ -220,19 +220,6 @@ struct HENUMInternal //***************************************** typedef struct _MDDefaultValue { -#if BIGENDIAN - _MDDefaultValue(void) - { - m_bType = ELEMENT_TYPE_END; - } - ~_MDDefaultValue(void) - { - if (m_bType == ELEMENT_TYPE_STRING) - { - delete[] m_wzValue; - } - } -#endif // type of default value BYTE m_bType; // CorElementType for the default value @@ -251,7 +238,7 @@ typedef struct _MDDefaultValue ULONGLONG m_ullValue; // ELEMENT_TYPE_UI8 FLOAT m_fltValue; // ELEMENT_TYPE_R4 DOUBLE m_dblValue; // ELEMENT_TYPE_R8 - LPCWSTR m_wzValue; // ELEMENT_TYPE_STRING + LPCWSTR m_wzValue; // ELEMENT_TYPE_STRING - Little endian IUnknown *m_unkValue; // ELEMENT_TYPE_CLASS }; ULONG m_cbSize; // default value size (for blob) diff --git a/src/coreclr/inc/new.hpp b/src/coreclr/inc/new.hpp index 09eec5d1ffcf82..037ceb3c667c20 100644 --- a/src/coreclr/inc/new.hpp +++ b/src/coreclr/inc/new.hpp @@ -7,17 +7,9 @@ #ifndef __new__hpp #define __new__hpp -#if defined(_MSC_VER) && _MSC_VER < 1900 -#define NOEXCEPT -#else -#define NOEXCEPT noexcept -#endif - -struct NoThrow { int x; }; -extern const NoThrow nothrow; +#include -void * __cdecl operator new(size_t n, const NoThrow&) NOEXCEPT; -void * __cdecl operator new[](size_t n, const NoThrow&) NOEXCEPT; +using std::nothrow; #ifdef _DEBUG void DisableThrowCheck(); diff --git a/src/coreclr/inc/readytorun.h b/src/coreclr/inc/readytorun.h index 88219146a123a4..1c3ce8237ef7fc 100644 --- a/src/coreclr/inc/readytorun.h +++ b/src/coreclr/inc/readytorun.h @@ -20,7 +20,7 @@ // If you update this, ensure you run `git grep MINIMUM_READYTORUN_MAJOR_VERSION` // and handle pending work. #define READYTORUN_MAJOR_VERSION 0x0009 -#define READYTORUN_MINOR_VERSION 0x0002 +#define READYTORUN_MINOR_VERSION 0x0003 #define MINIMUM_READYTORUN_MAJOR_VERSION 0x009 @@ -34,6 +34,7 @@ // R2R Version 9.0 adds support for the Vector512 type // R2R Version 9.1 adds new helpers to allocate objects on frozen segments // R2R Version 9.2 adds MemZero and NativeMemSet helpers +// R2R Version 9.3 adds BulkWriteBarrier helper struct READYTORUN_CORE_HEADER @@ -321,6 +322,7 @@ enum ReadyToRunHelper READYTORUN_HELPER_WriteBarrier = 0x30, READYTORUN_HELPER_CheckedWriteBarrier = 0x31, READYTORUN_HELPER_ByRefWriteBarrier = 0x32, + READYTORUN_HELPER_BulkWriteBarrier = 0x33, // Array helpers READYTORUN_HELPER_Stelem_Ref = 0x38, diff --git a/src/coreclr/inc/readytorunhelpers.h b/src/coreclr/inc/readytorunhelpers.h index bbb586e8eb4a30..a1fcef8fbaf835 100644 --- a/src/coreclr/inc/readytorunhelpers.h +++ b/src/coreclr/inc/readytorunhelpers.h @@ -24,6 +24,7 @@ HELPER(READYTORUN_HELPER_ThrowDivZero, CORINFO_HELP_THROWDIVZERO, HELPER(READYTORUN_HELPER_WriteBarrier, CORINFO_HELP_ASSIGN_REF, ) HELPER(READYTORUN_HELPER_CheckedWriteBarrier, CORINFO_HELP_CHECKED_ASSIGN_REF, ) HELPER(READYTORUN_HELPER_ByRefWriteBarrier, CORINFO_HELP_ASSIGN_BYREF, ) +HELPER(READYTORUN_HELPER_BulkWriteBarrier, CORINFO_HELP_BULK_WRITEBARRIER, ) HELPER(READYTORUN_HELPER_Stelem_Ref, CORINFO_HELP_ARRADDR_ST, ) HELPER(READYTORUN_HELPER_Ldelema_Ref, CORINFO_HELP_LDELEMA_REF, ) diff --git a/src/coreclr/inc/stresslog.h b/src/coreclr/inc/stresslog.h index 8e89a06a838dcf..998c62254f6eca 100644 --- a/src/coreclr/inc/stresslog.h +++ b/src/coreclr/inc/stresslog.h @@ -807,7 +807,7 @@ class ThreadStressLog { #endif //!STRESS_LOG_READONLY && !STRESS_LOG_ANALYZER #if defined(MEMORY_MAPPED_STRESSLOG) && !defined(STRESS_LOG_ANALYZER) - void* __cdecl operator new(size_t n, const NoThrow&) NOEXCEPT; + void* __cdecl operator new(size_t n, const std::nothrow_t&) noexcept; void __cdecl operator delete (void * chunk); #endif diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index ed15764b970e74..d4416a36919bd6 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -316,10 +316,10 @@ _Ret_bytecap_(n) void * __cdecl operator new[](size_t n); void __cdecl -operator delete(void *p) NOEXCEPT; +operator delete(void *p) noexcept; void __cdecl -operator delete[](void *p) NOEXCEPT; +operator delete[](void *p) noexcept; #ifdef _DEBUG_IMPL HRESULT _OutOfMemory(LPCSTR szFile, int iLine); @@ -3728,8 +3728,8 @@ extern const CExecutable executable; void * __cdecl operator new(size_t n, const CExecutable&); void * __cdecl operator new[](size_t n, const CExecutable&); -void * __cdecl operator new(size_t n, const CExecutable&, const NoThrow&); -void * __cdecl operator new[](size_t n, const CExecutable&, const NoThrow&); +void * __cdecl operator new(size_t n, const CExecutable&, const std::nothrow_t&) noexcept; +void * __cdecl operator new[](size_t n, const CExecutable&, const std::nothrow_t&) noexcept; // diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 85db2ec5efffa5..e001c56c26dcbd 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -1666,10 +1666,11 @@ JITINTERFACE_HRESULT WrapICorJitInfo::getPgoInstrumentationResults( ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t** pInstrumentationData, - ICorJitInfo::PgoSource* pgoSource) + ICorJitInfo::PgoSource* pPgoSource, + bool* pDynamicPgo) { API_ENTER(getPgoInstrumentationResults); - JITINTERFACE_HRESULT temp = wrapHnd->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pgoSource); + JITINTERFACE_HRESULT temp = wrapHnd->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, pDynamicPgo); API_LEAVE(getPgoInstrumentationResults); return temp; } diff --git a/src/coreclr/jit/abi.cpp b/src/coreclr/jit/abi.cpp index fd899b899546b1..7fa39d04644342 100644 --- a/src/coreclr/jit/abi.cpp +++ b/src/coreclr/jit/abi.cpp @@ -258,14 +258,20 @@ bool ABIPassingInformation::HasExactlyOneStackSegment() const // bool ABIPassingInformation::IsSplitAcrossRegistersAndStack() const { - bool anyReg = false; - bool anyStack = false; - for (unsigned i = 0; i < NumSegments; i++) + if (NumSegments < 2) + { + return false; + } + + bool isFirstInReg = Segments[0].IsPassedInRegister(); + for (unsigned i = 1; i < NumSegments; i++) { - anyReg |= Segments[i].IsPassedInRegister(); - anyStack |= Segments[i].IsPassedOnStack(); + if (isFirstInReg != Segments[i].IsPassedInRegister()) + { + return true; + } } - return anyReg && anyStack; + return false; } //----------------------------------------------------------------------------- @@ -415,6 +421,9 @@ ABIPassingInformation SwiftABIClassifier::Classify(Compiler* comp, { ABIPassingSegment newSegment = elemInfo.Segments[j]; newSegment.Offset += lowering->offsets[i]; + // Adjust the tail size if necessary; the lowered sequence can + // pass the tail as a larger type than the tail size. + newSegment.Size = min(newSegment.Size, structLayout->GetSize() - newSegment.Offset); segments.Push(newSegment); } } diff --git a/src/coreclr/jit/abi.h b/src/coreclr/jit/abi.h index ac0ad5090dcf2b..37268ce3effd9f 100644 --- a/src/coreclr/jit/abi.h +++ b/src/coreclr/jit/abi.h @@ -51,8 +51,8 @@ struct ABIPassingInformation // - On loongarch64/riscv64, structs can be passed in two registers or // can be split out over register and stack, giving // multiple register segments and a struct segment. - unsigned NumSegments = 0; - ABIPassingSegment* Segments = nullptr; + unsigned NumSegments; + ABIPassingSegment* Segments; ABIPassingInformation(unsigned numSegments = 0, ABIPassingSegment* segments = nullptr) : NumSegments(numSegments) diff --git a/src/coreclr/jit/block.cpp b/src/coreclr/jit/block.cpp index 60dbce6aaf00a0..ecee292264ec85 100644 --- a/src/coreclr/jit/block.cpp +++ b/src/coreclr/jit/block.cpp @@ -137,14 +137,17 @@ void FlowEdge::addLikelihood(weight_t addedLikelihood) // AllSuccessorEnumerator: Construct an instance of the enumerator. // // Arguments: -// comp - Compiler instance -// block - The block whose successors are to be iterated +// comp - Compiler instance +// block - The block whose successors are to be iterated +// useProfile - If true, determines the order of successors visited using profile data // -AllSuccessorEnumerator::AllSuccessorEnumerator(Compiler* comp, BasicBlock* block) +AllSuccessorEnumerator::AllSuccessorEnumerator(Compiler* comp, BasicBlock* block, const bool useProfile /* = false */) : m_block(block) { m_numSuccs = 0; - block->VisitAllSuccs(comp, [this](BasicBlock* succ) { + block->VisitAllSuccs( + comp, + [this](BasicBlock* succ) { if (m_numSuccs < ArrLen(m_successors)) { m_successors[m_numSuccs] = succ; @@ -152,18 +155,22 @@ AllSuccessorEnumerator::AllSuccessorEnumerator(Compiler* comp, BasicBlock* block m_numSuccs++; return BasicBlockVisit::Continue; - }); + }, + useProfile); if (m_numSuccs > ArrLen(m_successors)) { m_pSuccessors = new (comp, CMK_BasicBlock) BasicBlock*[m_numSuccs]; unsigned numSuccs = 0; - block->VisitAllSuccs(comp, [this, &numSuccs](BasicBlock* succ) { + block->VisitAllSuccs( + comp, + [this, &numSuccs](BasicBlock* succ) { assert(numSuccs < m_numSuccs); m_pSuccessors[numSuccs++] = succ; return BasicBlockVisit::Continue; - }); + }, + useProfile); assert(numSuccs == m_numSuccs); } diff --git a/src/coreclr/jit/block.h b/src/coreclr/jit/block.h index 168f29cca084dd..6ff2bb31b2a856 100644 --- a/src/coreclr/jit/block.h +++ b/src/coreclr/jit/block.h @@ -1256,27 +1256,6 @@ struct BasicBlock : private LIR::Range this->scaleBBWeight(BB_ZERO_WEIGHT); } - // makeBlockHot() - // This is used to override any profiling data - // and force a block to be in the hot region. - // We only call this method for handler entry point - // and only when HANDLER_ENTRY_MUST_BE_IN_HOT_SECTION is 1. - // Doing this helps fgReorderBlocks() by telling - // it to try to move these blocks into the hot region. - // Note that we do this strictly as an optimization, - // not for correctness. fgDetermineFirstColdBlock() - // will find all handler entry points and ensure that - // for now we don't place them in the cold section. - // - void makeBlockHot() - { - if (this->bbWeight == BB_ZERO_WEIGHT) - { - this->RemoveFlags(BBF_RUN_RARELY | BBF_PROF_WEIGHT); - this->bbWeight = 1; - } - } - bool isMaxBBWeight() const { return (bbWeight >= BB_MAX_WEIGHT); @@ -1820,7 +1799,7 @@ struct BasicBlock : private LIR::Range BasicBlockVisit VisitEHEnclosedHandlerSecondPassSuccs(Compiler* comp, TFunc func); template - BasicBlockVisit VisitAllSuccs(Compiler* comp, TFunc func); + BasicBlockVisit VisitAllSuccs(Compiler* comp, TFunc func, const bool useProfile = false); template BasicBlockVisit VisitEHSuccs(Compiler* comp, TFunc func); @@ -2518,7 +2497,7 @@ class AllSuccessorEnumerator public: // Constructs an enumerator of all `block`'s successors. - AllSuccessorEnumerator(Compiler* comp, BasicBlock* block); + AllSuccessorEnumerator(Compiler* comp, BasicBlock* block, const bool useProfile = false); // Gets the block whose successors are enumerated. BasicBlock* Block() diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 3511935a062b0a..2a2ede6bae9ac0 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -101,6 +101,16 @@ class CodeGen final : public CodeGenInterface } } +#if defined(TARGET_ARM64) + regNumber getNextSIMDRegWithWraparound(regNumber reg) + { + regNumber nextReg = REG_NEXT(reg); + + // Wraparound if necessary, REG_V0 comes next after REG_V31. + return (nextReg > REG_V31) ? REG_V0 : nextReg; + } +#endif // defined(TARGET_ARM64) + static GenTreeIndir indirForm(var_types type, GenTree* base); static GenTreeStoreInd storeIndirForm(var_types type, GenTree* base, GenTree* data); @@ -274,7 +284,9 @@ class CodeGen final : public CodeGenInterface void genEnregisterOSRArgsAndLocals(); #endif + void genHomeStackSegment(unsigned lclNum, const ABIPassingSegment& seg, regNumber initReg, bool* pInitRegZeroed); void genHomeSwiftStructParameters(bool handleStack); + void genHomeStackPartOfSplitParameter(regNumber initReg, bool* initRegStillZeroed); void genCheckUseBlockInit(); #if defined(UNIX_AMD64_ABI) && defined(FEATURE_SIMD) @@ -437,26 +449,7 @@ class CodeGen final : public CodeGenInterface FuncletFrameInfoDsc genFuncletInfo; -#elif defined(TARGET_LOONGARCH64) - - // A set of information that is used by funclet prolog and epilog generation. - // It is collected once, before funclet prologs and epilogs are generated, - // and used by all funclet prologs and epilogs, which must all be the same. - struct FuncletFrameInfoDsc - { - regMaskTP fiSaveRegs; // Set of callee-saved registers saved in the funclet prolog (includes RA) - int fiFunction_CallerSP_to_FP_delta; // Delta between caller SP and the frame pointer in the parent function - // (negative) - int fiSP_to_CalleeSaved_delta; // CalleeSaved register save offset from SP (positive) - int fiCalleeSavedPadding; // CalleeSaved offset padding (positive) - int fiSP_to_PSP_slot_delta; // PSP slot offset from SP (positive) - int fiCallerSP_to_PSP_slot_delta; // PSP slot offset from Caller SP (negative) - int fiSpDelta; // Stack pointer delta (negative) - }; - - FuncletFrameInfoDsc genFuncletInfo; - -#elif defined(TARGET_RISCV64) +#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) // A set of information that is used by funclet prolog and epilog generation. // It is collected once, before funclet prologs and epilogs are generated, @@ -467,7 +460,6 @@ class CodeGen final : public CodeGenInterface int fiFunction_CallerSP_to_FP_delta; // Delta between caller SP and the frame pointer in the parent function // (negative) int fiSP_to_CalleeSaved_delta; // CalleeSaved register save offset from SP (positive) - int fiCalleeSavedPadding; // CalleeSaved offset padding (positive) int fiSP_to_PSP_slot_delta; // PSP slot offset from SP (positive) int fiCallerSP_to_PSP_slot_delta; // PSP slot offset from Caller SP (negative) int fiSpDelta; // Stack pointer delta (negative) @@ -1272,7 +1264,6 @@ class CodeGen final : public CodeGenInterface void genJmpMethod(GenTree* jmp); BasicBlock* genCallFinally(BasicBlock* block); #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - // TODO: refactor for LA. void genCodeForJumpCompare(GenTreeOpCC* tree); #endif #if defined(TARGET_ARM64) diff --git a/src/coreclr/jit/codegenarm.cpp b/src/coreclr/jit/codegenarm.cpp index 2c010f116a2657..dea8b19fbee94f 100644 --- a/src/coreclr/jit/codegenarm.cpp +++ b/src/coreclr/jit/codegenarm.cpp @@ -280,7 +280,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre if (targetType == TYP_FLOAT) { // Get a temp integer register - regNumber tmpReg = tree->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(tree); float f = forceCastToFloat(constValue); instGen_Set_Reg_To_Imm(EA_4BYTE, tmpReg, *((int*)(&f))); @@ -293,8 +293,8 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre unsigned* cv = (unsigned*)&constValue; // Get two temp integer registers - regNumber tmpReg1 = tree->ExtractTempReg(); - regNumber tmpReg2 = tree->GetSingleTempReg(); + regNumber tmpReg1 = internalRegisters.Extract(tree); + regNumber tmpReg2 = internalRegisters.GetSingle(tree); instGen_Set_Reg_To_Imm(EA_4BYTE, tmpReg1, cv[0]); instGen_Set_Reg_To_Imm(EA_4BYTE, tmpReg2, cv[1]); @@ -431,9 +431,9 @@ void CodeGen::genLclHeap(GenTree* tree) } // Setup the regTmp, if there is one. - if (tree->AvailableTempRegCount() > 0) + if (internalRegisters.Count(tree) > 0) { - regTmp = tree->ExtractTempReg(); + regTmp = internalRegisters.Extract(tree); } // If we have an outgoing arg area then we must adjust the SP by popping off the @@ -833,7 +833,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) gcInfo.gcMarkRegPtrVal(REG_WRITE_BARRIER_DST_BYREF, dstAddr->TypeGet()); // Temp register used to perform the sequence of loads and stores. - regNumber tmpReg = cpObjNode->ExtractTempReg(); + regNumber tmpReg = internalRegisters.Extract(cpObjNode); assert(genIsValidIntReg(tmpReg)); if (cpObjNode->IsVolatile()) @@ -1026,18 +1026,18 @@ void CodeGen::genCodeForStoreLclFld(GenTreeLclFld* tree) { // Arm supports unaligned access only for integer types, // convert the storing floating data into 1 or 2 integer registers and write them as int. - regNumber addr = tree->ExtractTempReg(); + regNumber addr = internalRegisters.Extract(tree); emit->emitIns_R_S(INS_lea, EA_PTRSIZE, addr, varNum, offset); if (targetType == TYP_FLOAT) { - regNumber floatAsInt = tree->GetSingleTempReg(); + regNumber floatAsInt = internalRegisters.GetSingle(tree); emit->emitIns_Mov(INS_vmov_f2i, EA_4BYTE, floatAsInt, dataReg, /* canSkip */ false); emit->emitIns_R_R(INS_str, EA_4BYTE, floatAsInt, addr); } else { - regNumber halfdoubleAsInt1 = tree->ExtractTempReg(); - regNumber halfdoubleAsInt2 = tree->GetSingleTempReg(); + regNumber halfdoubleAsInt1 = internalRegisters.Extract(tree); + regNumber halfdoubleAsInt2 = internalRegisters.GetSingle(tree); emit->emitIns_R_R_R(INS_vmov_d2i, EA_8BYTE, halfdoubleAsInt1, halfdoubleAsInt2, dataReg); emit->emitIns_R_R_I(INS_str, EA_4BYTE, halfdoubleAsInt1, addr, 0); emit->emitIns_R_R_I(INS_str, EA_4BYTE, halfdoubleAsInt1, addr, 4); @@ -1209,7 +1209,7 @@ void CodeGen::genCkfinite(GenTree* treeNode) emitter* emit = GetEmitter(); var_types targetType = treeNode->TypeGet(); - regNumber intReg = treeNode->GetSingleTempReg(); + regNumber intReg = internalRegisters.GetSingle(treeNode); regNumber fpReg = genConsumeReg(treeNode->AsOp()->gtOp1); regNumber targetReg = treeNode->GetRegNum(); @@ -1592,7 +1592,7 @@ void CodeGen::genFloatToIntCast(GenTree* treeNode) genConsumeOperands(treeNode->AsOp()); - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); assert(insVcvt != INS_invalid); GetEmitter()->emitIns_R_R(insVcvt, dstSize, tmpReg, op1->GetRegNum()); diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 8695545cc934a3..dc79220dcd0b87 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2372,7 +2372,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre else { // Get a temp integer register to compute long address. - regNumber addrReg = tree->GetSingleTempReg(); + regNumber addrReg = internalRegisters.GetSingle(tree); // We must load the FP constant from the constant pool // Emit a data section constant for the float or double constant. @@ -2407,7 +2407,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre else { // Get a temp integer register to compute long address. - regNumber addrReg = tree->GetSingleTempReg(); + regNumber addrReg = internalRegisters.GetSingle(tree); simd8_t constValue; memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd8_t)); @@ -2431,7 +2431,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre else { // Get a temp integer register to compute long address. - regNumber addrReg = tree->GetSingleTempReg(); + regNumber addrReg = internalRegisters.GetSingle(tree); simd16_t constValue = {}; memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd12_t)); @@ -2455,7 +2455,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre else { // Get a temp integer register to compute long address. - regNumber addrReg = tree->GetSingleTempReg(); + regNumber addrReg = internalRegisters.GetSingle(tree); simd16_t constValue; memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd16_t)); @@ -3132,12 +3132,12 @@ void CodeGen::genLclHeap(GenTree* tree) // since we don't need any internal registers. if (compiler->info.compInitMem) { - assert(tree->AvailableTempRegCount() == 0); + assert(internalRegisters.Count(tree) == 0); regCnt = targetReg; } else { - regCnt = tree->ExtractTempReg(); + regCnt = internalRegisters.Extract(tree); inst_Mov(size->TypeGet(), regCnt, targetReg, /* canSkip */ true); } @@ -3254,12 +3254,12 @@ void CodeGen::genLclHeap(GenTree* tree) assert(regCnt == REG_NA); if (compiler->info.compInitMem) { - assert(tree->AvailableTempRegCount() == 0); + assert(internalRegisters.Count(tree) == 0); regCnt = targetReg; } else { - regCnt = tree->ExtractTempReg(); + regCnt = internalRegisters.Extract(tree); } instGen_Set_Reg_To_Imm(((unsigned int)amount == amount) ? EA_4BYTE : EA_8BYTE, regCnt, amount); } @@ -3323,7 +3323,7 @@ void CodeGen::genLclHeap(GenTree* tree) // // Setup the regTmp - regNumber regTmp = tree->GetSingleTempReg(); + regNumber regTmp = internalRegisters.GetSingle(tree); BasicBlock* loop = genCreateTempLabel(); BasicBlock* done = genCreateTempLabel(); @@ -3668,7 +3668,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) unsigned slots = layout->GetSlotCount(); // Temp register(s) used to perform the sequence of loads and stores. - regNumber tmpReg = cpObjNode->ExtractTempReg(RBM_ALLINT); + regNumber tmpReg = internalRegisters.Extract(cpObjNode, RBM_ALLINT); regNumber tmpReg2 = REG_NA; assert(genIsValidIntReg(tmpReg)); @@ -3677,7 +3677,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) if (slots > 1) { - tmpReg2 = cpObjNode->ExtractTempReg(RBM_ALLINT); + tmpReg2 = internalRegisters.Extract(cpObjNode, RBM_ALLINT); assert(tmpReg2 != tmpReg); assert(genIsValidIntReg(tmpReg2)); assert(tmpReg2 != REG_WRITE_BARRIER_DST_BYREF); @@ -3730,8 +3730,8 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) regNumber tmpSimdReg2 = REG_NA; if ((slots >= 4) && compiler->IsBaselineSimdIsaSupported()) { - tmpSimdReg1 = cpObjNode->ExtractTempReg(RBM_ALLFLOAT); - tmpSimdReg2 = cpObjNode->ExtractTempReg(RBM_ALLFLOAT); + tmpSimdReg1 = internalRegisters.Extract(cpObjNode, RBM_ALLFLOAT); + tmpSimdReg2 = internalRegisters.Extract(cpObjNode, RBM_ALLFLOAT); } unsigned i = 0; @@ -3810,7 +3810,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) regNumber idxReg = treeNode->AsOp()->gtOp1->GetRegNum(); regNumber baseReg = treeNode->AsOp()->gtOp2->GetRegNum(); - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); // load the ip-relative offset (which is relative to start of fgFirstBB) GetEmitter()->emitIns_R_R_R(INS_ldr, EA_4BYTE, baseReg, baseReg, idxReg, INS_OPTS_LSL); @@ -3869,7 +3869,7 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode) case GT_XAND: { // Grab a temp reg to perform `MVN` for dataReg first. - regNumber tempReg = treeNode->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(treeNode); GetEmitter()->emitIns_R_R(INS_mvn, dataSize, tempReg, dataReg); GetEmitter()->emitIns_R_R_R(INS_ldclral, dataSize, tempReg, (targetReg == REG_NA) ? REG_ZR : targetReg, addrReg); @@ -3902,9 +3902,10 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode) // These are imported normally if Atomics aren't supported. assert(!treeNode->OperIs(GT_XORR, GT_XAND)); - regNumber exResultReg = treeNode->ExtractTempReg(RBM_ALLINT); - regNumber storeDataReg = (treeNode->OperGet() == GT_XCHG) ? dataReg : treeNode->ExtractTempReg(RBM_ALLINT); - regNumber loadReg = (targetReg != REG_NA) ? targetReg : storeDataReg; + regNumber exResultReg = internalRegisters.Extract(treeNode, RBM_ALLINT); + regNumber storeDataReg = + (treeNode->OperGet() == GT_XCHG) ? dataReg : internalRegisters.Extract(treeNode, RBM_ALLINT); + regNumber loadReg = (targetReg != REG_NA) ? targetReg : storeDataReg; // Check allocator assumptions // @@ -4055,7 +4056,7 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode) } else { - regNumber exResultReg = treeNode->ExtractTempReg(RBM_ALLINT); + regNumber exResultReg = internalRegisters.Extract(treeNode, RBM_ALLINT); // Check allocator assumptions // @@ -4600,7 +4601,7 @@ void CodeGen::genCkfinite(GenTree* treeNode) emitter* emit = GetEmitter(); // Extract exponent into a register. - regNumber intReg = treeNode->GetSingleTempReg(); + regNumber intReg = internalRegisters.GetSingle(treeNode); regNumber fpReg = genConsumeReg(op1); inst_Mov(targetType, intReg, fpReg, /* canSkip */ false, emitActualTypeSize(treeNode)); @@ -5351,7 +5352,7 @@ void CodeGen::genStoreIndTypeSimd12(GenTreeStoreInd* treeNode) regNumber dataReg = genConsumeReg(data); // Need an additional integer register to extract upper 4 bytes from data. - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); // 8-byte write GetEmitter()->emitIns_R_R(INS_str, EA_8BYTE, dataReg, addrReg); @@ -5386,7 +5387,7 @@ void CodeGen::genLoadIndTypeSimd12(GenTreeIndir* treeNode) regNumber addrReg = genConsumeReg(addr); // Need an additional int register to read upper 4 bytes, which is different from targetReg - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); // 8-byte read GetEmitter()->emitIns_R_R(INS_ldr, EA_8BYTE, tgtReg, addrReg); diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp index 52633ed6733e6a..ddc7d831f228df 100644 --- a/src/coreclr/jit/codegenarm64test.cpp +++ b/src/coreclr/jit/codegenarm64test.cpp @@ -4572,14 +4572,24 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_S); // EOR ., /M, ., . theEmitter->emitIns_R_R_R(INS_sve_orr, EA_SCALABLE, REG_V29, REG_P7, REG_V31, INS_OPTS_SCALABLE_D); // ORR ., /M, ., . - - // IF_SVE_AB_3A theEmitter->emitIns_R_R_R(INS_sve_add, EA_SCALABLE, REG_V5, REG_P6, REG_V7, INS_OPTS_SCALABLE_B); // ADD ., /M, ., . theEmitter->emitIns_R_R_R(INS_sve_sub, EA_SCALABLE, REG_V15, REG_P7, REG_V29, INS_OPTS_SCALABLE_H); // SUB ., /M, ., . theEmitter->emitIns_R_R_R(INS_sve_subr, EA_SCALABLE, REG_V2, REG_P0, REG_V13, INS_OPTS_SCALABLE_S); // SUBR ., /M, ., . + theEmitter->emitIns_R_R_R(INS_sve_smax, EA_SCALABLE, REG_V24, REG_P0, REG_V2, + INS_OPTS_SCALABLE_B); // SMAX ., /M, ., . + theEmitter->emitIns_R_R_R(INS_sve_smin, EA_SCALABLE, REG_V9, REG_P1, REG_V27, + INS_OPTS_SCALABLE_H); // SMIN ., /M, ., . + theEmitter->emitIns_R_R_R(INS_sve_sabd, EA_SCALABLE, REG_V5, REG_P2, REG_V6, + INS_OPTS_SCALABLE_B); // SABD ., /M, ., . + theEmitter->emitIns_R_R_R(INS_sve_uabd, EA_SCALABLE, REG_V23, REG_P3, REG_V9, + INS_OPTS_SCALABLE_S); // UABD ., /M, ., . + theEmitter->emitIns_R_R_R(INS_sve_umax, EA_SCALABLE, REG_V15, REG_P4, REG_V2, + INS_OPTS_SCALABLE_S); // UMAX ., /M, ., . + theEmitter->emitIns_R_R_R(INS_sve_umin, EA_SCALABLE, REG_V12, REG_P7, REG_V0, + INS_OPTS_SCALABLE_D); // UMIN ., /M, ., . #ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_AB_3B @@ -4599,20 +4609,6 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_udivr, EA_SCALABLE, REG_V13, REG_P7, REG_V15, INS_OPTS_SCALABLE_D); // UDIVR ., /M, ., . - // IF_SVE_AD_3A - theEmitter->emitIns_R_R_R(INS_sve_smax, EA_SCALABLE, REG_V24, REG_P0, REG_V2, - INS_OPTS_SCALABLE_B); // SMAX ., /M, ., . - theEmitter->emitIns_R_R_R(INS_sve_smin, EA_SCALABLE, REG_V9, REG_P1, REG_V27, - INS_OPTS_SCALABLE_H); // SMIN ., /M, ., . - theEmitter->emitIns_R_R_R(INS_sve_sabd, EA_SCALABLE, REG_V5, REG_P2, REG_V6, - INS_OPTS_SCALABLE_B); // SABD ., /M, ., . - theEmitter->emitIns_R_R_R(INS_sve_uabd, EA_SCALABLE, REG_V23, REG_P3, REG_V9, - INS_OPTS_SCALABLE_S); // UABD ., /M, ., . - theEmitter->emitIns_R_R_R(INS_sve_umax, EA_SCALABLE, REG_V15, REG_P4, REG_V2, - INS_OPTS_SCALABLE_S); // UMAX ., /M, ., . - theEmitter->emitIns_R_R_R(INS_sve_umin, EA_SCALABLE, REG_V12, REG_P7, REG_V0, - INS_OPTS_SCALABLE_D); // UMIN ., /M, ., . - // IF_SVE_AE_3A theEmitter->emitIns_R_R_R(INS_sve_mul, EA_SCALABLE, REG_V5, REG_P1, REG_V3, INS_OPTS_SCALABLE_D); // MUL ., /M, ., . @@ -4802,11 +4798,11 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_D); // CLASTB ., , ., . // IF_SVE_CN_3A - theEmitter->emitIns_R_R_R(INS_sve_clasta, EA_2BYTE, REG_V12, REG_P1, REG_V15, INS_OPTS_SCALABLE_H, + theEmitter->emitIns_R_R_R(INS_sve_clasta, EA_SCALABLE, REG_V12, REG_P1, REG_V15, INS_OPTS_SCALABLE_H, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // CLASTA , , , . - theEmitter->emitIns_R_R_R(INS_sve_clastb, EA_4BYTE, REG_V13, REG_P2, REG_V16, INS_OPTS_SCALABLE_S, + theEmitter->emitIns_R_R_R(INS_sve_clastb, EA_SCALABLE, REG_V13, REG_P2, REG_V16, INS_OPTS_SCALABLE_S, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // CLASTB , , , . - theEmitter->emitIns_R_R_R(INS_sve_clastb, EA_8BYTE, REG_V14, REG_P0, REG_V17, INS_OPTS_SCALABLE_D, + theEmitter->emitIns_R_R_R(INS_sve_clastb, EA_SCALABLE, REG_V14, REG_P0, REG_V17, INS_OPTS_SCALABLE_D, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // CLASTB , , , . // IF_SVE_CO_3A @@ -5116,11 +5112,11 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_H); // FMINP ., /M, ., . // IF_SVE_HJ_3A - theEmitter->emitIns_R_R_R(INS_sve_fadda, EA_2BYTE, REG_V21, REG_P6, REG_V14, + theEmitter->emitIns_R_R_R(INS_sve_fadda, EA_SCALABLE, REG_V21, REG_P6, REG_V14, INS_OPTS_SCALABLE_H); // FADDA , , , . - theEmitter->emitIns_R_R_R(INS_sve_fadda, EA_4BYTE, REG_V22, REG_P5, REG_V13, + theEmitter->emitIns_R_R_R(INS_sve_fadda, EA_SCALABLE, REG_V22, REG_P5, REG_V13, INS_OPTS_SCALABLE_S); // FADDA , , , . - theEmitter->emitIns_R_R_R(INS_sve_fadda, EA_8BYTE, REG_V23, REG_P4, REG_V12, + theEmitter->emitIns_R_R_R(INS_sve_fadda, EA_SCALABLE, REG_V23, REG_P4, REG_V12, INS_OPTS_SCALABLE_D); // FADDA , , , . // IF_SVE_HL_3A @@ -5292,13 +5288,13 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_H); // FNMLS ., /M, ., . // IF_SVE_AF_3A - theEmitter->emitIns_R_R_R(INS_sve_andv, EA_1BYTE, REG_V0, REG_P0, REG_V0, + theEmitter->emitIns_R_R_R(INS_sve_andv, EA_SCALABLE, REG_V0, REG_P0, REG_V0, INS_OPTS_SCALABLE_B); // ANDV , , . - theEmitter->emitIns_R_R_R(INS_sve_eorv, EA_2BYTE, REG_V1, REG_P1, REG_V1, + theEmitter->emitIns_R_R_R(INS_sve_eorv, EA_SCALABLE, REG_V1, REG_P1, REG_V1, INS_OPTS_SCALABLE_H); // EORV , , . - theEmitter->emitIns_R_R_R(INS_sve_orv, EA_4BYTE, REG_V2, REG_P2, REG_V2, + theEmitter->emitIns_R_R_R(INS_sve_orv, EA_SCALABLE, REG_V2, REG_P2, REG_V2, INS_OPTS_SCALABLE_S); // ORV , , . - theEmitter->emitIns_R_R_R(INS_sve_orv, EA_8BYTE, REG_V3, REG_P3, REG_V3, + theEmitter->emitIns_R_R_R(INS_sve_orv, EA_SCALABLE, REG_V3, REG_P3, REG_V3, INS_OPTS_SCALABLE_D); // ORV , , . // IF_SVE_AG_3A @@ -5314,11 +5310,11 @@ void CodeGen::genArm64EmitterUnitTestsSve() #endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_AI_3A - theEmitter->emitIns_R_R_R(INS_sve_saddv, EA_1BYTE, REG_V1, REG_P4, REG_V2, + theEmitter->emitIns_R_R_R(INS_sve_saddv, EA_SCALABLE, REG_V1, REG_P4, REG_V2, INS_OPTS_SCALABLE_B); // SADDV
, , . - theEmitter->emitIns_R_R_R(INS_sve_saddv, EA_2BYTE, REG_V2, REG_P5, REG_V3, + theEmitter->emitIns_R_R_R(INS_sve_saddv, EA_SCALABLE, REG_V2, REG_P5, REG_V3, INS_OPTS_SCALABLE_H); // SADDV
, , . - theEmitter->emitIns_R_R_R(INS_sve_uaddv, EA_4BYTE, REG_V3, REG_P6, REG_V4, + theEmitter->emitIns_R_R_R(INS_sve_uaddv, EA_SCALABLE, REG_V3, REG_P6, REG_V4, INS_OPTS_SCALABLE_S); // UADDV
, , . // IF_SVE_AJ_3A @@ -5328,13 +5324,13 @@ void CodeGen::genArm64EmitterUnitTestsSve() #endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_AK_3A - theEmitter->emitIns_R_R_R(INS_sve_smaxv, EA_8BYTE, REG_V15, REG_P7, REG_V4, + theEmitter->emitIns_R_R_R(INS_sve_smaxv, EA_SCALABLE, REG_V15, REG_P7, REG_V4, INS_OPTS_SCALABLE_D); // SMAXV , , . - theEmitter->emitIns_R_R_R(INS_sve_sminv, EA_4BYTE, REG_V16, REG_P6, REG_V14, + theEmitter->emitIns_R_R_R(INS_sve_sminv, EA_SCALABLE, REG_V16, REG_P6, REG_V14, INS_OPTS_SCALABLE_S); // SMINV , , . - theEmitter->emitIns_R_R_R(INS_sve_umaxv, EA_2BYTE, REG_V17, REG_P5, REG_V24, + theEmitter->emitIns_R_R_R(INS_sve_umaxv, EA_SCALABLE, REG_V17, REG_P5, REG_V24, INS_OPTS_SCALABLE_H); // UMAXV , , . - theEmitter->emitIns_R_R_R(INS_sve_uminv, EA_1BYTE, REG_V18, REG_P4, REG_V31, + theEmitter->emitIns_R_R_R(INS_sve_uminv, EA_SCALABLE, REG_V18, REG_P4, REG_V31, INS_OPTS_SCALABLE_B); // UMINV , , . // IF_SVE_AL_3A @@ -6222,13 +6218,13 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_D); // COMPACT ., , . // IF_SVE_CP_3A - theEmitter->emitIns_R_R_R(INS_sve_cpy, EA_1BYTE, REG_V14, REG_P1, REG_V11, INS_OPTS_SCALABLE_B, + theEmitter->emitIns_R_R_R(INS_sve_cpy, EA_SCALABLE, REG_V14, REG_P1, REG_V11, INS_OPTS_SCALABLE_B, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // CPY ., /M, - theEmitter->emitIns_R_R_R(INS_sve_cpy, EA_4BYTE, REG_V13, REG_P2, REG_V10, INS_OPTS_SCALABLE_S, + theEmitter->emitIns_R_R_R(INS_sve_cpy, EA_SCALABLE, REG_V13, REG_P2, REG_V10, INS_OPTS_SCALABLE_S, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // CPY ., /M, - theEmitter->emitIns_R_R_R(INS_sve_mov, EA_2BYTE, REG_V12, REG_P3, REG_V9, INS_OPTS_SCALABLE_H, + theEmitter->emitIns_R_R_R(INS_sve_mov, EA_SCALABLE, REG_V12, REG_P3, REG_V9, INS_OPTS_SCALABLE_H, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // MOV ., /M, - theEmitter->emitIns_R_R_R(INS_sve_mov, EA_8BYTE, REG_V11, REG_P4, REG_V8, INS_OPTS_SCALABLE_D, + theEmitter->emitIns_R_R_R(INS_sve_mov, EA_SCALABLE, REG_V11, REG_P4, REG_V8, INS_OPTS_SCALABLE_D, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // MOV ., /M, // IF_SVE_CQ_3A @@ -6243,13 +6239,13 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_B); // MOV ., /M, // IF_SVE_CR_3A - theEmitter->emitIns_R_R_R(INS_sve_lasta, EA_1BYTE, REG_V6, REG_P1, REG_V27, INS_OPTS_SCALABLE_B, + theEmitter->emitIns_R_R_R(INS_sve_lasta, EA_SCALABLE, REG_V6, REG_P1, REG_V27, INS_OPTS_SCALABLE_B, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // LASTA , , . - theEmitter->emitIns_R_R_R(INS_sve_lasta, EA_2BYTE, REG_V5, REG_P2, REG_V26, INS_OPTS_SCALABLE_H, + theEmitter->emitIns_R_R_R(INS_sve_lasta, EA_SCALABLE, REG_V5, REG_P2, REG_V26, INS_OPTS_SCALABLE_H, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // LASTA , , . - theEmitter->emitIns_R_R_R(INS_sve_lastb, EA_4BYTE, REG_V4, REG_P3, REG_V25, INS_OPTS_SCALABLE_S, + theEmitter->emitIns_R_R_R(INS_sve_lastb, EA_SCALABLE, REG_V4, REG_P3, REG_V25, INS_OPTS_SCALABLE_S, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // LASTB , , . - theEmitter->emitIns_R_R_R(INS_sve_lastb, EA_8BYTE, REG_V3, REG_P4, REG_V24, INS_OPTS_SCALABLE_D, + theEmitter->emitIns_R_R_R(INS_sve_lastb, EA_SCALABLE, REG_V3, REG_P4, REG_V24, INS_OPTS_SCALABLE_D, INS_SCALABLE_OPTS_WITH_SIMD_SCALAR); // LASTB , , . // IF_SVE_CS_3A @@ -6768,15 +6764,15 @@ void CodeGen::genArm64EmitterUnitTestsSve() #endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HE_3A - theEmitter->emitIns_R_R_R(INS_sve_faddv, EA_2BYTE, REG_V21, REG_P7, REG_V7, + theEmitter->emitIns_R_R_R(INS_sve_faddv, EA_SCALABLE, REG_V21, REG_P7, REG_V7, INS_OPTS_SCALABLE_H); // FADDV , , . - theEmitter->emitIns_R_R_R(INS_sve_fmaxnmv, EA_2BYTE, REG_V22, REG_P6, REG_V6, + theEmitter->emitIns_R_R_R(INS_sve_fmaxnmv, EA_SCALABLE, REG_V22, REG_P6, REG_V6, INS_OPTS_SCALABLE_H); // FMAXNMV , , . - theEmitter->emitIns_R_R_R(INS_sve_fmaxv, EA_4BYTE, REG_V23, REG_P5, REG_V5, + theEmitter->emitIns_R_R_R(INS_sve_fmaxv, EA_SCALABLE, REG_V23, REG_P5, REG_V5, INS_OPTS_SCALABLE_S); // FMAXV , , . - theEmitter->emitIns_R_R_R(INS_sve_fminnmv, EA_8BYTE, REG_V24, REG_P4, REG_V4, + theEmitter->emitIns_R_R_R(INS_sve_fminnmv, EA_SCALABLE, REG_V24, REG_P4, REG_V4, INS_OPTS_SCALABLE_D); // FMINNMV , , . - theEmitter->emitIns_R_R_R(INS_sve_fminv, EA_4BYTE, REG_V25, REG_P3, REG_V3, + theEmitter->emitIns_R_R_R(INS_sve_fminv, EA_SCALABLE, REG_V25, REG_P3, REG_V3, INS_OPTS_SCALABLE_S); // FMINV , , . // IF_SVE_HQ_3A @@ -8909,7 +8905,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() // SUNPKLO ., . theEmitter->emitIns_R_R(INS_sve_sunpklo, EA_SCALABLE, REG_V1, REG_V5, INS_OPTS_SCALABLE_S); // UUNPKHI ., . - theEmitter->emitIns_R_R(INS_sve_uunpkhi, EA_SCALABLE, REG_V5, REG_V1, INS_OPTS_SCALABLE_D); + theEmitter->emitIns_R_R(INS_sve_uunpkhi, EA_SCALABLE, REG_V5, REG_V1, INS_OPTS_SCALABLE_B); // UUNPKLO ., . theEmitter->emitIns_R_R(INS_sve_uunpklo, EA_SCALABLE, REG_V8, REG_V6, INS_OPTS_SCALABLE_S); diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index d015332a76d8b7..90447292dbe837 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -910,9 +910,9 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) // in ARM64/ARM // Setup loReg (and hiReg) from the internal registers that we reserved in lower. // - regNumber loReg = treeNode->ExtractTempReg(); + regNumber loReg = internalRegisters.Extract(treeNode); #ifdef TARGET_ARM64 - regNumber hiReg = treeNode->GetSingleTempReg(); + regNumber hiReg = internalRegisters.GetSingle(treeNode); #endif // TARGET_ARM64 GenTreeLclVarCommon* srcLclNode = nullptr; @@ -1268,7 +1268,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) regNumber allocatedValueReg = REG_NA; if (treeNode->gtNumRegs == 1) { - allocatedValueReg = treeNode->ExtractTempReg(); + allocatedValueReg = internalRegisters.Extract(treeNode); } // Pick a register to store intermediate values in for the to-stack @@ -1640,19 +1640,19 @@ void CodeGen::genCodeForLclFld(GenTreeLclFld* tree) { // Arm supports unaligned access only for integer types, // load the floating data as 1 or 2 integer registers and convert them to float. - regNumber addr = tree->ExtractTempReg(); + regNumber addr = internalRegisters.Extract(tree); emit->emitIns_R_S(INS_lea, EA_PTRSIZE, addr, varNum, offs); if (targetType == TYP_FLOAT) { - regNumber floatAsInt = tree->GetSingleTempReg(); + regNumber floatAsInt = internalRegisters.GetSingle(tree); emit->emitIns_R_R(INS_ldr, EA_4BYTE, floatAsInt, addr); emit->emitIns_Mov(INS_vmov_i2f, EA_4BYTE, targetReg, floatAsInt, /* canSkip */ false); } else { - regNumber halfdoubleAsInt1 = tree->ExtractTempReg(); - regNumber halfdoubleAsInt2 = tree->GetSingleTempReg(); + regNumber halfdoubleAsInt1 = internalRegisters.Extract(tree); + regNumber halfdoubleAsInt2 = internalRegisters.GetSingle(tree); emit->emitIns_R_R_I(INS_ldr, EA_4BYTE, halfdoubleAsInt1, addr, 0); emit->emitIns_R_R_I(INS_ldr, EA_4BYTE, halfdoubleAsInt2, addr, 4); emit->emitIns_R_R_R(INS_vmov_i2d, EA_8BYTE, targetReg, halfdoubleAsInt1, halfdoubleAsInt2); @@ -1694,7 +1694,7 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node) // The index is never contained, even if it is a constant. assert(index->isUsedFromReg()); - const regNumber tmpReg = node->ExtractTempReg(); + const regNumber tmpReg = internalRegisters.Extract(node); regNumber indexReg = index->GetRegNum(); @@ -1742,7 +1742,7 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node) #ifdef TARGET_ARM64 if (!index->TypeIs(TYP_I_IMPL)) { - const regNumber tmpReg2 = node->ExtractTempReg(); + const regNumber tmpReg2 = internalRegisters.Extract(node); GetEmitter()->emitIns_Mov(INS_mov, EA_4BYTE, tmpReg2, indexReg, /* canSkip */ false); indexReg = tmpReg2; } @@ -2662,7 +2662,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) const int dstOffsetAdjustment = helper.GetDstOffset() - dstRegAddrAlignment; dstRegAddrAlignment = 0; - const regNumber tempReg = node->ExtractTempReg(RBM_ALLINT); + const regNumber tempReg = internalRegisters.Extract(node, RBM_ALLINT); genInstrWithConstant(INS_add, EA_PTRSIZE, tempReg, dstReg, dstOffsetAdjustment, tempReg); dstReg = tempReg; @@ -2684,7 +2684,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) if (shouldUse16ByteWideInstrs) { - const regNumber simdReg = node->GetSingleTempReg(RBM_ALLFLOAT); + const regNumber simdReg = internalRegisters.GetSingle(node, RBM_ALLFLOAT); const int initValue = (src->AsIntCon()->IconValue() & 0xFF); emit->emitIns_R_I(INS_movi, EA_16BYTE, simdReg, initValue, INS_OPTS_16B); @@ -2967,23 +2967,23 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) if ((srcOffsetAdjustment != 0) && (dstOffsetAdjustment != 0)) { - const regNumber tempReg1 = node->ExtractTempReg(RBM_ALLINT); + const regNumber tempReg1 = internalRegisters.Extract(node, RBM_ALLINT); genInstrWithConstant(INS_add, EA_PTRSIZE, tempReg1, srcReg, srcOffsetAdjustment, tempReg1); srcReg = tempReg1; - const regNumber tempReg2 = node->ExtractTempReg(RBM_ALLINT); + const regNumber tempReg2 = internalRegisters.Extract(node, RBM_ALLINT); genInstrWithConstant(INS_add, EA_PTRSIZE, tempReg2, dstReg, dstOffsetAdjustment, tempReg2); dstReg = tempReg2; } else if (srcOffsetAdjustment != 0) { - const regNumber tempReg = node->ExtractTempReg(RBM_ALLINT); + const regNumber tempReg = internalRegisters.Extract(node, RBM_ALLINT); genInstrWithConstant(INS_add, EA_PTRSIZE, tempReg, srcReg, srcOffsetAdjustment, tempReg); srcReg = tempReg; } else if (dstOffsetAdjustment != 0) { - const regNumber tempReg = node->ExtractTempReg(RBM_ALLINT); + const regNumber tempReg = internalRegisters.Extract(node, RBM_ALLINT); genInstrWithConstant(INS_add, EA_PTRSIZE, tempReg, dstReg, dstOffsetAdjustment, tempReg); dstReg = tempReg; } @@ -2991,16 +2991,16 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) regNumber intReg1 = REG_NA; regNumber intReg2 = REG_NA; - const unsigned intRegCount = node->AvailableTempRegCount(RBM_ALLINT); + const unsigned intRegCount = internalRegisters.Count(node, RBM_ALLINT); if (intRegCount >= 2) { - intReg1 = node->ExtractTempReg(RBM_ALLINT); - intReg2 = node->ExtractTempReg(RBM_ALLINT); + intReg1 = internalRegisters.Extract(node, RBM_ALLINT); + intReg2 = internalRegisters.Extract(node, RBM_ALLINT); } else if (intRegCount == 1) { - intReg1 = node->GetSingleTempReg(RBM_ALLINT); + intReg1 = internalRegisters.GetSingle(node, RBM_ALLINT); intReg2 = rsGetRsvdReg(); } else @@ -3010,8 +3010,8 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) if (shouldUse16ByteWideInstrs) { - const regNumber simdReg1 = node->ExtractTempReg(RBM_ALLFLOAT); - const regNumber simdReg2 = node->GetSingleTempReg(RBM_ALLFLOAT); + const regNumber simdReg1 = internalRegisters.Extract(node, RBM_ALLFLOAT); + const regNumber simdReg2 = internalRegisters.GetSingle(node, RBM_ALLFLOAT); helper.Unroll(FP_REGSIZE_BYTES, intReg1, simdReg1, simdReg2, srcReg, dstReg, GetEmitter()); } @@ -3022,7 +3022,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) #endif // TARGET_ARM64 #ifdef TARGET_ARM - const regNumber tempReg = node->ExtractTempReg(RBM_ALLINT); + const regNumber tempReg = internalRegisters.Extract(node, RBM_ALLINT); for (unsigned regSize = REGSIZE_BYTES; size > 0; size -= regSize, srcOffset += regSize, dstOffset += regSize) { @@ -3147,13 +3147,13 @@ void CodeGen::genCodeForMemmove(GenTreeBlk* tree) if (size >= simdSize) { // Number of SIMD regs needed to save the whole src to regs. - const unsigned numberOfSimdRegs = tree->AvailableTempRegCount(RBM_ALLFLOAT); + const unsigned numberOfSimdRegs = internalRegisters.Count(tree, RBM_ALLFLOAT); // Pop all temp regs to a local array, currently, this impl is limited with LSRA's MaxInternalCount regNumber tempRegs[LinearScan::MaxInternalCount] = {}; for (unsigned i = 0; i < numberOfSimdRegs; i++) { - tempRegs[i] = tree->ExtractTempReg(RBM_ALLFLOAT); + tempRegs[i] = internalRegisters.Extract(tree, RBM_ALLFLOAT); } auto emitSimdLoadStore = [&](bool load) { @@ -3190,15 +3190,15 @@ void CodeGen::genCodeForMemmove(GenTreeBlk* tree) const unsigned loadStoreSize = 1 << BitOperations::Log2(size); if (loadStoreSize == size) { - const regNumber tmpReg = tree->GetSingleTempReg(RBM_ALLINT); + const regNumber tmpReg = internalRegisters.GetSingle(tree, RBM_ALLINT); emitLoadStore(/* load */ true, loadStoreSize, tmpReg, 0); emitLoadStore(/* load */ false, loadStoreSize, tmpReg, 0); } else { - assert(tree->AvailableTempRegCount() == 2); - const regNumber tmpReg1 = tree->ExtractTempReg(RBM_ALLINT); - const regNumber tmpReg2 = tree->ExtractTempReg(RBM_ALLINT); + assert(internalRegisters.Count(tree) == 2); + const regNumber tmpReg1 = internalRegisters.Extract(tree, RBM_ALLINT); + const regNumber tmpReg2 = internalRegisters.Extract(tree, RBM_ALLINT); emitLoadStore(/* load */ true, loadStoreSize, tmpReg1, 0); emitLoadStore(/* load */ true, loadStoreSize, tmpReg2, size - loadStoreSize); emitLoadStore(/* load */ false, loadStoreSize, tmpReg1, 0); @@ -3258,7 +3258,7 @@ void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) // Extend liveness of dstReg in case if it gets killed by the store. gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); - const regNumber offsetReg = initBlkNode->GetSingleTempReg(); + const regNumber offsetReg = internalRegisters.GetSingle(initBlkNode); instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE); BasicBlock* loop = genCreateTempLabel(); @@ -3342,7 +3342,7 @@ void CodeGen::genCall(GenTreeCall* call) const regNumber regThis = genGetThisArgReg(call); #if defined(TARGET_ARM) - const regNumber tmpReg = call->ExtractTempReg(); + const regNumber tmpReg = internalRegisters.Extract(call); GetEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, tmpReg, regThis, 0); #elif defined(TARGET_ARM64) GetEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, REG_ZR, regThis, 0); @@ -3368,7 +3368,7 @@ void CodeGen::genCall(GenTreeCall* call) (call->IsVirtualStubRelativeIndir() && (call->gtEntryPoint.accessType == IAT_VALUE))); assert(call->gtControlExpr == nullptr); - regNumber tmpReg = call->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(call); // Register where we save call address in should not be overridden by epilog. assert((genRegMask(tmpReg) & (RBM_INT_CALLEE_TRASH & ~RBM_LR)) == genRegMask(tmpReg)); @@ -3376,7 +3376,7 @@ void CodeGen::genCall(GenTreeCall* call) call->IsVirtualStubRelativeIndir() ? compiler->virtualStubParamInfo->GetReg() : REG_R2R_INDIRECT_PARAM; GetEmitter()->emitIns_R_R(ins_Load(TYP_I_IMPL), emitActualTypeSize(TYP_I_IMPL), tmpReg, callAddrReg); // We will use this again when emitting the jump in genCallInstruction in the epilog - call->gtRsvdRegs |= genRegMask(tmpReg); + internalRegisters.Add(call, genRegMask(tmpReg)); } #endif @@ -3666,15 +3666,25 @@ void CodeGen::genCallInstruction(GenTreeCall* call) if (callThroughIndirReg != REG_NA) { assert(call->IsR2ROrVirtualStubRelativeIndir()); - regNumber targetAddrReg = call->GetSingleTempReg(); + regNumber targetAddrReg; // For fast tailcalls we have already loaded the call target when processing the call node. if (!call->IsFastTailCall()) { +#ifdef TARGET_ARM + // For arm32 we've allocated an internal register to load the target into. + // Loading into lr takes 4 bytes (instead of potentially 2 with another register). + targetAddrReg = internalRegisters.GetSingle(call); +#else + // For arm64 we just use lr and skip the internal register. + targetAddrReg = REG_LR; +#endif + GetEmitter()->emitIns_R_R(ins_Load(TYP_I_IMPL), emitActualTypeSize(TYP_I_IMPL), targetAddrReg, callThroughIndirReg); } else { + targetAddrReg = internalRegisters.GetSingle(call); // Register where we save call address in should not be overridden by epilog. assert((genRegMask(targetAddrReg) & (RBM_INT_CALLEE_TRASH & ~RBM_LR)) == genRegMask(targetAddrReg)); } @@ -3731,7 +3741,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) #ifdef TARGET_ARM if (!validImmForBL((ssize_t)addr)) { - regNumber tmpReg = call->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(call); instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, tmpReg, (ssize_t)addr); // clang-format off genEmitCall(emitter::EC_INDIR_R, @@ -4721,7 +4731,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) if (offset != 0) { - regNumber tmpReg = lea->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(lea); // When generating fully interruptible code we have to use the "large offset" sequence // when calculating a EA_BYREF as we can't report a byref that points outside of the object @@ -4803,7 +4813,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) else { // We require a tmpReg to hold the offset - regNumber tmpReg = lea->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(lea); // First load tmpReg with the large offset constant instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset); diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 417a7e6f31695d..6dcbba13b48533 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -62,10 +62,117 @@ CodeGenInterface* getCodeGenerator(Compiler* comp) return new (comp, CMK_Codegen) CodeGen(comp); } +NodeInternalRegisters::NodeInternalRegisters(Compiler* comp) + : m_table(comp->getAllocator(CMK_LSRA)) +{ +} + +//------------------------------------------------------------------------ +// Add: Add internal allocated registers for the specified node. +// +// Parameters: +// tree - IR node to add internal allocated registers to +// regs - Registers to add +// +void NodeInternalRegisters::Add(GenTree* tree, regMaskTP regs) +{ + assert(regs != RBM_NONE); + + regMaskTP* result = m_table.LookupPointerOrAdd(tree, RBM_NONE); + *result |= regs; +} + +//------------------------------------------------------------------------ +// Extract: Find the lowest number temporary register from the gtRsvdRegs set +// that is also in the optional given mask (typically, RBM_ALLINT or +// RBM_ALLFLOAT), and return it. Remove this register from the temporary +// register set, so it won't be returned again. +// +// Parameters: +// tree - IR node whose internal registers to extract +// mask - Mask of allowed registers that can be returned +// +// Returns: +// Register number. +// +regNumber NodeInternalRegisters::Extract(GenTree* tree, regMaskTP mask) +{ + regMaskTP* regs = m_table.LookupPointer(tree); + assert(regs != nullptr); + + regMaskTP availableSet = *regs & mask; + assert(availableSet != RBM_NONE); + + regNumber result = genFirstRegNumFromMask(availableSet); + *regs ^= genRegMask(result); + + return result; +} + +//------------------------------------------------------------------------ +// GetSingleTempReg: There is expected to be exactly one available temporary register +// in the given mask in the internal register set. Get that register. No future calls to get +// a temporary register are expected. Removes the register from the set, but only in +// DEBUG to avoid doing unnecessary work in non-DEBUG builds. +// +// Parameters: +// tree - IR node whose internal registers to extract +// mask - Mask of allowed registers that can be returned +// +// Returns: +// Register number. +// +regNumber NodeInternalRegisters::GetSingle(GenTree* tree, regMaskTP mask) +{ + regMaskTP* regs = m_table.LookupPointer(tree); + assert(regs != nullptr); + + regMaskTP availableSet = *regs & mask; + assert(genExactlyOneBit(availableSet)); + + regNumber result = genFirstRegNumFromMask(availableSet); + INDEBUG(*regs &= ~genRegMask(result)); + + return result; +} + +//------------------------------------------------------------------------ +// GetAll: Get all internal registers for the specified IR node. +// +// Parameters: +// tree - IR node whose internal registers to query +// +// Returns: +// Mask of registers. +// +regMaskTP NodeInternalRegisters::GetAll(GenTree* tree) +{ + regMaskTP regs; + return m_table.Lookup(tree, ®s) ? regs : RBM_NONE; +} + +//------------------------------------------------------------------------ +// Count: return the number of available temporary registers in the (optional) +// given set (typically, RBM_ALLINT or RBM_ALLFLOAT). +// +// Parameters: +// tree - IR node whose internal registers to query +// mask - Mask of registers to count +// +// Returns: +// Count of nodes +// +unsigned NodeInternalRegisters::Count(GenTree* tree, regMaskTP mask) +{ + regMaskTP regs; + return m_table.Lookup(tree, ®s) ? genCountBits(regs & mask) : 0; +} + // CodeGen constructor CodeGenInterface::CodeGenInterface(Compiler* theCompiler) : gcInfo(theCompiler) , regSet(theCompiler, gcInfo) + , internalRegisters(theCompiler) , compiler(theCompiler) , treeLifeUpdater(nullptr) { @@ -1665,7 +1772,7 @@ void CodeGen::genGenerateCode(void** codePtr, uint32_t* nativeSizeOfCode) if (genWriteBarrierUsed && JitConfig.EnableExtraSuperPmiQueries() && !compiler->opts.IsReadyToRun()) { void* ignored; - for (int i = CORINFO_HELP_ASSIGN_REF; i <= CORINFO_HELP_ASSIGN_STRUCT; i++) + for (int i = CORINFO_HELP_ASSIGN_REF; i <= CORINFO_HELP_BULK_WRITEBARRIER; i++) { compiler->compGetHelperFtn((CorInfoHelpFunc)i, &ignored); } @@ -2802,7 +2909,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ -#if !defined(TARGET_RISCV64) struct RegNode; struct RegNodeEdge @@ -3346,8 +3452,6 @@ void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed) } } -#endif - // ----------------------------------------------------------------------------- // genGetParameterHomingTempRegisterCandidates: Get the registers that are // usable during register homing. @@ -4122,15 +4226,77 @@ void CodeGen::genEnregisterOSRArgsAndLocals() } } +#if defined(SWIFT_SUPPORT) || defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64) +//----------------------------------------------------------------------------- +// genHomeSwiftStructParameters: Move the incoming segment to the local stack frame. +// +// Arguments: +// lclNum - Number of local variable to home +// seg - Stack segment of the local variable to home +// initReg - Scratch register to use if needed +// initRegStillZeroed - Set to false if the scratch register was needed +// +void CodeGen::genHomeStackSegment(unsigned lclNum, + const ABIPassingSegment& seg, + regNumber initReg, + bool* initRegStillZeroed) +{ + var_types loadType = TYP_UNDEF; + switch (seg.Size) + { + case 1: + loadType = TYP_UBYTE; + break; + case 2: + loadType = TYP_USHORT; + break; + case 3: + case 4: + loadType = TYP_INT; + break; + case 5: + case 6: + case 7: + case 8: + loadType = TYP_LONG; + break; + default: + assert(!"Unexpected segment size for struct parameter not passed implicitly by ref"); + return; + } + emitAttr size = emitTypeSize(loadType); + + int loadOffset = (int)seg.GetStackOffset(); + if (isFramePointerUsed()) + { + loadOffset -= genCallerSPtoFPdelta(); + } + else + { + loadOffset -= genCallerSPtoInitialSPdelta(); + } + +#ifdef TARGET_XARCH + GetEmitter()->emitIns_R_AR(ins_Load(loadType), size, initReg, genFramePointerReg(), loadOffset); +#else + genInstrWithConstant(ins_Load(loadType), size, initReg, genFramePointerReg(), loadOffset, initReg); +#endif + GetEmitter()->emitIns_S_R(ins_Store(loadType), size, initReg, lclNum, seg.Offset); + + if (initRegStillZeroed) + *initRegStillZeroed = false; +} +#endif // defined(SWIFT_SUPPORT) || defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64) + #ifdef SWIFT_SUPPORT //----------------------------------------------------------------------------- // genHomeSwiftStructParameters: -// Reassemble Swift struct parameters if necessary. +// Reassemble Swift struct parameters if necessary. // -// Parameters: -// handleStack - If true, reassemble the segments that were passed on the stack. -// If false, reassemble the segments that were passed in registers. +// Arguments: +// handleStack - If true, reassemble the segments that were passed on the stack. +// If false, reassemble the segments that were passed in registers. // void CodeGen::genHomeSwiftStructParameters(bool handleStack) { @@ -4176,55 +4342,63 @@ void CodeGen::genHomeSwiftStructParameters(bool handleStack) } else { - var_types loadType = TYP_UNDEF; - switch (seg.Size) - { - case 1: - loadType = TYP_UBYTE; - break; - case 2: - loadType = TYP_USHORT; - break; - case 4: - loadType = TYP_INT; - break; - case 8: - loadType = TYP_LONG; - break; - default: - assert(!"Unexpected segment size for struct parameter not passed implicitly by ref"); - continue; - } + // We can use REG_SCRATCH as a temporary register here as we ensured that during LSRA build. + genHomeStackSegment(lclNum, seg, REG_SCRATCH, nullptr); + } + } + } +} +#endif - int offset; - if (isFramePointerUsed()) - { - offset = -genCallerSPtoFPdelta(); - } - else - { - offset = -genCallerSPtoInitialSPdelta(); - } +//----------------------------------------------------------------------------- +// genHomeStackPartOfSplitParameter: Home the tail (stack) portion of a split parameter next to where the head +// (register) portion is homed. +// +// Arguments: +// initReg - scratch register to use if needed +// initRegStillZeroed - set to false if scratch register was needed +// +// Notes: +// No-op on platforms where argument registers are already homed to form a contiguous space with incoming stack. +// +void CodeGen::genHomeStackPartOfSplitParameter(regNumber initReg, bool* initRegStillZeroed) +{ +#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64) + unsigned lclNum = 0; + for (; lclNum < compiler->info.compArgsCount; lclNum++) + { + LclVarDsc* var = compiler->lvaGetDesc(lclNum); + if (!var->lvOnFrame || !varTypeIsStruct(var)) + { + continue; + } - offset += (int)seg.GetStackOffset(); + const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(lclNum); + if (abiInfo.IsSplitAcrossRegistersAndStack()) + { + assert(var->lvIsSplit); + JITDUMP("Homing stack part of split parameter V%02u\n", lclNum); - // Move the incoming segment to the local stack frame. We can - // use REG_SCRATCH as a temporary register here as we ensured - // that during LSRA build. -#ifdef TARGET_XARCH - GetEmitter()->emitIns_R_AR(ins_Load(loadType), emitTypeSize(loadType), REG_SCRATCH, - genFramePointerReg(), offset); -#else - genInstrWithConstant(ins_Load(loadType), emitTypeSize(loadType), REG_SCRATCH, genFramePointerReg(), - offset, REG_SCRATCH); -#endif + assert(abiInfo.NumSegments == 2); + assert(abiInfo.Segments[0].GetRegister() == REG_ARG_LAST); + assert(abiInfo.Segments[1].GetStackOffset() == 0); + const ABIPassingSegment& seg = abiInfo.Segments[1]; - GetEmitter()->emitIns_S_R(ins_Store(loadType), emitTypeSize(loadType), REG_SCRATCH, lclNum, seg.Offset); + genHomeStackSegment(lclNum, seg, initReg, initRegStillZeroed); + +#ifdef DEBUG + for (lclNum += 1; lclNum < compiler->info.compArgsCount; lclNum++) + { + const ABIPassingInformation& abiInfo2 = compiler->lvaGetParameterABIInfo(lclNum); + // There should be only one split parameter + assert(!abiInfo2.IsSplitAcrossRegistersAndStack()); } +#endif + break; } } +#endif // TARGET_RISCV64 || TARGET_LOONGARCH64 } -#endif /*----------------------------------------------------------------------------- * @@ -4744,20 +4918,13 @@ void CodeGen::genFinalizeFrame() #endif // defined(TARGET_XARCH) #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - if (isFramePointerUsed()) - { - // For a FP based frame we have to push/pop the FP register - // - maskCalleeRegsPushed |= RBM_FPBASE; + // This assert check that we are not using REG_FP + assert(!regSet.rsRegsModified(RBM_FPBASE)); - // This assert check that we are not using REG_FP - // as both the frame pointer and as a codegen register - // - assert(!regSet.rsRegsModified(RBM_FPBASE)); - } + assert(isFramePointerUsed()); + // we always push FP/RA. See genPushCalleeSavedRegisters + maskCalleeRegsPushed |= (RBM_FPBASE | RBM_RA); - // we always push RA. See genPushCalleeSavedRegisters - maskCalleeRegsPushed |= RBM_RA; #endif // TARGET_LOONGARCH64 || TARGET_RISCV64 compiler->compCalleeRegsPushed = genCountBits(maskCalleeRegsPushed); @@ -5550,6 +5717,8 @@ void CodeGen::genFnProlog() { compiler->lvaUpdateArgsWithInitialReg(); + genHomeStackPartOfSplitParameter(initReg, &initRegZeroed); + if ((intRegState.rsCalleeRegArgMaskLiveIn | floatRegState.rsCalleeRegArgMaskLiveIn) != RBM_NONE) { genHomeRegisterParams(initReg, &initRegZeroed); diff --git a/src/coreclr/jit/codegeninterface.h b/src/coreclr/jit/codegeninterface.h index ef87ccca858702..608c72c22d48d0 100644 --- a/src/coreclr/jit/codegeninterface.h +++ b/src/coreclr/jit/codegeninterface.h @@ -46,6 +46,21 @@ struct RegState CodeGenInterface* getCodeGenerator(Compiler* comp); +class NodeInternalRegisters +{ + typedef JitHashTable, regMaskTP> NodeInternalRegistersTable; + NodeInternalRegistersTable m_table; + +public: + NodeInternalRegisters(Compiler* comp); + + void Add(GenTree* tree, regMaskTP reg); + regNumber Extract(GenTree* tree, regMaskTP mask = static_cast(-1)); + regNumber GetSingle(GenTree* tree, regMaskTP mask = static_cast(-1)); + regMaskTP GetAll(GenTree* tree); + unsigned Count(GenTree* tree, regMaskTP mask = static_cast(-1)); +}; + class CodeGenInterface { friend class emitter; @@ -122,9 +137,10 @@ class CodeGenInterface GCInfo gcInfo; - RegSet regSet; - RegState intRegState; - RegState floatRegState; + RegSet regSet; + RegState intRegState; + RegState floatRegState; + NodeInternalRegisters internalRegisters; protected: Compiler* compiler; diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 145c074b8fc681..786f40c2f4ca7d 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1648,7 +1648,6 @@ void CodeGen::genConsumeRegs(GenTree* tree) // Update the life of the lcl var. genUpdateLife(tree); } -#ifdef TARGET_XARCH #ifdef FEATURE_HW_INTRINSICS else if (tree->OperIs(GT_HWINTRINSIC)) { @@ -1656,7 +1655,6 @@ void CodeGen::genConsumeRegs(GenTree* tree) genConsumeMultiOpOperands(hwintrinsic); } #endif // FEATURE_HW_INTRINSICS -#endif // TARGET_XARCH else if (tree->OperIs(GT_BITCAST, GT_NEG, GT_CAST, GT_LSH, GT_RSH, GT_RSZ, GT_ROR, GT_BSWAP, GT_BSWAP16)) { genConsumeRegs(tree->gtGetOp1()); @@ -1907,7 +1905,7 @@ void CodeGen::genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg) { if (sizeReg != REG_NA) { - assert((blkNode->gtRsvdRegs & genRegMask(sizeReg)) != 0); + assert((internalRegisters.GetAll(blkNode) & genRegMask(sizeReg)) != 0); // This can go via helper which takes the size as a native uint. instGen_Set_Reg_To_Imm(EA_PTRSIZE, sizeReg, blkNode->Size()); } diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index 2954a989c74668..6fceb11807ed33 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -190,8 +190,7 @@ void CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg, bool* // reg1 - First register of pair to save. // reg2 - Second register of pair to save. // spOffset - The offset from SP to store reg1 (must be positive or zero). -// spDelta - If non-zero, the amount to add to SP before the register saves (must be negative or -// zero). +// spDelta - Always zero for LoongArch64 now. // useSaveNextPair - True if the last prolog instruction was to save the previous register pair. This // allows us to emit the "save_next" unwind code. // tmpReg - An available temporary register. Needed for the case of large frames. @@ -210,8 +209,7 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1, bool* pTmpRegIsZero) { assert(spOffset >= 0); - assert(spDelta <= 0); - assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned + assert(spDelta == 0); assert(genIsValidFloatReg(reg1) == genIsValidFloatReg(reg2)); // registers must be both general-purpose, or both // FP/SIMD @@ -221,16 +219,6 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1, ins = INS_fst_d; } - if (spDelta != 0) - { - // generate addi.d SP,SP,-imm - genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); - - assert((spDelta + spOffset + 16) <= 0); - - assert(spOffset <= 2031); // 2047-16 - } - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); compiler->unwindSaveReg(reg1, spOffset); @@ -249,8 +237,7 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1, // Arguments: // reg1 - Register to save. // spOffset - The offset from SP to store reg1 (must be positive or zero). -// spDelta - If non-zero, the amount to add to SP before the register saves (must be negative or -// zero). +// spDelta - Always zero for LoongArch64 now. // tmpReg - An available temporary register. Needed for the case of large frames. // pTmpRegIsZero - If we use tmpReg, and pTmpRegIsZero is non-null, we set *pTmpRegIsZero to 'false'. // Otherwise, we don't touch it. @@ -261,8 +248,7 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1, void CodeGen::genPrologSaveReg(regNumber reg1, int spOffset, int spDelta, regNumber tmpReg, bool* pTmpRegIsZero) { assert(spOffset >= 0); - assert(spDelta <= 0); - assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned + assert(spDelta == 0); instruction ins = INS_st_d; if (genIsValidFloatReg(reg1)) @@ -270,12 +256,6 @@ void CodeGen::genPrologSaveReg(regNumber reg1, int spOffset, int spDelta, regNum ins = INS_fst_d; } - if (spDelta != 0) - { - // generate addi.d SP,SP,-imm - genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); - } - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); compiler->unwindSaveReg(reg1, spOffset); } @@ -290,8 +270,7 @@ void CodeGen::genPrologSaveReg(regNumber reg1, int spOffset, int spDelta, regNum // reg1 - First register of pair to restore. // reg2 - Second register of pair to restore. // spOffset - The offset from SP to load reg1 (must be positive or zero). -// spDelta - If non-zero, the amount to add to SP after the register restores (must be positive or -// zero). +// spDelta - Always zero for LoongArch64 now. // useSaveNextPair - True if the last prolog instruction was to save the previous register pair. This // allows us to emit the "save_next" unwind code. // tmpReg - An available temporary register. Needed for the case of large frames. @@ -310,8 +289,7 @@ void CodeGen::genEpilogRestoreRegPair(regNumber reg1, bool* pTmpRegIsZero) { assert(spOffset >= 0); - assert(spDelta >= 0); - assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned + assert(spDelta == 0); assert(genIsValidFloatReg(reg1) == genIsValidFloatReg(reg2)); // registers must be both general-purpose, or both // FP/SIMD @@ -321,27 +299,11 @@ void CodeGen::genEpilogRestoreRegPair(regNumber reg1, ins = INS_fld_d; } - if (spDelta != 0) - { - assert(!useSaveNextPair); - - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg2, REG_SPBASE, spOffset + 8); - compiler->unwindSaveReg(reg2, spOffset + 8); - - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); - compiler->unwindSaveReg(reg1, spOffset); - - // generate addi.d SP,SP,imm - genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); - } - else - { - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg2, REG_SPBASE, spOffset + 8); - compiler->unwindSaveReg(reg2, spOffset + 8); + GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg2, REG_SPBASE, spOffset + 8); + compiler->unwindSaveReg(reg2, spOffset + 8); - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); - compiler->unwindSaveReg(reg1, spOffset); - } + GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); + compiler->unwindSaveReg(reg1, spOffset); } //------------------------------------------------------------------------ @@ -350,8 +312,7 @@ void CodeGen::genEpilogRestoreRegPair(regNumber reg1, // Arguments: // reg1 - Register to restore. // spOffset - The offset from SP to restore reg1 (must be positive or zero). -// spDelta - If non-zero, the amount to add to SP after the register restores (must be positive or -// zero). +// spDelta - Always zero for LoongArch64 now. // tmpReg - An available temporary register. Needed for the case of large frames. // pTmpRegIsZero - If we use tmpReg, and pTmpRegIsZero is non-null, we set *pTmpRegIsZero to 'false'. // Otherwise, we don't touch it. @@ -362,8 +323,7 @@ void CodeGen::genEpilogRestoreRegPair(regNumber reg1, void CodeGen::genEpilogRestoreReg(regNumber reg1, int spOffset, int spDelta, regNumber tmpReg, bool* pTmpRegIsZero) { assert(spOffset >= 0); - assert(spDelta >= 0); - assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned + assert(spDelta == 0); instruction ins = INS_ld_d; if (genIsValidFloatReg(reg1)) @@ -371,20 +331,8 @@ void CodeGen::genEpilogRestoreReg(regNumber reg1, int spOffset, int spDelta, reg ins = INS_fld_d; } - if (spDelta != 0) - { - // ld.d reg1,SP,offset - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); - compiler->unwindSaveReg(reg1, spOffset); - - // generate addi.d SP,SP,imm - genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true); - } - else - { - GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); - compiler->unwindSaveReg(reg1, spOffset); - } + GetEmitter()->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, REG_SPBASE, spOffset); + compiler->unwindSaveReg(reg1, spOffset); } //------------------------------------------------------------------------ @@ -519,12 +467,13 @@ int CodeGen::genGetSlotSizeForRegsInMask(regMaskTP regsMask) // genSaveCalleeSavedRegisterGroup: Saves the group of registers described by the mask. // // Arguments: -// regsMask - a mask of registers for prolog generation; -// spDelta - if non-zero, the amount to add to SP before the first register save (or together with it); -// spOffset - the offset from SP that is the beginning of the callee-saved register area; +// regsMask - a mask of registers for prolog generation; +// spDelta - Always zero for LoongArch64 now. +// spOffset - the offset from SP that is the beginning of the callee-saved register area; // void CodeGen::genSaveCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta, int spOffset) { + assert(spDelta == 0); const int slotSize = genGetSlotSizeForRegsInMask(regsMask); ArrayStack regStack(compiler->getAllocator(CMK_Codegen)); @@ -536,19 +485,16 @@ void CodeGen::genSaveCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta, i if (regPair.reg2 != REG_NA) { // We can use two SD instructions. - genPrologSaveRegPair(regPair.reg1, regPair.reg2, spOffset, spDelta, regPair.useSaveNextPair, REG_R21, - nullptr); + genPrologSaveRegPair(regPair.reg1, regPair.reg2, spOffset, 0, regPair.useSaveNextPair, REG_R21, nullptr); spOffset += 2 * slotSize; } else { // No register pair; we use a SD instruction. - genPrologSaveReg(regPair.reg1, spOffset, spDelta, REG_R21, nullptr); + genPrologSaveReg(regPair.reg1, spOffset, 0, REG_R21, nullptr); spOffset += slotSize; } - - spDelta = 0; // We've now changed SP already, if necessary; don't do it again. } } @@ -574,34 +520,22 @@ void CodeGen::genSaveCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta, i // // Arguments: // regsToSaveMask - The mask of callee-saved registers to save. If empty, this function does nothing. -// lowestCalleeSavedOffset - The offset from SP that is the beginning of the callee-saved register area. Note that -// if non-zero spDelta, then this is the offset of the first save *after* that -// SP adjustment. -// spDelta - If non-zero, the amount to add to SP before the register saves (must be negative or -// zero). +// lowestCalleeSavedOffset - The offset from SP that is the beginning of the callee-saved register area. +// spDelta - Always zero for LoongArch64 now. // // Notes: // The save set can not contain FP/RA in which case FP/RA is saved along with the other callee-saved registers. // void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowestCalleeSavedOffset, int spDelta) { - assert(spDelta <= 0); + assert(spDelta == 0); - unsigned regsToSaveCount = genCountBits(regsToSaveMask); - if (regsToSaveCount == 0) + if (regsToSaveMask == 0) { - if (spDelta != 0) - { - // Currently this is the case for varargs only - // whose size is MAX_REG_ARG * REGSIZE_BYTES = 64 bytes. - genStackPointerAdjustment(spDelta, REG_R21, nullptr, /* reportUnwindData */ true); - } return; } - assert((spDelta % 16) == 0); - - assert(regsToSaveCount <= genCountBits(RBM_CALLEE_SAVED)); + assert(genCountBits(regsToSaveMask) <= genCountBits(RBM_CALLEE_SAVED)); // Save integer registers at higher addresses than floating-point registers. @@ -610,15 +544,14 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe if (maskSaveRegsFloat != RBM_NONE) { - genSaveCalleeSavedRegisterGroup(maskSaveRegsFloat, spDelta, lowestCalleeSavedOffset); - spDelta = 0; + genSaveCalleeSavedRegisterGroup(maskSaveRegsFloat, 0, lowestCalleeSavedOffset); lowestCalleeSavedOffset += genCountBits(maskSaveRegsFloat) * FPSAVE_REGSIZE_BYTES; } if (maskSaveRegsInt != RBM_NONE) { - genSaveCalleeSavedRegisterGroup(maskSaveRegsInt, spDelta, lowestCalleeSavedOffset); - // No need to update spDelta, lowestCalleeSavedOffset since they're not used after this. + // No need to update spDelta. + genSaveCalleeSavedRegisterGroup(maskSaveRegsInt, 0, lowestCalleeSavedOffset); } } @@ -627,11 +560,12 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe // // Arguments: // regsMask - a mask of registers for epilog generation; -// spDelta - if non-zero, the amount to add to SP after the last register restore (or together with it); +// spDelta - Always zero for LoongArch64 now. // spOffset - the offset from SP that is the beginning of the callee-saved register area; // void CodeGen::genRestoreCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta, int spOffset) { + assert(spDelta == 0); const int slotSize = genGetSlotSizeForRegsInMask(regsMask); ArrayStack regStack(compiler->getAllocator(CMK_Codegen)); @@ -640,15 +574,6 @@ void CodeGen::genRestoreCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta int stackDelta = 0; for (int i = 0; i < regStack.Height(); ++i) { - bool lastRestoreInTheGroup = (i == regStack.Height() - 1); - bool updateStackDelta = lastRestoreInTheGroup && (spDelta != 0); - if (updateStackDelta) - { - // Update stack delta only if it is the last restore (the first save). - assert(stackDelta == 0); - stackDelta = spDelta; - } - RegPair regPair = regStack.Top(i); if (regPair.reg2 != REG_NA) { @@ -670,10 +595,9 @@ void CodeGen::genRestoreCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta // in the function or funclet epilog. This exactly reverses the actions of genSaveCalleeSavedRegistersHelp(). // // Arguments: -// regsToRestoreMask - The mask of callee-saved registers to restore. If empty, this function does nothing. -// lowestCalleeSavedOffset - The offset from SP that is the beginning of the callee-saved register area. -// spDelta - If non-zero, the amount to add to SP after the register restores (must be positive or -// zero). +// regsToRestoreMask - The mask of callee-saved registers to restore. If empty, this function does nothing. +// lowestCalleeSavedOffset - The offset from SP that is the beginning of the callee-saved register area. +// spDelta - Always zero for LoongArch64 now. // // Here's an example restore sequence: // ld.d s8,sp,#xxx @@ -694,23 +618,15 @@ void CodeGen::genRestoreCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, int lowestCalleeSavedOffset, int spDelta) { - assert(spDelta >= 0); - unsigned regsToRestoreCount = genCountBits(regsToRestoreMask); - if (regsToRestoreCount == 0) + assert(spDelta == 0); + if (regsToRestoreMask == 0) { - if (spDelta != 0) - { - // Currently this is the case for varargs only - // whose size is MAX_REG_ARG * REGSIZE_BYTES = 64 bytes. - genStackPointerAdjustment(spDelta, REG_R21, nullptr, /* reportUnwindData */ true); - } return; } - assert((spDelta % 16) == 0); - - // We also can restore FP and RA, even though they are not in RBM_CALLEE_SAVED. - assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_RA)); + unsigned regsToRestoreCount = genCountBits(regsToRestoreMask); + // The FP and RA are not in RBM_CALLEE_SAVED. + assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED)); // Point past the end, to start. We predecrement to find the offset to load from. static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES); @@ -725,15 +641,13 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in if (maskRestoreRegsInt != RBM_NONE) { - int spIntDelta = (maskRestoreRegsFloat != RBM_NONE) ? 0 : spDelta; // should we delay the SP adjustment? - genRestoreCalleeSavedRegisterGroup(maskRestoreRegsInt, spIntDelta, spOffset); + genRestoreCalleeSavedRegisterGroup(maskRestoreRegsInt, 0, spOffset); spOffset -= genCountBits(maskRestoreRegsInt) * REGSIZE_BYTES; } if (maskRestoreRegsFloat != RBM_NONE) { - // If there is any spDelta, it must be used here. - genRestoreCalleeSavedRegisterGroup(maskRestoreRegsFloat, spDelta, spOffset); + genRestoreCalleeSavedRegisterGroup(maskRestoreRegsFloat, 0, spOffset); // No need to update spOffset since it's not used after this. } } @@ -755,7 +669,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in * filter: a0 = non-zero if the handler should handle the exception, zero otherwise (see GT_RETFILT) * finally/fault: none * - * The LOONGARCH64 funclet prolog is the following (Note: #framesz is total funclet frame size, + * The LoongArch64 funclet prolog is the following (Note: #framesz is total funclet frame size, * including everything; #outsz is outgoing argument space. #framesz must be a multiple of 16): * * Frame type liking: @@ -771,19 +685,17 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in * |-----------------------| * | incoming arguments | * +=======================+ <---- Caller's SP - * | OSR padding | // If required - * |-----------------------| - * | Varargs regs space | // Only for varargs main functions; 64 bytes + * | Varargs regs space | // Only for varargs main functions; not used for LA64. * |-----------------------| * | MonitorAcquired | // 8 bytes; for synchronized methods * |-----------------------| * | PSP slot | // 8 bytes (omitted in NativeAOT ABI) * |-----------------------| - * ~ alignment padding ~ // To make the whole frame 16 byte aligned + * |Callee saved registers | // multiple of 8 bytes, not including FP/RA * |-----------------------| * | Saved FP, RA | // 16 bytes * |-----------------------| - * |Callee saved registers | // multiple of 8 bytes, not includting FP/RA + * ~ alignment padding ~ // To make the whole frame 16 byte aligned * |-----------------------| * | Outgoing arg space | // multiple of 8 bytes; if required (i.e., #outsz != 0) * |-----------------------| <---- Ambient SP @@ -793,38 +705,22 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in * V * * - * Both #1 and #2 only change SP once. That means that there will be a maximum of one alignment slot needed. For the general case, #3, - * it is possible that we will need to add alignment to both changes to SP, leading to 16 bytes of alignment. Remember that the stack - * pointer needs to be 16 byte aligned at all times. The size of the PSP slot plus callee-saved registers space is a maximum of 232 bytes: - * - * FP,RA registers - * 9 int callee-saved register s0-s8 - * 8 float callee-saved registers f24-f31 - * 8 saved integer argument registers a0-a7, if varargs function support. - * 1 PSP slot - * == 20 slots * 8 bytes = 160 bytes. - * * The outgoing argument size, however, can be very large, if we call a function that takes a large number of * arguments (note that we currently use the same outgoing argument space size in the funclet as for the main * function, even if the funclet doesn't have any calls, or has a much smaller, or larger, maximum number of - * outgoing arguments for any call). In that case, we need to 16-byte align the initial change to SP, before - * saving off the callee-saved registers and establishing the PSPsym, so we can use the limited immediate offset - * encodings we have available, before doing another 16-byte aligned SP adjustment to create the outgoing argument - * space. Both changes to SP might need to add alignment padding. - * - * In addition to the above "standard" frames, we also need to support a frame where the saved FP/RA are at the - * highest addresses. This is to match the frame layout (specifically, callee-saved registers including FP/RA - * and the PSPSym) that is used in the main function when a GS cookie is required due to the use of localloc. - * (Note that localloc cannot be used in a funclet.) In these variants, not only has the position of FP/RA - * changed, but where the alignment padding is placed has also changed. - * + * outgoing arguments for any call). * - * Note that in all cases, the PSPSym is in exactly the same position with respect to Caller-SP, and that location is the same relative to Caller-SP - * as in the main function. + * Note that in all cases, the PSPSym is in exactly the same position with respect to Caller-SP, + * and that location is the same relative to Caller-SP as in the main function where higher than + * the callee-saved registers. + * That is to say, the PSPSym's relative offset to Caller-SP is not depended on the callee-saved registers. + * TODO-LoongArch64: the funclet's callee-saved registers should not shared with main function. * * Funclets do not have varargs arguments. However, because the PSPSym must exist at the same offset from Caller-SP as in the main function, we * must add buffer space for the saved varargs/argument registers here, if the main function did the same. * + * Note that localloc cannot be used in a funclet. + * * ; After this header, fill the PSP slot, for use by the VM (it gets reported with the GC info), or by code generation of nested filters. * ; This is not part of the "OS prolog"; it has no associated unwind data, and is not reversed in the funclet epilog. * @@ -880,7 +776,9 @@ void CodeGen::genFuncletProlog(BasicBlock* block) { #ifdef DEBUG if (verbose) + { printf("*************** In genFuncletProlog()\n"); + } #endif assert(block != NULL); @@ -910,42 +808,39 @@ void CodeGen::genFuncletProlog(BasicBlock* block) maskArgRegsLiveIn = RBM_A0; } - regMaskTP maskSaveRegs = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; - int regsSavedSize = (compiler->compCalleeRegsPushed - 2) << 3; + regMaskTP maskSaveRegs = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; + int FP_offset = genFuncletInfo.fiSP_to_CalleeSaved_delta; - int SP_to_CalleeSaved_delta = genFuncletInfo.fiSP_to_CalleeSaved_delta; - if ((SP_to_CalleeSaved_delta + regsSavedSize + genFuncletInfo.fiCalleeSavedPadding) <= 2040) + if ((FP_offset + (genCountBits(maskSaveRegs) << 3)) <= (2040 - 16)) // no FP/RA. { - SP_to_CalleeSaved_delta += genFuncletInfo.fiCalleeSavedPadding; - genStackPointerAdjustment(frameSize, REG_R21, nullptr, /* reportUnwindData */ true); - genSaveCalleeSavedRegistersHelp(maskSaveRegs, SP_to_CalleeSaved_delta, 0); - SP_to_CalleeSaved_delta += regsSavedSize; + GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_RA, REG_SPBASE, SP_to_CalleeSaved_delta); - compiler->unwindSaveReg(REG_RA, SP_to_CalleeSaved_delta); + GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_FP, REG_SPBASE, SP_to_CalleeSaved_delta + 8); - compiler->unwindSaveReg(REG_FP, SP_to_CalleeSaved_delta + 8); + genSaveCalleeSavedRegistersHelp(maskSaveRegs, FP_offset + 16, 0); } else { assert(frameSize < -2040); - int SP_delta = frameSize + SP_to_CalleeSaved_delta; - genStackPointerAdjustment(SP_delta, REG_R21, nullptr, /* reportUnwindData */ true); + genStackPointerAdjustment(frameSize + (FP_offset & -16), REG_R21, nullptr, true); - genSaveCalleeSavedRegistersHelp(maskSaveRegs, genFuncletInfo.fiCalleeSavedPadding, 0); - regsSavedSize += genFuncletInfo.fiCalleeSavedPadding; + frameSize = -(FP_offset & -16); + FP_offset &= 0xf; - GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_RA, REG_SPBASE, regsSavedSize); - compiler->unwindSaveReg(REG_RA, regsSavedSize); + GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_FP, REG_SPBASE, regsSavedSize + 8); - compiler->unwindSaveReg(REG_FP, regsSavedSize + 8); + GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - genStackPointerAdjustment(-SP_to_CalleeSaved_delta, REG_R21, nullptr, /* reportUnwindData */ true); + genSaveCalleeSavedRegistersHelp(maskSaveRegs, FP_offset + 16, 0); + + genStackPointerAdjustment(frameSize, REG_R21, nullptr, true); } // This is the end of the OS-reported prolog for purposes of unwinding @@ -1012,41 +907,28 @@ void CodeGen::genFuncletEpilog() int frameSize = genFuncletInfo.fiSpDelta; assert(frameSize < 0); - regMaskTP regsToRestoreMask = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; - int regsRestoreSize = (compiler->compCalleeRegsPushed - 2) << 3; + regMaskTP maskSaveRegs = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; + int FP_offset = genFuncletInfo.fiSP_to_CalleeSaved_delta; - int SP_to_CalleeSaved_delta = genFuncletInfo.fiSP_to_CalleeSaved_delta; - if ((SP_to_CalleeSaved_delta + regsRestoreSize + genFuncletInfo.fiCalleeSavedPadding) <= 2040) + if ((FP_offset + (genCountBits(maskSaveRegs) << 3)) > (2040 - 16)) // no FP/RA. { - SP_to_CalleeSaved_delta += genFuncletInfo.fiCalleeSavedPadding; - genRestoreCalleeSavedRegistersHelp(regsToRestoreMask, SP_to_CalleeSaved_delta, 0); - SP_to_CalleeSaved_delta += regsRestoreSize; - - GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_RA, REG_SPBASE, SP_to_CalleeSaved_delta); - compiler->unwindSaveReg(REG_RA, SP_to_CalleeSaved_delta); + assert(frameSize < -2040); - GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_FP, REG_SPBASE, SP_to_CalleeSaved_delta + 8); - compiler->unwindSaveReg(REG_FP, SP_to_CalleeSaved_delta + 8); + genStackPointerAdjustment(FP_offset & -16, REG_R21, nullptr, /* reportUnwindData */ true); - genStackPointerAdjustment(-frameSize, REG_R21, nullptr, /* reportUnwindData */ true); + frameSize += FP_offset & -16; + FP_offset = FP_offset & 0xf; } - else - { - assert(frameSize < -2040); - - genStackPointerAdjustment(SP_to_CalleeSaved_delta, REG_R21, nullptr, /* reportUnwindData */ true); - genRestoreCalleeSavedRegistersHelp(regsToRestoreMask, genFuncletInfo.fiCalleeSavedPadding, 0); - regsRestoreSize += genFuncletInfo.fiCalleeSavedPadding; + genRestoreCalleeSavedRegistersHelp(maskSaveRegs, FP_offset + 16, 0); - GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_RA, REG_SPBASE, regsRestoreSize); - compiler->unwindSaveReg(REG_RA, regsRestoreSize); + GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_FP, REG_SPBASE, regsRestoreSize + 8); - compiler->unwindSaveReg(REG_FP, regsRestoreSize + 8); + GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - genStackPointerAdjustment(-frameSize - SP_to_CalleeSaved_delta, REG_R21, nullptr, /* reportUnwindData */ true); - } + genStackPointerAdjustment(-frameSize, REG_R21, nullptr, /* reportUnwindData */ true); GetEmitter()->emitIns_R_R_I(INS_jirl, emitActualTypeSize(TYP_I_IMPL), REG_R0, REG_RA, 0); compiler->unwindReturn(REG_RA); @@ -1072,7 +954,6 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo() } assert(isFramePointerUsed()); - // The frame size and offsets must be finalized assert(compiler->lvaDoneFrameLayout == Compiler::FINAL_FRAME_LAYOUT); @@ -1080,58 +961,40 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo() assert((rsMaskSaveRegs & RBM_RA) != 0); assert((rsMaskSaveRegs & RBM_FP) != 0); - unsigned PSPSize = (compiler->lvaPSPSym != BAD_VAR_NUM) ? 8 : 0; - // Because a method and funclets must have the same caller-relative PSPSym offset, // if there is a PSPSym, we have to pad the funclet frame size for OSR. // - unsigned osrPad = 0; - if (compiler->opts.IsOSR() && (PSPSize > 0)) + int osrPad = 0; + if (compiler->opts.IsOSR()) { - osrPad = compiler->info.compPatchpointInfo->TotalFrameSize(); + osrPad -= compiler->info.compPatchpointInfo->TotalFrameSize(); // OSR pad must be already aligned to stack size. assert((osrPad % STACK_ALIGN) == 0); } - genFuncletInfo.fiCalleeSavedPadding = 0; - genFuncletInfo.fiFunction_CallerSP_to_FP_delta = genCallerSPtoFPdelta() - osrPad; - - unsigned regsSavedSize = genCountBits(rsMaskSaveRegs) << 3; - assert(genCountBits(rsMaskSaveRegs) == compiler->compCalleeRegsPushed); - - unsigned saveRegsPlusPSPSize = regsSavedSize + PSPSize; - - assert(compiler->lvaOutgoingArgSpaceSize % REGSIZE_BYTES == 0); - unsigned outgoingArgSpaceAligned = roundUp(compiler->lvaOutgoingArgSpaceSize, STACK_ALIGN); + /* Now save it for future use */ + genFuncletInfo.fiFunction_CallerSP_to_FP_delta = genCallerSPtoFPdelta() + osrPad; - unsigned funcletFrameSize = osrPad + saveRegsPlusPSPSize + compiler->lvaOutgoingArgSpaceSize; - unsigned funcletFrameSizeAligned = roundUp(funcletFrameSize, STACK_ALIGN); + int funcletFrameSize = compiler->lvaOutgoingArgSpaceSize; - int SP_to_CalleeSaved_delta = compiler->lvaOutgoingArgSpaceSize; - if ((SP_to_CalleeSaved_delta + regsSavedSize) >= 2040) - { - int offset = funcletFrameSizeAligned - SP_to_CalleeSaved_delta; - SP_to_CalleeSaved_delta = AlignUp((UINT)offset, STACK_ALIGN); + genFuncletInfo.fiSP_to_CalleeSaved_delta = funcletFrameSize; - genFuncletInfo.fiCalleeSavedPadding = SP_to_CalleeSaved_delta - offset; - } + funcletFrameSize += genCountBits(rsMaskSaveRegs) * REGSIZE_BYTES; - if (compiler->lvaMonAcquired != BAD_VAR_NUM && !compiler->opts.IsOSR()) + int delta_PSP = -TARGET_POINTER_SIZE; + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) { - // We furthermore allocate the "monitor acquired" bool between PSP and - // the saved registers because this is part of the EnC header. - // Note that OSR methods reuse the monitor bool created by tier 0. - osrPad += compiler->lvaLclSize(compiler->lvaMonAcquired); + delta_PSP -= TARGET_POINTER_SIZE; } - /* Now save it for future use */ - genFuncletInfo.fiSpDelta = -(int)funcletFrameSizeAligned; - genFuncletInfo.fiSaveRegs = rsMaskSaveRegs; - genFuncletInfo.fiSP_to_CalleeSaved_delta = SP_to_CalleeSaved_delta; + funcletFrameSize = funcletFrameSize - delta_PSP - osrPad; + funcletFrameSize = roundUp((unsigned)funcletFrameSize, STACK_ALIGN); - genFuncletInfo.fiSP_to_PSP_slot_delta = funcletFrameSizeAligned - osrPad - 8; - genFuncletInfo.fiCallerSP_to_PSP_slot_delta = -(int)osrPad - 8; + genFuncletInfo.fiSpDelta = -funcletFrameSize; + genFuncletInfo.fiSaveRegs = rsMaskSaveRegs; + genFuncletInfo.fiSP_to_PSP_slot_delta = funcletFrameSize + delta_PSP + osrPad; + genFuncletInfo.fiCallerSP_to_PSP_slot_delta = osrPad + delta_PSP; #ifdef DEBUG if (verbose) @@ -1650,7 +1513,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre else { // Get a temp integer register to compute long address. - // regNumber addrReg = tree->GetSingleTempReg(); + // regNumber addrReg = internalRegisters.GetSingle(tree); // We must load the FP constant from the constant pool // Emit a data section constant for the float or double constant. @@ -2099,12 +1962,12 @@ void CodeGen::genLclHeap(GenTree* tree) // since we don't need any internal registers. if (compiler->info.compInitMem) { - assert(tree->AvailableTempRegCount() == 0); + assert(internalRegisters.Count(tree) == 0); regCnt = targetReg; } else { - regCnt = tree->ExtractTempReg(); + regCnt = internalRegisters.Extract(tree); if (regCnt != targetReg) { emit->emitIns_R_R_I(INS_ori, easz, regCnt, targetReg, 0); @@ -2201,12 +2064,12 @@ void CodeGen::genLclHeap(GenTree* tree) assert(regCnt == REG_NA); if (compiler->info.compInitMem) { - assert(tree->AvailableTempRegCount() == 0); + assert(internalRegisters.Count(tree) == 0); regCnt = targetReg; } else { - regCnt = tree->ExtractTempReg(); + regCnt = internalRegisters.Extract(tree); } instGen_Set_Reg_To_Imm(((unsigned int)amount == amount) ? EA_4BYTE : EA_8BYTE, regCnt, amount); } @@ -2271,7 +2134,7 @@ void CodeGen::genLclHeap(GenTree* tree) // // Setup the regTmp - regNumber regTmp = tree->GetSingleTempReg(); + regNumber regTmp = internalRegisters.GetSingle(tree); assert(regCnt != REG_R21); emit->emitIns_R_R_R(INS_sltu, EA_PTRSIZE, REG_R21, REG_SPBASE, regCnt); @@ -2722,7 +2585,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) unsigned slots = layout->GetSlotCount(); // Temp register(s) used to perform the sequence of loads and stores. - regNumber tmpReg = cpObjNode->ExtractTempReg(); + regNumber tmpReg = internalRegisters.Extract(cpObjNode); regNumber tmpReg2 = REG_NA; assert(genIsValidIntReg(tmpReg)); @@ -2731,7 +2594,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) if (slots > 1) { - tmpReg2 = cpObjNode->GetSingleTempReg(); + tmpReg2 = internalRegisters.GetSingle(cpObjNode); assert(tmpReg2 != tmpReg); assert(genIsValidIntReg(tmpReg2)); assert(tmpReg2 != REG_WRITE_BARRIER_DST_BYREF); @@ -2866,7 +2729,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) regNumber idxReg = treeNode->AsOp()->gtOp1->GetRegNum(); regNumber baseReg = treeNode->AsOp()->gtOp2->GetRegNum(); - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); // load the ip-relative offset (which is relative to start of fgFirstBB) GetEmitter()->emitIns_R_R_I(INS_slli_d, EA_8BYTE, REG_R21, idxReg, 2); @@ -3728,7 +3591,7 @@ void CodeGen::genCkfinite(GenTree* treeNode) emitAttr attr = emitActualTypeSize(treeNode); // Extract exponent into a register. - regNumber intReg = treeNode->GetSingleTempReg(); + regNumber intReg = internalRegisters.GetSingle(treeNode); regNumber fpReg = genConsumeReg(op1); emit->emitIns_R_R(attr == EA_8BYTE ? INS_movfr2gr_d : INS_movfr2gr_s, attr, intReg, fpReg); @@ -4278,9 +4141,17 @@ void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree) int CodeGenInterface::genSPtoFPdelta() const { assert(isFramePointerUsed()); - assert(compiler->compCalleeRegsPushed >= 2); + assert(compiler->compCalleeRegsPushed >= 2); // always FP/RA. - int delta = compiler->lvaOutgoingArgSpaceSize + (compiler->compCalleeRegsPushed << 3) - 8; + int delta = compiler->compLclFrameSize; + if (compiler->lvaPSPSym != BAD_VAR_NUM) + { + delta -= TARGET_POINTER_SIZE; + } + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) + { + delta -= TARGET_POINTER_SIZE; + } assert(delta >= 0); return delta; @@ -5230,7 +5101,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) // Setup loReg from the internal registers that we reserved in lower. // - regNumber loReg = treeNode->ExtractTempReg(); + regNumber loReg = internalRegisters.Extract(treeNode); regNumber addrReg = REG_NA; GenTreeLclVarCommon* varNode = nullptr; @@ -5511,7 +5382,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) assert(source->OperGet() == GT_BLK); assert(varTypeIsStruct(targetType)); - regNumber baseReg = treeNode->ExtractTempReg(); + regNumber baseReg = internalRegisters.Extract(treeNode); regNumber addrReg = REG_NA; GenTreeLclVarCommon* varNode = nullptr; @@ -6148,7 +6019,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode) assert(srcOffset < INT32_MAX - static_cast(size)); assert(dstOffset < INT32_MAX - static_cast(size)); - regNumber tempReg = cpBlkNode->ExtractTempReg(RBM_ALLINT); + regNumber tempReg = internalRegisters.Extract(cpBlkNode, RBM_ALLINT); if (size >= 2 * REGSIZE_BYTES) { @@ -6277,7 +6148,7 @@ void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) // Extend liveness of dstReg in case if it gets killed by the store. gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); - const regNumber offsetReg = initBlkNode->GetSingleTempReg(); + const regNumber offsetReg = internalRegisters.GetSingle(initBlkNode); instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE); // loop begin: @@ -6376,7 +6247,7 @@ void CodeGen::genCall(GenTreeCall* call) (call->IsVirtualStubRelativeIndir() && (call->gtEntryPoint.accessType == IAT_VALUE))); assert(call->gtControlExpr == nullptr); - regNumber tmpReg = call->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(call); // Register where we save call address in should not be overridden by epilog. assert((genRegMask(tmpReg) & (RBM_INT_CALLEE_TRASH & ~RBM_RA)) == genRegMask(tmpReg)); @@ -6384,7 +6255,7 @@ void CodeGen::genCall(GenTreeCall* call) call->IsVirtualStubRelativeIndir() ? compiler->virtualStubParamInfo->GetReg() : REG_R2R_INDIRECT_PARAM; GetEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), emitActualTypeSize(TYP_I_IMPL), tmpReg, callAddrReg, 0); // We will use this again when emitting the jump in genCallInstruction in the epilog - call->gtRsvdRegs |= genRegMask(tmpReg); + internalRegisters.Add(call, genRegMask(tmpReg)); } #endif @@ -6602,7 +6473,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) if (callThroughIndirReg != REG_NA) { assert(call->IsR2ROrVirtualStubRelativeIndir()); - regNumber targetAddrReg = call->GetSingleTempReg(); + regNumber targetAddrReg = internalRegisters.GetSingle(call); // For fast tailcalls we have already loaded the call target when processing the call node. if (!call->IsFastTailCall()) { @@ -7260,7 +7131,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) } else { - regNumber tmpReg = lea->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(lea); noway_assert(tmpReg != index->GetRegNum()); noway_assert(tmpReg != memBase->GetRegNum()); @@ -7297,7 +7168,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) else { // We require a tmpReg to hold the offset - regNumber tmpReg = lea->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(lea); // First load tmpReg with the large offset constant emit->emitIns_I_la(EA_PTRSIZE, tmpReg, offset); @@ -7660,8 +7531,8 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind) * ... * st.d s8,sp,off2+8*8 * - * st.d ra,sp,off3 - * st.d fp,sp,off3+8 + * st.d ra,sp,off3+8 + * st.d fp,sp,off3 * * Notes: * 1. FP is always saved, and the first store is FP, RA. @@ -7669,37 +7540,41 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind) * 3. For frames with varargs, not implemented completely and not tested ! * 4. We allocate the frame here; no further changes to SP are allowed (except in the body, for localloc). * - * For functions with GS and localloc, we change the frame so the frame pointer and RA are saved at the top - * of the frame, just under the varargs registers (if any). Note that the funclet frames must follow the same - * rule, and both main frame and funclet frames (if any) must put PSPSym in the same offset from Caller-SP. + * For functions with GS and localloc, we had saved the frame pointer and RA at the top + * of the frame. Note that the funclet frames must follow the same rule, + * and both main frame and funclet frames (if any) must put PSPSym in the same offset from Caller-SP. * Since this frame type is relatively rare, we force using it via stress modes, for additional coverage. * * The frames look like the following (simplified to only include components that matter for establishing the * frames). See also Compiler::lvaAssignFrameOffsets(). * - * * The LoongArch64's frame layout is liking: * + * If we need to generate a GS cookie, we need to make sure the saved frame pointer and return address + * (FP and RA) are protected from buffer overrun by the GS cookie. + * So we always save the FP/RA along with the rest of the callee-saved registers above. + * * | | * |-----------------------| * | incoming arguments | * +=======================+ <---- Caller's SP - * | Arguments Or | // if needed. * | Varargs regs space | // Only for varargs functions; (varargs not implemented for LoongArch64) * |-----------------------| * | MonitorAcquired | // 8 bytes; for synchronized methods * |-----------------------| - * | PSP slot | // 8 bytes (omitted in NativeAOT ABI) + * | PSPSym | // 8 bytes, Only for frames with EH, (omitted in NativeAOT ABI) * |-----------------------| - * | locals, temps, etc. | + * |Callee saved registers | // not including FP/RA; multiple of 8 bytes * |-----------------------| - * | possible GS cookie | + * | Saved RA | // 8 bytes * |-----------------------| * | Saved FP | // 8 bytes * |-----------------------| - * | Saved RA | // 8 bytes + * | possible GS cookie | * |-----------------------| - * |Callee saved registers | // not including FP/RA; multiple of 8 bytes + * | locals, temps, etc. | + * |-----------------------| + * | possible GS cookie | * |-----------------------| * | Outgoing arg space | // multiple of 8 bytes; if required (i.e., #outsz != 0) * |-----------------------| <---- Ambient SP @@ -7748,6 +7623,9 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe regSet.rsMaskCalleeSaved = rsPushRegs | RBM_FPBASE | RBM_RA; #ifdef DEBUG + JITDUMP("Frame info. #outsz=%d; #framesz=%d; LclFrameSize=%d;\n", unsigned(compiler->lvaOutgoingArgSpaceSize), + genTotalFrameSize(), compiler->compLclFrameSize); + if (compiler->compCalleeRegsPushed != genCountBits(regSet.rsMaskCalleeSaved)) { printf("Error: unexpected number of callee-saved registers to push. Expected: %d. Got: %d ", @@ -7770,84 +7648,52 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe } #endif // DEBUG - // The frameType number is arbitrary, is defined below, and corresponds to one of the frame styles we - // generate based on various sizes. - int frameType = 0; - - // The amount to add from SP before starting to store the callee-saved registers. - int calleeSaveSPDelta = 0; - - // If we need to generate a GS cookie, we need to make sure the saved frame pointer and return address - // (FP and RA) are protected from buffer overrun by the GS cookie. If FP/RA are at the lowest addresses, - // then they are safe, since they are lower than any unsafe buffers. And the GS cookie we add will - // protect our caller's frame. If we have a localloc, however, that is dynamically placed lower than our - // saved FP/RA. In that case, we save FP/RA along with the rest of the callee-saved registers, above - // the GS cookie. - // - // After the frame is allocated, the frame pointer is established, pointing at the saved frame pointer to - // create a frame pointer chain. - // + int totalFrameSize = genTotalFrameSize(); + int leftFrameSize = 0; + int localFrameSize = compiler->compLclFrameSize; + if (compiler->lvaPSPSym != BAD_VAR_NUM) + { + localFrameSize -= TARGET_POINTER_SIZE; + } + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) + { + localFrameSize -= TARGET_POINTER_SIZE; + } - // This will be the starting place for saving the callee-saved registers, in increasing order. - int offset = compiler->lvaOutgoingArgSpaceSize; +#ifdef DEBUG + if (compiler->opts.disAsm) + { + printf("Frame info. #outsz=%d; #framesz=%d; lcl=%d\n", unsigned(compiler->lvaOutgoingArgSpaceSize), + genTotalFrameSize(), localFrameSize); + } +#endif - int totalFrameSize = genTotalFrameSize(); - // The (totalFrameSize <= 2040) condition ensures the offsets of st.d/ld.d. + int FP_offset = localFrameSize; if (totalFrameSize <= 2040) { GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -totalFrameSize); compiler->unwindAllocStack(totalFrameSize); - - // Case #1. - // - // Generate: - // addi.d sp, sp, -framesz - // st.d callee_saved_registers ### not including the fp and ra. - // st.d ra,sp,outsz - // st.d fp,sp,outsz+8 - // - // After saving callee-saved registers, ra and fp, we establish the frame pointer with: - // addi.d fp, sp, (the offset of saving fp) - // We do this *after* saving callee-saved registers, so the prolog/epilog unwind codes mostly match. - - JITDUMP("Frame type 1. #outsz=%d; #framesz=%d; LclFrameSize=%d\n", unsigned(compiler->lvaOutgoingArgSpaceSize), - totalFrameSize, compiler->compLclFrameSize); - - frameType = 1; } else { - JITDUMP("Frame type 2. #outsz=%d; #framesz=%d; LclFrameSize=%d\n", unsigned(compiler->lvaOutgoingArgSpaceSize), - totalFrameSize, compiler->compLclFrameSize); - - frameType = 2; - - if ((offset + (compiler->compCalleeRegsPushed << 3)) >= 2040) - { - offset = totalFrameSize - compiler->lvaOutgoingArgSpaceSize; - calleeSaveSPDelta = AlignUp((UINT)offset, STACK_ALIGN); - offset = calleeSaveSPDelta - offset; - - genStackPointerAdjustment(-calleeSaveSPDelta, initReg, pInitRegZeroed, /* reportUnwindData */ true); - } - else + if ((localFrameSize + (compiler->compCalleeRegsPushed << 3)) > 2040) { - genStackPointerAdjustment(-totalFrameSize, initReg, pInitRegZeroed, /* reportUnwindData */ true); + leftFrameSize = localFrameSize & -16; + totalFrameSize = totalFrameSize - (localFrameSize & -16); + FP_offset = localFrameSize & 0xf; } + genStackPointerAdjustment(-totalFrameSize, initReg, pInitRegZeroed, /* reportUnwindData */ true); } + GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - JITDUMP(" offset=%d, calleeSaveSPDelta=%d\n", offset, calleeSaveSPDelta); - genSaveCalleeSavedRegistersHelp(rsPushRegs, offset, 0); - offset += (int)(genCountBits(rsPushRegs) << 3); - - GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_RA, REG_SPBASE, offset); - compiler->unwindSaveReg(REG_RA, offset); + GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_FP, REG_SPBASE, offset + 8); - compiler->unwindSaveReg(REG_FP, offset + 8); + genSaveCalleeSavedRegistersHelp(rsPushRegs, FP_offset + 16, 0); - JITDUMP(" offsetSpToSavedFp=%d\n", offset + 8); - genEstablishFramePointer(offset + 8, /* reportUnwindData */ true); + JITDUMP(" offsetSpToSavedFp=%d\n", FP_offset); + genEstablishFramePointer(FP_offset, /* reportUnwindData */ true); // For varargs, home the incoming arg registers last. Note that there is nothing to unwind here, // so we just report "NOP" unwind codes. If there's no more frame setup after this, we don't @@ -7858,19 +7704,9 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe NYI_LOONGARCH64("genPushCalleeSavedRegisters unsupports compIsVarArgs"); } -#ifdef DEBUG - if (compiler->opts.disAsm) - { - assert(frameType != 0); - printf("DEBUG: LOONGARCH64, frameType:%d\n\n", frameType); - } -#endif - - if (calleeSaveSPDelta != 0) + if (leftFrameSize != 0) { - assert(frameType == 2); - calleeSaveSPDelta = totalFrameSize - calleeSaveSPDelta; - genStackPointerAdjustment(-calleeSaveSPDelta, initReg, pInitRegZeroed, /* reportUnwindData */ true); + genStackPointerAdjustment(-leftFrameSize, initReg, pInitRegZeroed, /* reportUnwindData */ true); } } @@ -7882,85 +7718,78 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) assert(isFramePointerUsed()); - // This will be the starting place for restoring the callee-saved registers, in decreasing order. - int calleeSaveSPOffset = 0; - int remainingSPSize = 0; - int totalFrameSize = genTotalFrameSize(); - if (totalFrameSize <= 2040) + int localFrameSize = compiler->compLclFrameSize; + if (compiler->lvaPSPSym != BAD_VAR_NUM) + { + localFrameSize -= TARGET_POINTER_SIZE; + } + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) { - JITDUMP("Frame type 1. #outsz=%d; #framesz=%d; localloc? %s\n", unsigned(compiler->lvaOutgoingArgSpaceSize), - totalFrameSize, dspBool(compiler->compLocallocUsed)); + localFrameSize -= TARGET_POINTER_SIZE; + } + + JITDUMP("Frame type. #outsz=%d; #framesz=%d; #calleeSaveRegsPushed:%d; " + "localloc? %s\n", + unsigned(compiler->lvaOutgoingArgSpaceSize), totalFrameSize, compiler->compCalleeRegsPushed, + dspBool(compiler->compLocallocUsed)); + emitter* emit = GetEmitter(); + int FP_offset = localFrameSize; + int remainingSPSize = totalFrameSize; + if (totalFrameSize <= 2040) + { if (compiler->compLocallocUsed) { - int SPtoFPdelta = (compiler->compCalleeRegsPushed << 3) - 8 + compiler->lvaOutgoingArgSpaceSize; - + int SPtoFPdelta = genSPtoFPdelta(); // Restore sp from fp - GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -SPtoFPdelta); + emit->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -SPtoFPdelta); compiler->unwindSetFrameReg(REG_FPBASE, SPtoFPdelta); } - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize; - remainingSPSize = totalFrameSize; } else { - JITDUMP("Frame type 2. #outsz=%d; #framesz=%d; #calleeSaveRegsPushed:%d; " - "localloc? %s\n", - unsigned(compiler->lvaOutgoingArgSpaceSize), totalFrameSize, compiler->compCalleeRegsPushed, - dspBool(compiler->compLocallocUsed)); - - if ((compiler->lvaOutgoingArgSpaceSize + (compiler->compCalleeRegsPushed << 3)) > 2047) + if (compiler->compLocallocUsed) { - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize & -16; - if (compiler->compLocallocUsed) + int SPtoFPdelta = genSPtoFPdelta(); + // Restore sp from fp + if (emitter::isValidSimm12(SPtoFPdelta)) { - int SPtoFPdelta = (compiler->compCalleeRegsPushed << 3) - 8; - - // Restore sp from fp - GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -SPtoFPdelta); - compiler->unwindSetFrameReg(REG_FPBASE, SPtoFPdelta); + emit->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -SPtoFPdelta); } else { - genStackPointerAdjustment(calleeSaveSPOffset, REG_RA, nullptr, /* reportUnwindData */ true); + emit->emitIns_I_la(EA_PTRSIZE, REG_RA, SPtoFPdelta); + emit->emitIns_R_R_R(INS_sub_d, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, REG_RA); } - remainingSPSize = totalFrameSize - calleeSaveSPOffset; - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize - calleeSaveSPOffset; } - else + if ((localFrameSize + (compiler->compCalleeRegsPushed << 3)) > 2040) { - if (compiler->compLocallocUsed) - { - int SPtoFPdelta = (compiler->compCalleeRegsPushed << 3) - 8 + compiler->lvaOutgoingArgSpaceSize; + remainingSPSize = localFrameSize & -16; + genStackPointerAdjustment(remainingSPSize, REG_RA, nullptr, /* reportUnwindData */ true); - // Restore sp from fp - GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -SPtoFPdelta); - compiler->unwindSetFrameReg(REG_FPBASE, SPtoFPdelta); - } - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize; - remainingSPSize = totalFrameSize; + remainingSPSize = totalFrameSize - remainingSPSize; + FP_offset = localFrameSize & 0xf; } } - JITDUMP(" calleeSaveSPOffset=%d\n", calleeSaveSPOffset); - genRestoreCalleeSavedRegistersHelp(regsToRestoreMask, calleeSaveSPOffset, 0); - calleeSaveSPOffset += (compiler->compCalleeRegsPushed - 2) << 3; + JITDUMP(" calleeSaveSPOffset=%d\n", FP_offset + 16); + genRestoreCalleeSavedRegistersHelp(regsToRestoreMask, FP_offset + 16, 0); - GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_RA, REG_SPBASE, calleeSaveSPOffset); - compiler->unwindSaveReg(REG_RA, calleeSaveSPOffset); + emit->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - GetEmitter()->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_FP, REG_SPBASE, calleeSaveSPOffset + 8); - compiler->unwindSaveReg(REG_FP, calleeSaveSPOffset + 8); + emit->emitIns_R_R_I(INS_ld_d, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); if (emitter::isValidUimm11(remainingSPSize)) { - GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, remainingSPSize); + emit->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, remainingSPSize); } else { - GetEmitter()->emitIns_I_la(EA_PTRSIZE, REG_R21, remainingSPSize); - GetEmitter()->emitIns_R_R_R(INS_add_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, REG_R21); + emit->emitIns_I_la(EA_PTRSIZE, REG_R21, remainingSPSize); + emit->emitIns_R_R_R(INS_add_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, REG_R21); } compiler->unwindAllocStack(remainingSPSize); @@ -7972,12 +7801,12 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) if (emitter::isValidUimm11(tier0FrameSize)) { - GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, tier0FrameSize); + emit->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, tier0FrameSize); } else { - GetEmitter()->emitIns_I_la(EA_PTRSIZE, REG_R21, tier0FrameSize); - GetEmitter()->emitIns_R_R_R(INS_add_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, REG_R21); + emit->emitIns_I_la(EA_PTRSIZE, REG_R21, tier0FrameSize); + emit->emitIns_R_R_R(INS_add_d, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, REG_R21); } compiler->unwindAllocStack(tier0FrameSize); } diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 546ba7b3180899..84a2663dcbcce5 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -770,8 +770,8 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in * addi sp, sp, -#framesz ; establish the frame * sd s1, #outsz(sp) ; save callee-saved registers, as necessary * sd s2, #(outsz+8)(sp) - * sd ra, #(outsz+?)(sp) ; save RA (8 bytes) - * sd fp, #(outsz+?+8)(sp) ; save FP (8 bytes) + * sd ra, #(outsz+?+8)(sp) ; save RA (8 bytes) + * sd fp, #(outsz+?)(sp) ; save FP (8 bytes) * * The funclet frame layout: * @@ -779,8 +779,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in * |-----------------------| * | incoming arguments | * +=======================+ <---- Caller's SP - * | Arguments Or | // if needed - * | Varargs regs space | // Only for varargs functions; NYI on RV64 + * | Varargs regs space | // Only for varargs main functions; not used for RV64. * |-----------------------| * | MonitorAcquired | // 8 bytes; for synchronized methods * |-----------------------| @@ -788,11 +787,9 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in * |-----------------------| * ~ alignment padding ~ // To make the whole frame 16 byte aligned * |-----------------------| - * | Saved FP | // 8 bytes - * |-----------------------| - * | Saved RA | // 8 bytes + * |Callee saved registers | // multiple of 8 bytes, not including FP/RA * |-----------------------| - * |Callee saved registers | // multiple of 8 bytes, not includting RA/FP + * | Saved FP, RA | // 16 bytes * |-----------------------| * | Outgoing arg space | // multiple of 8 bytes; if required (i.e., #outsz != 0) * |-----------------------| <---- Ambient SP @@ -801,31 +798,27 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in * | | downward | * V * - * Note, that SP only change once. That means, there will be a maximum of one alignment slot needed. - * Also remember, the stack oiubter needs to be 16 byte aligned at all times. - * The size of the PSP slot plus callee-saved registers space is a maximum of 280 bytes: - * - * RA,FP registers - * 11 int callee-saved register s1-s11 - * 12 float callee-saved registers f8-f9, f18-f27 - * 8 saved integer argument registers a0-a7, if varargs function support. - * 1 PSP slot - * 1 alignment slot or monitor acquired slot - * == 35 slots * 8 bytes = 280 bytes. * * The outgoing argument size, however, can be very large, if we call a function that takes a large number of * arguments (note that we currently use the same outgoing argument space size in the funclet as for the main * function, even if the funclet doesn't have any calls, or has a much smaller, or larger, maximum number of - * outgoing arguments for any call). In that case, we need to 16-byte align the initial change to SP, before - * saving off the callee-saved registers and establishing the PSPsym, so we can use the limited immediate offset - * encodings we have available, before doing another 16-byte aligned SP adjustment to create the outgoing argument - * space. Both changes to SP might need to add alignment padding. + * outgoing arguments for any call). + * + * Note that in all cases, the PSPSym is in exactly the same position with respect to Caller-SP, + * and that location is the same relative to Caller-SP as in the main function where higher than + * the callee-saved registers. + * That is to say, the PSPSym's relative offset to Caller-SP is not depended on the callee-saved registers. + * + * Funclets do not have varargs arguments. However, because the PSPSym must exist at the same offset from Caller-SP as in the main function, we + * must add buffer space for the saved varargs/argument registers here, if the main function did the same. + * + * Note that localloc cannot be used in a funclet. * * An example epilog sequence: * addi sp, sp, #outsz ; if any outgoing argument space * ld s1, #(xxx-8)(sp) ; restore callee-saved registers * ld s2, #xxx(sp) - * ld ra, #(xxx+?-8)(sp) ; restore RA + * ld ra, #(xxx+?+8)(sp) ; restore RA * ld fp, #(xxx+?)(sp) ; restore FP * addi sp, sp, #framesz * jarl zero, ra @@ -840,8 +833,8 @@ void CodeGen::genFuncletProlog(BasicBlock* block) printf("*************** In genFuncletProlog()\n"); } #endif + // TODO-RISCV64: Implement varargs (NYI_RISCV64) - // TODO-RISCV64-CQ: We can use C extension for optimization assert(block != NULL); assert(block->HasFlag(BBF_FUNCLET_BEG)); @@ -852,9 +845,8 @@ void CodeGen::genFuncletProlog(BasicBlock* block) compiler->unwindBegProlog(); - const bool isFilter = (block->bbCatchTyp == BBCT_FILTER); - const int frameSize = genFuncletInfo.fiSpDelta; - + bool isFilter = (block->bbCatchTyp == BBCT_FILTER); + int frameSize = genFuncletInfo.fiSpDelta; assert(frameSize < 0); regMaskTP maskArgRegsLiveIn; @@ -871,53 +863,39 @@ void CodeGen::genFuncletProlog(BasicBlock* block) maskArgRegsLiveIn = RBM_A0; } - regMaskTP maskSaveRegs = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; - int regsSavedSize = (compiler->compCalleeRegsPushed - 2) << 3; - - int calleeSavedDelta = genFuncletInfo.fiSP_to_CalleeSaved_delta; + regMaskTP maskSaveRegs = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; + int FP_offset = genFuncletInfo.fiSP_to_CalleeSaved_delta; - emitter* emit = GetEmitter(); - - if (calleeSavedDelta + regsSavedSize + genFuncletInfo.fiCalleeSavedPadding <= 2040) + if ((FP_offset + (genCountBits(maskSaveRegs) << 3)) <= (2040 - 16)) // no FP/RA. { - calleeSavedDelta += genFuncletInfo.fiCalleeSavedPadding; - - // addi sp, sp, #frameSize genStackPointerAdjustment(frameSize, REG_SCRATCH, nullptr, /* reportUnwindData */ true); - genSaveCalleeSavedRegistersHelp(maskSaveRegs, calleeSavedDelta, 0); - calleeSavedDelta += regsSavedSize; + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - // sd ra, #calleeSavedDelta(sp) - emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_RA, REG_SPBASE, calleeSavedDelta); - compiler->unwindSaveReg(REG_RA, calleeSavedDelta); + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - // sd fp, #(calleeSavedDelta+8)(sp) - emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_FP, REG_SPBASE, calleeSavedDelta + 8); - compiler->unwindSaveReg(REG_FP, calleeSavedDelta + 8); + genSaveCalleeSavedRegistersHelp(maskSaveRegs, FP_offset + 16, 0); } else { assert(frameSize < -2040); - int spDelta = frameSize + calleeSavedDelta; + genStackPointerAdjustment(frameSize + (FP_offset & -16), REG_SCRATCH, nullptr, true); - // addi sp, sp, #spDelta - genStackPointerAdjustment(spDelta, REG_SCRATCH, nullptr, /* reportUnwindData */ true); + frameSize = -(FP_offset & -16); + FP_offset &= 0xf; - genSaveCalleeSavedRegistersHelp(maskSaveRegs, genFuncletInfo.fiCalleeSavedPadding, 0); - regsSavedSize += genFuncletInfo.fiCalleeSavedPadding; + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - // sd ra, #regsSavedSize(sp) - emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_RA, REG_SPBASE, regsSavedSize); - compiler->unwindSaveReg(REG_RA, regsSavedSize); + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - // sd fp, #(regsSavedSize+8)(sp) - emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_FP, REG_SPBASE, regsSavedSize + 8); - compiler->unwindSaveReg(REG_FP, regsSavedSize + 8); + genSaveCalleeSavedRegistersHelp(maskSaveRegs, FP_offset + 16, 0); - // addi sp, sp -#calleeSavedDelta - genStackPointerAdjustment(-calleeSavedDelta, REG_SCRATCH, nullptr, /* reportUnwindData */ true); + genStackPointerAdjustment(frameSize, REG_SCRATCH, nullptr, true); } // This is the end of the OS-reported prolog for purposes of unwinding @@ -977,66 +955,38 @@ void CodeGen::genFuncletEpilog() printf("*************** In genFuncletEpilog()\n"); } #endif - // TODO-RISCV64: Implement varargs (NYI_RISCV64) - // TODO-RISCV64-CQ: We can use C extension for optimization ScopedSetVariable _setGeneratingEpilog(&compiler->compGeneratingEpilog, true); compiler->unwindBegEpilog(); - const int frameSize = genFuncletInfo.fiSpDelta; - + int frameSize = genFuncletInfo.fiSpDelta; assert(frameSize < 0); - regMaskTP maskRestoreRegs = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; - int regsRestoreSize = (compiler->compCalleeRegsPushed - 2) << 3; - - int calleeSavedDelta = genFuncletInfo.fiSP_to_CalleeSaved_delta; - - emitter* emit = GetEmitter(); - regNumber tempReg = rsGetRsvdReg(); + regMaskTP maskSaveRegs = genFuncletInfo.fiSaveRegs & RBM_CALLEE_SAVED; + int FP_offset = genFuncletInfo.fiSP_to_CalleeSaved_delta; - if (calleeSavedDelta + regsRestoreSize + genFuncletInfo.fiCalleeSavedPadding <= 2040) + if ((FP_offset + (genCountBits(maskSaveRegs) << 3)) > (2040 - 16)) // no FP/RA. { - calleeSavedDelta += genFuncletInfo.fiCalleeSavedPadding; - genRestoreCalleeSavedRegistersHelp(maskRestoreRegs, calleeSavedDelta, 0); - calleeSavedDelta += regsRestoreSize; - - // ld ra, #calleeSavedDelta(sp) - emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_RA, REG_SPBASE, calleeSavedDelta); - compiler->unwindSaveReg(REG_RA, calleeSavedDelta); + assert(frameSize < -2040); - // ld fp, #(calleeSavedDelta+8)(sp) - emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_FP, REG_SPBASE, calleeSavedDelta + 8); - compiler->unwindSaveReg(REG_FP, calleeSavedDelta + 8); + genStackPointerAdjustment(FP_offset & -16, REG_SCRATCH, nullptr, /* reportUnwindData */ true); - // addi sp, sp, -#frameSize - genStackPointerAdjustment(-frameSize, tempReg, nullptr, /* reportUnwindData */ true); + frameSize += FP_offset & -16; + FP_offset = FP_offset & 0xf; } - else - { - assert(frameSize < -2040); - // addi sp, sp, #calleeSavedDelta - genStackPointerAdjustment(calleeSavedDelta, tempReg, nullptr, /* reportUnwindData */ true); + genRestoreCalleeSavedRegistersHelp(maskSaveRegs, FP_offset + 16, 0); - genRestoreCalleeSavedRegistersHelp(maskRestoreRegs, genFuncletInfo.fiCalleeSavedPadding, 0); - regsRestoreSize += genFuncletInfo.fiCalleeSavedPadding; + GetEmitter()->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - // ld ra, #regsRestoreSize(sp) - emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_RA, REG_SPBASE, regsRestoreSize); - compiler->unwindSaveReg(REG_RA, regsRestoreSize); + GetEmitter()->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - // ld fp, #(regsRestoreSize+8)(sp) - emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_FP, REG_SPBASE, regsRestoreSize + 8); - compiler->unwindSaveReg(REG_FP, regsRestoreSize + 8); + genStackPointerAdjustment(-frameSize, REG_SCRATCH, nullptr, /* reportUnwindData */ true); - // addi sp, sp, -#(frameSize + calleeSavedDelta) - genStackPointerAdjustment(-(frameSize + calleeSavedDelta), tempReg, nullptr, /* reportUnwindData */ true); - } - - // jarl zero, ra - emit->emitIns_R_R_I(INS_jalr, emitActualTypeSize(TYP_I_IMPL), REG_R0, REG_RA, 0); + GetEmitter()->emitIns_R_R_I(INS_jalr, emitActualTypeSize(TYP_I_IMPL), REG_R0, REG_RA, 0); compiler->unwindReturn(REG_RA); compiler->unwindEndEpilog(); @@ -1059,7 +1009,6 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo() } assert(isFramePointerUsed()); - // The frame size and offsets must be finalized assert(compiler->lvaDoneFrameLayout == Compiler::FINAL_FRAME_LAYOUT); @@ -1067,74 +1016,56 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo() assert((rsMaskSaveRegs & RBM_RA) != 0); assert((rsMaskSaveRegs & RBM_FP) != 0); - unsigned pspSize = (compiler->lvaPSPSym != BAD_VAR_NUM) ? 8 : 0; - - // If there is a PSP slot, we have to pad the funclet frame size for OSR. - // For more details see CodeGen::genFuncletProlog + // Because a method and funclets must have the same caller-relative PSPSym offset, + // if there is a PSPSym, we have to pad the funclet frame size for OSR. // - unsigned osrPad = 0; - if (compiler->opts.IsOSR() && (pspSize != 0)) + int osrPad = 0; + if (compiler->opts.IsOSR()) { - osrPad = compiler->info.compPatchpointInfo->TotalFrameSize(); + osrPad -= compiler->info.compPatchpointInfo->TotalFrameSize(); - // osrPad must be aligned to stackSize - assert(osrPad % STACK_ALIGN == 0); + // OSR pad must be already aligned to stack size. + assert((osrPad % STACK_ALIGN) == 0); } - genFuncletInfo.fiCalleeSavedPadding = 0; - genFuncletInfo.fiFunction_CallerSP_to_FP_delta = genCallerSPtoFPdelta() - osrPad; - - unsigned savedRegsSize = genCountBits(rsMaskSaveRegs); - assert(savedRegsSize == compiler->compCalleeRegsPushed); - savedRegsSize <<= 3; + /* Now save it for future use */ + genFuncletInfo.fiFunction_CallerSP_to_FP_delta = genCallerSPtoFPdelta() + osrPad; - unsigned saveRegsPlusPSPSize = savedRegsSize + pspSize; + int funcletFrameSize = compiler->lvaOutgoingArgSpaceSize; - assert(compiler->lvaOutgoingArgSpaceSize % REGSIZE_BYTES == 0); - unsigned outgoingArgSpaceAligned = roundUp(compiler->lvaOutgoingArgSpaceSize, STACK_ALIGN); + genFuncletInfo.fiSP_to_CalleeSaved_delta = funcletFrameSize; - unsigned funcletFrameSize = osrPad + saveRegsPlusPSPSize + compiler->lvaOutgoingArgSpaceSize; - unsigned funcletFrameSizeAligned = roundUp(funcletFrameSize, STACK_ALIGN); + funcletFrameSize += genCountBits(rsMaskSaveRegs) * REGSIZE_BYTES; - int SP_to_CalleeSaved_delta = compiler->lvaOutgoingArgSpaceSize; - if ((SP_to_CalleeSaved_delta + savedRegsSize) >= 2040) + int delta_PSP = -TARGET_POINTER_SIZE; + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) { - int offset = funcletFrameSizeAligned - SP_to_CalleeSaved_delta; - SP_to_CalleeSaved_delta = AlignUp((UINT)offset, STACK_ALIGN); - - genFuncletInfo.fiCalleeSavedPadding = SP_to_CalleeSaved_delta - offset; + delta_PSP -= TARGET_POINTER_SIZE; } - if (compiler->lvaMonAcquired != BAD_VAR_NUM && !compiler->opts.IsOSR()) - { - // We furthermore allocate the "monitor acquired" bool between PSP and - // the saved registers because this is part of the EnC header. - // Note that OSR methods reuse the monitor bool created by tier 0. - osrPad += compiler->lvaLclSize(compiler->lvaMonAcquired); - } + funcletFrameSize = funcletFrameSize - delta_PSP - osrPad; + funcletFrameSize = roundUp((unsigned)funcletFrameSize, STACK_ALIGN); - /* Now save it for future use */ - genFuncletInfo.fiSpDelta = -(int)funcletFrameSizeAligned; + genFuncletInfo.fiSpDelta = -funcletFrameSize; genFuncletInfo.fiSaveRegs = rsMaskSaveRegs; - genFuncletInfo.fiSP_to_CalleeSaved_delta = SP_to_CalleeSaved_delta; - genFuncletInfo.fiSP_to_PSP_slot_delta = funcletFrameSizeAligned - osrPad - 8; - genFuncletInfo.fiCallerSP_to_PSP_slot_delta = -(int)osrPad - 8; + genFuncletInfo.fiSP_to_PSP_slot_delta = funcletFrameSize + delta_PSP + osrPad; + genFuncletInfo.fiCallerSP_to_PSP_slot_delta = osrPad + delta_PSP; #ifdef DEBUG if (verbose) { printf("\n"); printf("Funclet prolog / epilog info\n"); - printf(" Save regs: "); + printf(" Save regs: "); dspRegMask(genFuncletInfo.fiSaveRegs); printf("\n"); if (compiler->opts.IsOSR()) { - printf(" OSR Pad: %d\n", osrPad); + printf(" OSR Pad: %d\n", osrPad); } - printf(" Function CallerSP-to-FP delta: %d\n", genFuncletInfo.fiFunction_CallerSP_to_FP_delta); + printf(" Function CallerSP-to-FP delta: %d\n", genFuncletInfo.fiFunction_CallerSP_to_FP_delta); printf(" SP to CalleeSaved location delta: %d\n", genFuncletInfo.fiSP_to_CalleeSaved_delta); - printf(" SP delta: %d\n", genFuncletInfo.fiSpDelta); + printf(" SP delta: %d\n", genFuncletInfo.fiSpDelta); } assert(genFuncletInfo.fiSP_to_CalleeSaved_delta >= 0); @@ -1605,7 +1536,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre else { // Get a temp integer register to compute long address. - // regNumber addrReg = tree->GetSingleTempReg(); + // regNumber addrReg = internalRegisters.GetSingle(tree); // We must load the FP constant from the constant pool // Emit a data section constant for the float or double constant. @@ -1685,7 +1616,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode) assert(EA_SIZE(attr) == EA_4BYTE); if (isUnsigned) { - regNumber tempReg = treeNode->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(treeNode); emit->emitIns_R_R_I(INS_slli, EA_8BYTE, tempReg, op1->GetRegNum(), 32); emit->emitIns_R_R_I(INS_slli, EA_8BYTE, targetReg, op2->GetRegNum(), 32); emit->emitIns_R_R_R(INS_mulhu, EA_8BYTE, targetReg, tempReg, targetReg); @@ -2051,7 +1982,7 @@ void CodeGen::genLclHeap(GenTree* tree) } else { - regCnt = tree->ExtractTempReg(); + regCnt = internalRegisters.Extract(tree); if (regCnt != targetReg) { emit->emitIns_R_R_I(INS_ori, easz, regCnt, targetReg, 0); @@ -2081,7 +2012,7 @@ void CodeGen::genLclHeap(GenTree* tree) unsigned outgoingArgSpaceAligned = roundUp(compiler->lvaOutgoingArgSpaceSize, STACK_ALIGN); // assert((compiler->lvaOutgoingArgSpaceSize % STACK_ALIGN) == 0); // This must be true for the stack to remain // // aligned - tempReg = tree->ExtractTempReg(); + tempReg = internalRegisters.Extract(tree); genInstrWithConstant(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, outgoingArgSpaceAligned, tempReg); stackAdjustment += outgoingArgSpaceAligned; } @@ -2136,7 +2067,7 @@ void CodeGen::genLclHeap(GenTree* tree) else { if (tempReg == REG_NA) - tempReg = tree->ExtractTempReg(); + tempReg = internalRegisters.Extract(tree); emit->emitLoadImmediate(EA_PTRSIZE, tempReg, amount); emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, tempReg); } @@ -2154,7 +2085,7 @@ void CodeGen::genLclHeap(GenTree* tree) } else { - regCnt = tree->ExtractTempReg(); + regCnt = internalRegisters.Extract(tree); } instGen_Set_Reg_To_Imm(((unsigned int)amount == amount) ? EA_4BYTE : EA_8BYTE, regCnt, amount); } @@ -2221,9 +2152,9 @@ void CodeGen::genLclHeap(GenTree* tree) // if (tempReg == REG_NA) - tempReg = tree->ExtractTempReg(); + tempReg = internalRegisters.Extract(tree); - regNumber rPageSize = tree->GetSingleTempReg(); + regNumber rPageSize = internalRegisters.GetSingle(tree); assert(regCnt != tempReg); emit->emitIns_R_R_R(INS_sltu, EA_PTRSIZE, tempReg, REG_SPBASE, regCnt); @@ -2428,7 +2359,7 @@ void CodeGen::genCodeForDivMod(GenTreeOp* tree) ssize_t intConst = (int)(divisorOp->AsIntCon()->gtIconVal); if (!emitter::isGeneralRegister(divisorReg)) { - tempReg = tree->GetSingleTempReg(); + tempReg = internalRegisters.GetSingle(tree); divisorReg = tempReg; } emit->emitLoadImmediate(EA_PTRSIZE, divisorReg, intConst); @@ -2451,7 +2382,7 @@ void CodeGen::genCodeForDivMod(GenTreeOp* tree) if ((exceptions & ExceptionSetFlags::ArithmeticException) != ExceptionSetFlags::None) { if (tempReg == REG_NA) - tempReg = tree->GetSingleTempReg(); + tempReg = internalRegisters.GetSingle(tree); // Check if the divisor is not -1 branch to 'sdivLabel' emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, tempReg, REG_ZERO, -1); @@ -2677,7 +2608,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) unsigned slots = layout->GetSlotCount(); // Temp register(s) used to perform the sequence of loads and stores. - regNumber tmpReg = cpObjNode->ExtractTempReg(); + regNumber tmpReg = internalRegisters.Extract(cpObjNode); regNumber tmpReg2 = REG_NA; assert(genIsValidIntReg(tmpReg)); @@ -2686,7 +2617,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) if (slots > 1) { - tmpReg2 = cpObjNode->GetSingleTempReg(); + tmpReg2 = internalRegisters.GetSingle(cpObjNode); assert(tmpReg2 != tmpReg); assert(genIsValidIntReg(tmpReg2)); assert(tmpReg2 != REG_WRITE_BARRIER_DST_BYREF); @@ -2821,7 +2752,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) regNumber idxReg = treeNode->AsOp()->gtOp1->GetRegNum(); regNumber baseReg = treeNode->AsOp()->gtOp2->GetRegNum(); - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); // load the ip-relative offset (which is relative to start of fgFirstBB) GetEmitter()->emitIns_R_R_I(INS_slli, EA_8BYTE, tmpReg, idxReg, 2); @@ -2921,7 +2852,7 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode) regNumber loc = locOp->GetRegNum(); regNumber val = valOp->GetRegNum(); regNumber comparand = comparandOp->GetRegNum(); - regNumber storeErr = treeNode->ExtractTempReg(RBM_ALLINT); + regNumber storeErr = internalRegisters.Extract(treeNode, RBM_ALLINT); // Register allocator should have extended the lifetimes of all input and internal registers // They should all be different @@ -3628,7 +3559,7 @@ void CodeGen::genFloatToIntCast(GenTree* treeNode) genConsumeOperands(treeNode->AsOp()); - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); assert(tmpReg != treeNode->GetRegNum()); assert(tmpReg != op1->GetRegNum()); @@ -3675,7 +3606,7 @@ void CodeGen::genCkfinite(GenTree* treeNode) emitAttr attr = emitActualTypeSize(treeNode); // Extract exponent into a register. - regNumber intReg = treeNode->GetSingleTempReg(); + regNumber intReg = internalRegisters.GetSingle(treeNode); regNumber fpReg = genConsumeReg(op1); emit->emitIns_R_R(attr == EA_4BYTE ? INS_fclass_s : INS_fclass_d, attr, intReg, fpReg); @@ -3740,7 +3671,7 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) } else if (tree->OperIs(GT_EQ)) { - regNumber tempReg = tree->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(tree); skipLabel = genCreateTempLabel(); emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, targetReg, regOp1); emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, tempReg, regOp2); @@ -3785,7 +3716,7 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) } else if (tree->OperIs(GT_NE)) { - regNumber tempReg = tree->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(tree); emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, targetReg, regOp1); emit->emitIns_R_R(cmpSize == EA_4BYTE ? INS_fclass_s : INS_fclass_d, cmpSize, tempReg, regOp2); emit->emitIns_R_R_R(INS_or, EA_8BYTE, tempReg, targetReg, tempReg); @@ -3824,7 +3755,7 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) { imm = static_cast(imm); - regNumber tmpRegOp1 = tree->GetSingleTempReg(); + regNumber tmpRegOp1 = internalRegisters.GetSingle(tree); assert(regOp1 != tmpRegOp1); emit->emitIns_R_R_I(INS_slli, EA_8BYTE, tmpRegOp1, regOp1, 32); @@ -3953,7 +3884,7 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree) if (cmpSize == EA_4BYTE) { regNumber tmpRegOp1 = REG_RA; - regNumber tmpRegOp2 = tree->GetSingleTempReg(); + regNumber tmpRegOp2 = internalRegisters.GetSingle(tree); assert(regOp1 != tmpRegOp2); assert(regOp2 != tmpRegOp2); @@ -4224,9 +4155,17 @@ void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree) int CodeGenInterface::genSPtoFPdelta() const { assert(isFramePointerUsed()); - assert(compiler->compCalleeRegsPushed >= 2); + assert(compiler->compCalleeRegsPushed >= 2); // always FP/RA. - int delta = compiler->lvaOutgoingArgSpaceSize + (compiler->compCalleeRegsPushed << 3) - 8; + int delta = compiler->compLclFrameSize; + if (compiler->lvaPSPSym != BAD_VAR_NUM) + { + delta -= TARGET_POINTER_SIZE; + } + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) + { + delta -= TARGET_POINTER_SIZE; + } assert(delta >= 0); return delta; @@ -5341,7 +5280,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) // Setup loReg from the internal registers that we reserved in lower. // - regNumber loReg = treeNode->ExtractTempReg(); + regNumber loReg = internalRegisters.Extract(treeNode); GenTreeLclVarCommon* srcLclNode = nullptr; regNumber addrReg = REG_NA; @@ -5584,7 +5523,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) regNumber allocatedValueReg = REG_NA; if (treeNode->gtNumRegs == 1) { - allocatedValueReg = treeNode->ExtractTempReg(); + allocatedValueReg = internalRegisters.Extract(treeNode); } // Pick a register to store intermediate values in for the to-stack @@ -5731,13 +5670,13 @@ void CodeGen::genRangeCheck(GenTree* oper) if (genActualType(length) == TYP_INT) { - regNumber tempReg = oper->ExtractTempReg(); + regNumber tempReg = internalRegisters.Extract(oper); GetEmitter()->emitIns_R_R_I(INS_addiw, EA_4BYTE, tempReg, lengthReg, 0); // sign-extend lengthReg = tempReg; } if (genActualType(index) == TYP_INT) { - regNumber tempReg = oper->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(oper); GetEmitter()->emitIns_R_R_I(INS_addiw, EA_4BYTE, tempReg, indexReg, 0); // sign-extend indexReg = tempReg; } @@ -5820,7 +5759,7 @@ void CodeGen::genCodeForShift(GenTree* tree) if (tree->OperIs(GT_ROR, GT_ROL)) { - regNumber tempReg = tree->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(tree); unsigned immWidth = emitter::getBitWidth(size); // For RISCV64, immWidth will be set to 32 or 64 if (!shiftBy->IsCnsIntOrI()) { @@ -6010,7 +5949,7 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node) // The index is never contained, even if it is a constant. assert(index->isUsedFromReg()); - regNumber tempReg = node->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(node); // Generate the bounds check if necessary. if (node->IsBoundsChecked()) @@ -6217,7 +6156,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode) assert(srcOffset < INT32_MAX - static_cast(size)); assert(dstOffset < INT32_MAX - static_cast(size)); - regNumber tempReg = cpBlkNode->ExtractTempReg(RBM_ALLINT); + regNumber tempReg = internalRegisters.Extract(cpBlkNode, RBM_ALLINT); if (size >= 2 * REGSIZE_BYTES) { @@ -6346,7 +6285,7 @@ void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) // Extend liveness of dstReg in case if it gets killed by the store. gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); - const regNumber tempReg = initBlkNode->GetSingleTempReg(); + const regNumber tempReg = internalRegisters.GetSingle(initBlkNode); instGen_Set_Reg_To_Imm(EA_PTRSIZE, tempReg, size - TARGET_POINTER_SIZE); // tempReg = dstReg + tempReg (a new interior pointer, but in a nongc region) @@ -6452,7 +6391,7 @@ void CodeGen::genCall(GenTreeCall* call) (call->IsVirtualStubRelativeIndir() && (call->gtEntryPoint.accessType == IAT_VALUE))); assert(call->gtControlExpr == nullptr); - regNumber tmpReg = call->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(call); // Register where we save call address in should not be overridden by epilog. assert((genRegMask(tmpReg) & (RBM_INT_CALLEE_TRASH & ~RBM_RA)) == genRegMask(tmpReg)); @@ -6460,7 +6399,7 @@ void CodeGen::genCall(GenTreeCall* call) call->IsVirtualStubRelativeIndir() ? compiler->virtualStubParamInfo->GetReg() : REG_R2R_INDIRECT_PARAM; GetEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), emitActualTypeSize(TYP_I_IMPL), tmpReg, callAddrReg, 0); // We will use this again when emitting the jump in genCallInstruction in the epilog - call->gtRsvdRegs |= genRegMask(tmpReg); + internalRegisters.Add(call, genRegMask(tmpReg)); } #endif @@ -6678,7 +6617,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) if (callThroughIndirReg != REG_NA) { assert(call->IsR2ROrVirtualStubRelativeIndir()); - regNumber targetAddrReg = call->GetSingleTempReg(); + regNumber targetAddrReg = internalRegisters.GetSingle(call); // For fast tailcalls we have already loaded the call target when processing the call node. if (!call->IsFastTailCall()) { @@ -6946,7 +6885,7 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d case GenIntCastDesc::CHECK_UINT_RANGE: { - regNumber tempReg = cast->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(cast); // We need to check if the value is not greater than 0xFFFFFFFF // if the upper 32 bits are zero. ssize_t imm = -1; @@ -6960,7 +6899,7 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d case GenIntCastDesc::CHECK_POSITIVE_INT_RANGE: { - regNumber tempReg = cast->GetSingleTempReg(); + regNumber tempReg = internalRegisters.GetSingle(cast); // We need to check if the value is not greater than 0x7FFFFFFF // if the upper 33 bits are zero. // instGen_Set_Reg_To_Imm(EA_8BYTE, tempReg, 0xFFFFFFFF80000000LL); @@ -6976,7 +6915,7 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d case GenIntCastDesc::CHECK_INT_RANGE: { - const regNumber tempReg = cast->GetSingleTempReg(); + const regNumber tempReg = internalRegisters.GetSingle(cast); assert(tempReg != reg); GetEmitter()->emitLoadImmediate(EA_8BYTE, tempReg, INT32_MAX); genJumpToThrowHlpBlk_la(SCK_OVERFLOW, INS_blt, tempReg, nullptr, reg); @@ -6991,7 +6930,7 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d assert(desc.CheckKind() == GenIntCastDesc::CHECK_SMALL_INT_RANGE); const int castMaxValue = desc.CheckSmallIntMax(); const int castMinValue = desc.CheckSmallIntMin(); - const regNumber tempReg = cast->GetSingleTempReg(); + const regNumber tempReg = internalRegisters.GetSingle(cast); instruction ins; if (castMaxValue > 2047) @@ -7290,7 +7229,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) assert(isPow2(lea->gtScale)); BitScanForward(&scale, lea->gtScale); assert(scale <= 4); - regNumber scaleTempReg = scale ? lea->ExtractTempReg() : REG_NA; + regNumber scaleTempReg = scale ? internalRegisters.Extract(lea) : REG_NA; if (offset == 0) { @@ -7311,7 +7250,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) } else { - regNumber tmpReg = lea->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(lea); noway_assert(tmpReg != index->GetRegNum()); noway_assert(tmpReg != memBase->GetRegNum()); @@ -7348,7 +7287,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) else { // We require a tmpReg to hold the offset - regNumber tmpReg = lea->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(lea); // First load tmpReg with the large offset constant emit->emitLoadImmediate(EA_PTRSIZE, tmpReg, offset); @@ -7733,8 +7672,8 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind) * sd s11, #(offset+8*10)(sp) * * ; save ra, fp - * sd ra, #offset3(sp) ; save RA (8 bytes) - * sd fp, #(offset3+8)(sp) ; save FP (8 bytes) + * sd ra, #offset3+8(sp) ; save RA (8 bytes) + * sd fp, #(offset3)(sp) ; save FP (8 bytes) * * Notes: * 1. FP is always saved, and the first store is FP, RA. @@ -7742,9 +7681,9 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind) * 3. For frames with varargs, not implemented completely and not tested ! * 4. We allocate the frame here; no further changes to SP are allowed (except in the body, for localloc). * - * For functions with GS and localloc, we change the frame so the frame pointer and RA are saved at the top - * of the frame, just under the varargs registers (if any). Note that the funclet frames must follow the same - * rule, and both main frame and funclet frames (if any) must put PSPSym in the same offset from Caller-SP. + * For functions with GS and localloc, we had saved the frame pointer and RA at the top + * of the frame. Note that the funclet frames must follow the same rule, + * and both main frame and funclet frames (if any) must put PSPSym in the same offset from Caller-SP. * Since this frame type is relatively rare, we force using it via stress modes, for additional coverage. * * The frames look like the following (simplified to only include components that matter for establishing the @@ -7752,6 +7691,10 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind) * * The RISC-V's frame layout is liking: * + * If we need to generate a GS cookie, we need to make sure the saved frame pointer and return address + * (FP and RA) are protected from buffer overrun by the GS cookie. + * So we always save the FP/RA along with the rest of the callee-saved registers above. + * * | | * |-----------------------| * | incoming arguments | @@ -7763,15 +7706,17 @@ void CodeGen::instGen_MemoryBarrier(BarrierKind barrierKind) * |-----------------------| * | PSP slot | // 8 bytes (omitted in NativeAOT ABI) * |-----------------------| - * | locals, temps, etc. | - * |-----------------------| - * | possible GS cookie | + * |Callee saved registers | // not including FP/RA; multiple of 8 bytes * |-----------------------| * | Saved FP | // 8 bytes * |-----------------------| * | Saved RA | // 8 bytes * |-----------------------| - * |Callee saved registers | // not including FP/RA; multiple of 8 bytes + * | possible GS cookie | + * |-----------------------| + * | locals, temps, etc. | + * |-----------------------| + * | possible GS cookie | * |-----------------------| * | Outgoing arg space | // multiple of 8 bytes; if required (i.e., #outsz != 0) * |-----------------------| <---- Ambient SP @@ -7785,12 +7730,6 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe { assert(compiler->compGeneratingProlog); - // The 'initReg' could have been calculated as one of the callee-saved registers (let's say T0, T1 and T2 are in - // use, so the next possible register is S1, which should be callee-save register). This is fine, as long as we - // save callee-saved registers before using 'initReg' for the first time. Instead, we can use REG_SCRATCH - // beforehand. We don't care if REG_SCRATCH will be overwritten, so we'll skip 'RegZeroed check'. - // - // Unlike on x86/x64, we can also push float registers to stack regMaskTP rsPushRegs = regSet.rsGetModifiedCalleeSavedRegsMask(); #if ETW_EBP_FRAMED @@ -7800,7 +7739,7 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe } #endif - // On RV64 we always use the FP (frame-pointer) + // We always use the FP (frame-pointer). assert(isFramePointerUsed()); // @@ -7823,25 +7762,25 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe // is not worth it. // - // we will push callee-saved registers along with fp and ra registers to stack - regMaskTP rsPushRegsMask = rsPushRegs | RBM_FP | RBM_RA; - regSet.rsMaskCalleeSaved = rsPushRegsMask; + regSet.rsMaskCalleeSaved = rsPushRegs | RBM_FPBASE | RBM_RA; #ifdef DEBUG - if (compiler->compCalleeRegsPushed != genCountBits(rsPushRegsMask)) + JITDUMP("Frame info. #outsz=%d; #framesz=%d; LclFrameSize=%d;\n", unsigned(compiler->lvaOutgoingArgSpaceSize), + genTotalFrameSize(), compiler->compLclFrameSize); + + if (compiler->compCalleeRegsPushed != genCountBits(regSet.rsMaskCalleeSaved)) { printf("Error: unexpected number of callee-saved registers to push. Expected: %d. Got: %d ", - compiler->compCalleeRegsPushed, genCountBits(rsPushRegsMask)); - dspRegMask(rsPushRegsMask); + compiler->compCalleeRegsPushed, genCountBits(rsPushRegs | RBM_FPBASE | RBM_RA)); + dspRegMask(rsPushRegs | RBM_FPBASE | RBM_RA); printf("\n"); - assert(compiler->compCalleeRegsPushed == genCountBits(rsPushRegsMask)); + assert(compiler->compCalleeRegsPushed == genCountBits(rsPushRegs | RBM_FPBASE | RBM_RA)); } if (verbose) { - regMaskTP maskSaveRegsFloat = rsPushRegs & RBM_FLT_CALLEE_SAVED; - regMaskTP maskSaveRegsInt = rsPushRegs & RBM_INT_CALLEE_SAVED; - + regMaskTP maskSaveRegsFloat = rsPushRegs & RBM_ALLFLOAT; + regMaskTP maskSaveRegsInt = rsPushRegs & ~maskSaveRegsFloat; printf("Save float regs: "); dspRegMask(maskSaveRegsFloat); printf("\n"); @@ -7851,80 +7790,57 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe } #endif // DEBUG - // The frameType number is arbitrary, is defined below, and corresponds to one of the frame styles we - // generate based on various sizes. - int frameType = 0; - - // The amount to subtract from SP before starting to store the callee-saved registers. It might be folded into the - // first save instruction as a "predecrement" amount, if possible. - int calleeSaveSPDelta = 0; - - // If we need to generate a GS cookie, we need to make sure the saved frame pointer and return address - // (FP and RA) are protected from buffer overrun by the GS cookie. If FP/RA are at the lowest addresses, - // then they are safe, since they are lower than any unsafe buffers. And the GS cookie we add will - // protect our caller's frame. If we have a localloc, however, that is dynamically placed lower than our - // saved FP/RA. In that case, we save FP/RA along with the rest of the callee-saved registers, above - // the GS cookie. - // - // After the frame is allocated, the frame pointer is established, pointing at the saved frame pointer to - // create a frame pointer chain. - // - - // This will be the starting place for saving the callee-saved registers, in increasing order. - int offset = compiler->lvaOutgoingArgSpaceSize; - int totalFrameSize = genTotalFrameSize(); + int leftFrameSize = 0; + int localFrameSize = compiler->compLclFrameSize; + if (compiler->lvaPSPSym != BAD_VAR_NUM) + { + localFrameSize -= TARGET_POINTER_SIZE; + } + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) + { + localFrameSize -= TARGET_POINTER_SIZE; + } - emitter* emit = GetEmitter(); +#ifdef DEBUG + if (compiler->opts.disAsm) + { + printf("Frame info. #outsz=%d; #framesz=%d; lcl=%d\n", unsigned(compiler->lvaOutgoingArgSpaceSize), + genTotalFrameSize(), localFrameSize); + } +#endif - // ensure offset of sd/ld + int FP_offset = localFrameSize; if (totalFrameSize <= 2040) { - frameType = 1; - - emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -totalFrameSize); + GetEmitter()->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -totalFrameSize); compiler->unwindAllocStack(totalFrameSize); - - JITDUMP("Frame type 1. #outsz=%d; #framesz=%d; LclFrameSize=%d\n", unsigned(compiler->lvaOutgoingArgSpaceSize), - totalFrameSize, compiler->compLclFrameSize); } else { - frameType = 2; - // we have to adjust stack pointer; probably using add instead of addi - - JITDUMP("Frame type 2. #outsz=%d; #framesz=%d; LclFrameSize=%d\n", unsigned(compiler->lvaOutgoingArgSpaceSize), - totalFrameSize, compiler->compLclFrameSize); - - if ((offset + (compiler->compCalleeRegsPushed << 3)) >= 2040) + if ((localFrameSize + (compiler->compCalleeRegsPushed << 3)) > 2040) { - offset = totalFrameSize - compiler->lvaOutgoingArgSpaceSize; - calleeSaveSPDelta = AlignUp((UINT)offset, STACK_ALIGN); - offset = calleeSaveSPDelta - offset; - - genStackPointerAdjustment(-calleeSaveSPDelta, REG_SCRATCH, nullptr, /* reportUnwindData */ true); - } - else - { - genStackPointerAdjustment(-totalFrameSize, REG_SCRATCH, nullptr, /* reportUnwindData */ true); + leftFrameSize = localFrameSize & -16; + totalFrameSize = totalFrameSize - (localFrameSize & -16); + FP_offset = localFrameSize & 0xf; } + // The 'initReg' could have been calculated as one of the callee-saved registers (let's say T0, T1 and T2 are in + // use, so the next possible register is S1, which should be callee-save register). This is fine, as long as we + // save callee-saved registers before using 'initReg' for the first time. Instead, we can use REG_SCRATCH + // beforehand. We don't care if REG_SCRATCH will be overwritten, so we'll skip 'RegZeroed check'. + // TODO-RV64: this should be resolved before calling `genPushCalleeSavedRegisters`. + genStackPointerAdjustment(-totalFrameSize, REG_SCRATCH, nullptr, /* reportUnwindData */ true); } + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); - JITDUMP(" offset=%d, calleeSaveSPDelta=%d\n", offset, calleeSaveSPDelta); - - genSaveCalleeSavedRegistersHelp(rsPushRegs, offset, 0); - offset += (int)(genCountBits(rsPushRegs) << 3); // each reg has 8 bytes - - // From now on, we can safely use initReg. + GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_RA, REG_SPBASE, offset); - compiler->unwindSaveReg(REG_RA, offset); + genSaveCalleeSavedRegistersHelp(rsPushRegs, FP_offset + 16, 0); - emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_FP, REG_SPBASE, offset + 8); - compiler->unwindSaveReg(REG_FP, offset + 8); - - JITDUMP(" offsetSpToSavedFp=%d\n", offset + 8); - genEstablishFramePointer(offset + 8, /* reportUnwindData */ true); + JITDUMP(" offsetSpToSavedFp=%d\n", FP_offset); + genEstablishFramePointer(FP_offset, /* reportUnwindData */ true); // For varargs, home the incoming arg registers last. Note that there is nothing to unwind here, // so we just report "NOP" unwind codes. If there's no more frame setup after this, we don't @@ -7935,18 +7851,9 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe NYI_RISCV64("genPushCalleeSavedRegisters unsupports compIsVarArgs"); } -#ifdef DEBUG - if (compiler->opts.disAsm) + if (leftFrameSize != 0) { - printf("DEBUG: RISCV64, frameType:%d\n\n", frameType); - } -#endif - - if (calleeSaveSPDelta != 0) - { - assert(frameType == 2); - calleeSaveSPDelta = totalFrameSize - calleeSaveSPDelta; - genStackPointerAdjustment(-calleeSaveSPDelta, initReg, pInitRegZeroed, /* reportUnwindData */ true); + genStackPointerAdjustment(-leftFrameSize, REG_SCRATCH, nullptr, /* reportUnwindData */ true); } } @@ -7956,80 +7863,72 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) regMaskTP regsToRestoreMask = regSet.rsGetModifiedCalleeSavedRegsMask(); - // On RV64 we always use the FP (frame-pointer) assert(isFramePointerUsed()); - int totalFrameSize = genTotalFrameSize(); - int remainingSPSize = totalFrameSize; - int callerSPtoFPdelta = 0; - int calleeSaveSPOffset = 0; // This will be the starting place for restoring - // the callee-saved registers, in decreasing order. + int totalFrameSize = genTotalFrameSize(); + int localFrameSize = compiler->compLclFrameSize; + if (compiler->lvaPSPSym != BAD_VAR_NUM) + { + localFrameSize -= TARGET_POINTER_SIZE; + } + if ((compiler->lvaMonAcquired != BAD_VAR_NUM) && !compiler->opts.IsOSR()) + { + localFrameSize -= TARGET_POINTER_SIZE; + } - emitter* emit = GetEmitter(); + JITDUMP("Frame type. #outsz=%d; #framesz=%d; #calleeSaveRegsPushed:%d; " + "localloc? %s\n", + unsigned(compiler->lvaOutgoingArgSpaceSize), totalFrameSize, compiler->compCalleeRegsPushed, + dspBool(compiler->compLocallocUsed)); - // ensure offset of sd/ld + emitter* emit = GetEmitter(); + int FP_offset = localFrameSize; + int remainingSPSize = totalFrameSize; if (totalFrameSize <= 2040) { - JITDUMP("Frame type 1. #outsz=%d; #framesz=%d; localloc? %s\n", unsigned(compiler->lvaOutgoingArgSpaceSize), - totalFrameSize, dspBool(compiler->compLocallocUsed)); - if (compiler->compLocallocUsed) { - callerSPtoFPdelta = (compiler->compCalleeRegsPushed << 3) - 8 + compiler->lvaOutgoingArgSpaceSize; + int SPtoFPdelta = genSPtoFPdelta(); + // Restore sp from fp + emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -SPtoFPdelta); + compiler->unwindSetFrameReg(REG_FPBASE, SPtoFPdelta); } - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize; - // remainingSPSize = totalFrameSize; } else { - JITDUMP("Frame type 2. #outsz=%d; #framesz=%d; calleeSaveRegsPushed: %d; localloc? %s\n", - unsigned(compiler->lvaOutgoingArgSpaceSize), totalFrameSize, compiler->compCalleeRegsPushed, - dspBool(compiler->compLocallocUsed)); - - if ((compiler->lvaOutgoingArgSpaceSize + (compiler->compCalleeRegsPushed << 3)) > 2047) + if (compiler->compLocallocUsed) { - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize & 0xfffffff0; - - if (compiler->compLocallocUsed) + int SPtoFPdelta = genSPtoFPdelta(); + // Restore sp from fp + if (emitter::isValidSimm12(SPtoFPdelta)) { - callerSPtoFPdelta = (compiler->compCalleeRegsPushed << 3) - 8; + emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -SPtoFPdelta); } else { - genStackPointerAdjustment(calleeSaveSPOffset, REG_RA, nullptr, /* reportUnwindData */ true); + regNumber tempReg = rsGetRsvdReg(); + emit->emitLoadImmediate(EA_PTRSIZE, tempReg, SPtoFPdelta); + emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, tempReg); } - remainingSPSize = totalFrameSize - calleeSaveSPOffset; - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize - calleeSaveSPOffset; } - else + if ((localFrameSize + (compiler->compCalleeRegsPushed << 3)) > 2040) { - if (compiler->compLocallocUsed) - { - callerSPtoFPdelta = (compiler->compCalleeRegsPushed << 3) - 8 + compiler->lvaOutgoingArgSpaceSize; - } - calleeSaveSPOffset = compiler->lvaOutgoingArgSpaceSize; - // remainingSPSize = totalFrameSize; - } - } + remainingSPSize = localFrameSize & -16; + genStackPointerAdjustment(remainingSPSize, REG_RA, nullptr, /* reportUnwindData */ true); - if (compiler->compLocallocUsed) - { - // restore sp form fp: addi sp, -#callerSPtoFPdelta(fp) - emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, -callerSPtoFPdelta); - compiler->unwindSetFrameReg(REG_FPBASE, callerSPtoFPdelta); + remainingSPSize = totalFrameSize - remainingSPSize; + FP_offset = localFrameSize & 0xf; + } } - JITDUMP(" calleeSaveSPOffset=%d, callerSPtoFPdelta=%d\n", calleeSaveSPOffset, callerSPtoFPdelta); - genRestoreCalleeSavedRegistersHelp(regsToRestoreMask, calleeSaveSPOffset, 0); - - // restore ra/fp regs - calleeSaveSPOffset += (compiler->compCalleeRegsPushed - 2) << 3; + JITDUMP(" calleeSaveSPOffset=%d\n", FP_offset + 16); + genRestoreCalleeSavedRegistersHelp(regsToRestoreMask, FP_offset + 16, 0); - emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_RA, REG_SPBASE, calleeSaveSPOffset); - compiler->unwindSaveReg(REG_RA, calleeSaveSPOffset); + emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_RA, REG_SPBASE, FP_offset + 8); + compiler->unwindSaveReg(REG_RA, FP_offset + 8); - emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_FP, REG_SPBASE, calleeSaveSPOffset + 8); - compiler->unwindSaveReg(REG_FP, calleeSaveSPOffset + 8); + emit->emitIns_R_R_I(INS_ld, EA_PTRSIZE, REG_FP, REG_SPBASE, FP_offset); + compiler->unwindSaveReg(REG_FP, FP_offset); if (emitter::isValidUimm11(remainingSPSize)) { @@ -8043,7 +7942,7 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) } compiler->unwindAllocStack(remainingSPSize); - // for OSR we have to adjust SP to remove tier0 frame + // For OSR, we must also adjust the SP to remove the Tier0 frame. if (compiler->opts.IsOSR()) { const int tier0FrameSize = compiler->info.compPatchpointInfo->TotalFrameSize(); @@ -8063,449 +7962,6 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) } } -void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed) -{ - *initRegStillZeroed = false; - assert(!(intRegState.rsCalleeRegArgMaskLiveIn & floatRegState.rsCalleeRegArgMaskLiveIn)); - - regMaskTP regArgMaskLive = intRegState.rsCalleeRegArgMaskLiveIn | floatRegState.rsCalleeRegArgMaskLiveIn; - -#ifdef DEBUG - if (verbose) - { - printf("*************** In genFnPrologCalleeRegArgs() RISCV64:0x%llx.\n", regArgMaskLive); - } -#endif - - // We should be generating the prolog block when we are called - assert(compiler->compGeneratingProlog); - - // We expect to have some registers of the type we are doing, that are LiveIn, otherwise we don't need to be called. - noway_assert(regArgMaskLive != 0); - - unsigned varNum; - unsigned regArgNum = 0; - // Process any rearrangements including circular dependencies. - regNumber regArg[MAX_REG_ARG + MAX_FLOAT_REG_ARG]; - regNumber regArgInit[MAX_REG_ARG + MAX_FLOAT_REG_ARG]; - emitAttr regArgAttr[MAX_REG_ARG + MAX_FLOAT_REG_ARG]; - - for (int i = 0; i < MAX_REG_ARG + MAX_FLOAT_REG_ARG; i++) - { - regArg[i] = REG_NA; - -#ifdef DEBUG - regArgInit[i] = REG_NA; - regArgAttr[i] = EA_UNKNOWN; -#endif - } - - for (varNum = 0; varNum < compiler->lvaCount; ++varNum) - { - LclVarDsc* varDsc = compiler->lvaTable + varNum; - - // Is this variable a register arg? - if (!varDsc->lvIsParam) - { - continue; - } - - if (!varDsc->lvIsRegArg) - { - continue; - } - - if (varDsc->lvIsInReg()) - { - assert(genIsValidIntReg(varDsc->GetArgReg()) || genIsValidFloatReg(varDsc->GetArgReg())); - assert(!(genIsValidIntReg(varDsc->GetOtherArgReg()) || genIsValidFloatReg(varDsc->GetOtherArgReg()))); - if (varDsc->GetArgInitReg() != varDsc->GetArgReg()) - { - if (genIsValidIntReg(varDsc->GetArgInitReg())) - { - if (varDsc->GetArgInitReg() > REG_ARG_LAST) - { - bool isSkip; - instruction ins; - emitAttr size; - if (genIsValidIntReg(varDsc->GetArgReg())) - { - ins = INS_mov; - if (varDsc->TypeGet() == TYP_INT) - { - size = EA_4BYTE; - isSkip = false; - } - else - { - size = EA_PTRSIZE; - isSkip = true; - } - } - else - { - ins = INS_fmv_x_d; - size = EA_PTRSIZE; - isSkip = true; - } - GetEmitter()->emitIns_Mov(ins, size, varDsc->GetArgInitReg(), varDsc->GetArgReg(), isSkip); - regArgMaskLive &= ~genRegMask(varDsc->GetArgReg()); - } - else - { - if (genIsValidIntReg(varDsc->GetArgReg())) - { - assert(isValidIntArgReg(varDsc->GetArgReg(), compiler->info.compCallConv)); - regArg[varDsc->GetArgReg() - REG_ARG_FIRST] = varDsc->GetArgReg(); - regArgInit[varDsc->GetArgReg() - REG_ARG_FIRST] = varDsc->GetArgInitReg(); - regArgAttr[varDsc->GetArgReg() - REG_ARG_FIRST] = - varDsc->TypeGet() == TYP_INT ? EA_4BYTE : EA_PTRSIZE; - } - else - { - assert(isValidFloatArgReg(varDsc->GetArgReg())); - regArg[varDsc->GetArgReg() - REG_ARG_FP_FIRST + MAX_REG_ARG] = varDsc->GetArgReg(); - regArgInit[varDsc->GetArgReg() - REG_ARG_FP_FIRST + MAX_REG_ARG] = varDsc->GetArgInitReg(); - regArgAttr[varDsc->GetArgReg() - REG_ARG_FP_FIRST + MAX_REG_ARG] = - varDsc->TypeGet() == TYP_FLOAT ? EA_4BYTE : EA_PTRSIZE; - } - regArgNum++; - } - } - else - { - assert(genIsValidFloatReg(varDsc->GetArgInitReg())); - if (genIsValidIntReg(varDsc->GetArgReg())) - { - emitAttr size = (varDsc->TypeGet() == TYP_FLOAT) ? EA_4BYTE : EA_PTRSIZE; - GetEmitter()->emitIns_Mov(size, varDsc->GetArgInitReg(), varDsc->GetArgReg(), false); - regArgMaskLive &= ~genRegMask(varDsc->GetArgReg()); - } - else if (varDsc->GetArgInitReg() > REG_ARG_FP_LAST) - { - GetEmitter()->emitIns_Mov(INS_fsgnj_d, EA_PTRSIZE, varDsc->GetArgInitReg(), varDsc->GetArgReg(), - true); - regArgMaskLive &= ~genRegMask(varDsc->GetArgReg()); - } - else - { - assert(isValidFloatArgReg(varDsc->GetArgReg())); - regArg[varDsc->GetArgReg() - REG_ARG_FP_FIRST + MAX_REG_ARG] = varDsc->GetArgReg(); - regArgInit[varDsc->GetArgReg() - REG_ARG_FP_FIRST + MAX_REG_ARG] = varDsc->GetArgInitReg(); - regArgAttr[varDsc->GetArgReg() - REG_ARG_FP_FIRST + MAX_REG_ARG] = - varDsc->TypeGet() == TYP_FLOAT ? EA_4BYTE : EA_PTRSIZE; - regArgNum++; - } - } - } - else - { - // TODO-RISCV64: should delete this by optimization "struct {long a; int32_t b;};" - // liking AMD64_ABI within morph. - if (genIsValidIntReg(varDsc->GetArgReg()) && (varDsc->TypeGet() == TYP_INT)) - { - GetEmitter()->emitIns_Mov(INS_mov, EA_4BYTE, varDsc->GetArgInitReg(), varDsc->GetArgReg(), false); - } - regArgMaskLive &= ~genRegMask(varDsc->GetArgReg()); - } -#ifdef USING_SCOPE_INFO - psiMoveToReg(varNum); -#endif // USING_SCOPE_INFO - if (!varDsc->lvLiveInOutOfHndlr) - { - continue; - } - } - - // When we have a promoted struct we have two possible LclVars that can represent the incoming argument - // in the regArgTab[], either the original TYP_STRUCT argument or the introduced lvStructField. - // We will use the lvStructField if we have a TYPE_INDEPENDENT promoted struct field otherwise - // use the original TYP_STRUCT argument. - // - if (varDsc->lvPromoted || varDsc->lvIsStructField) - { - LclVarDsc* parentVarDsc = varDsc; - if (varDsc->lvIsStructField) - { - assert(!varDsc->lvPromoted); - parentVarDsc = &compiler->lvaTable[varDsc->lvParentLcl]; - } - - Compiler::lvaPromotionType promotionType = compiler->lvaGetPromotionType(parentVarDsc); - - if (promotionType == Compiler::PROMOTION_TYPE_INDEPENDENT) - { - // For register arguments that are independent promoted structs we put the promoted field varNum - // in the regArgTab[] - if (varDsc->lvPromoted) - { - continue; - } - } - else - { - // For register arguments that are not independent promoted structs we put the parent struct varNum - // in the regArgTab[] - if (varDsc->lvIsStructField) - { - continue; - } - } - } - - var_types storeType = TYP_UNDEF; - int slotSize = TARGET_POINTER_SIZE; - - if (varTypeIsStruct(varDsc)) - { - if (emitter::isFloatReg(varDsc->GetArgReg())) - { - storeType = varDsc->lvIs4Field1 ? TYP_FLOAT : TYP_DOUBLE; - } - else - { - assert(emitter::isGeneralRegister(varDsc->GetArgReg())); - if (varDsc->lvIs4Field1) - { - storeType = TYP_INT; - } - else - { - storeType = varDsc->GetLayout()->GetGCPtrType(0); - } - } - slotSize = (int)EA_SIZE(emitActualTypeSize(storeType)); - -#if FEATURE_MULTIREG_ARGS - // Must be <= MAX_PASS_MULTIREG_BYTES or else it wouldn't be passed in registers - noway_assert(varDsc->lvSize() <= MAX_PASS_MULTIREG_BYTES); -#endif - } - else // Not a struct type - { - storeType = compiler->mangleVarArgsType(genActualType(varDsc->TypeGet())); - if (emitter::isFloatReg(varDsc->GetArgReg()) != varTypeIsFloating(storeType)) - { - assert(varTypeIsFloating(storeType)); - storeType = storeType == TYP_DOUBLE ? TYP_I_IMPL : TYP_INT; - } - } - emitAttr size = emitActualTypeSize(storeType); - - regNumber srcRegNum = varDsc->GetArgReg(); - - // Stack argument - if the ref count is 0 don't care about it - if (!varDsc->lvOnFrame) - { - noway_assert(varDsc->lvRefCnt() == 0); - regArgMaskLive &= ~genRegMask(varDsc->GetArgReg()); - if (varDsc->GetOtherArgReg() < REG_STK) - { - regArgMaskLive &= ~genRegMask(varDsc->GetOtherArgReg()); - } - } - else - { - assert(srcRegNum != varDsc->GetOtherArgReg()); - - regNumber tmpReg = REG_NA; - - bool FPbased; - int baseOffset = compiler->lvaFrameAddress(varNum, &FPbased); - - // First store the `varDsc->GetArgReg()` on stack. - if (emitter::isValidSimm12(baseOffset)) - { - GetEmitter()->emitIns_S_R(ins_Store(storeType), size, srcRegNum, varNum, 0); - } - else - { - assert(tmpReg == REG_NA); - - tmpReg = REG_RA; - // Prepare tmpReg to possible future use - GetEmitter()->emitLoadImmediate(EA_PTRSIZE, tmpReg, baseOffset); - GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, tmpReg, tmpReg, FPbased ? REG_FPBASE : REG_SPBASE); - GetEmitter()->emitIns_S_R_R(ins_Store(storeType), size, srcRegNum, tmpReg, varNum, 0); - } - - regArgMaskLive &= ~genRegMask(srcRegNum); - - // Then check if varDsc is a struct arg - if (varTypeIsStruct(varDsc)) - { - if (emitter::isFloatReg(varDsc->GetOtherArgReg())) - { - srcRegNum = varDsc->GetOtherArgReg(); - storeType = varDsc->lvIs4Field2 ? TYP_FLOAT : TYP_DOUBLE; - size = EA_SIZE(emitActualTypeSize(storeType)); - - slotSize = slotSize < (int)size ? (int)size : slotSize; - } - else if (emitter::isGeneralRegister(varDsc->GetOtherArgReg())) - { - if (varDsc->lvIs4Field2) - { - storeType = TYP_INT; - } - else - { - storeType = varDsc->GetLayout()->GetGCPtrType(1); - } - - srcRegNum = varDsc->GetOtherArgReg(); - size = emitActualTypeSize(storeType); - - slotSize = slotSize < (int)EA_SIZE(size) ? (int)EA_SIZE(size) : slotSize; - } - baseOffset += slotSize; - - // if the struct passed by two register, then store the second register `varDsc->GetOtherArgReg()`. - if (srcRegNum == varDsc->GetOtherArgReg()) - { - GetEmitter()->emitIns_S_R_R(ins_Store(storeType), size, srcRegNum, tmpReg, varNum, slotSize); - regArgMaskLive &= ~genRegMask(srcRegNum); // maybe do this later is better! - } - else if (varDsc->lvIsSplit) - { - // the struct is a split struct. - assert(varDsc->GetArgReg() == REG_ARG_LAST && varDsc->GetOtherArgReg() == REG_STK); - - // For the RISCV64's ABI, the split struct arg will be passed via `A7` and a stack slot on caller. - // But if the `A7` is stored on stack on the callee side, the whole split struct should be - // stored continuous on the stack on the callee side. - // So, after we save `A7` on the stack in prolog, it has to copy the stack slot of the split struct - // which was passed by the caller. Here we load the stack slot to `REG_SCRATCH`, and save it - // on the stack following the `A7` in prolog. - if (emitter::isValidSimm12(genTotalFrameSize())) - { - GetEmitter()->emitIns_R_R_I(INS_ld, size, REG_SCRATCH, REG_SPBASE, genTotalFrameSize()); - } - else - { - assert(!EA_IS_RELOC(size)); - GetEmitter()->emitLoadImmediate(size, REG_SCRATCH, genTotalFrameSize()); - GetEmitter()->emitIns_R_R_R(INS_add, size, REG_SCRATCH, REG_SCRATCH, REG_SPBASE); - GetEmitter()->emitIns_R_R_I(INS_ld, size, REG_SCRATCH, REG_SCRATCH, 0); - } - - GetEmitter()->emitIns_S_R_R(ins_Store(storeType), size, REG_SCRATCH, tmpReg, varNum, slotSize); - } - } - -#ifdef USING_SCOPE_INFO - { - psiMoveToStack(varNum); - } -#endif // USING_SCOPE_INFO - } - } - - if (regArgNum > 0) - { - for (int i = MAX_REG_ARG + MAX_FLOAT_REG_ARG - 1; i >= 0; i--) - { - if (regArg[i] != REG_NA && !isValidIntArgReg(regArgInit[i], compiler->info.compCallConv) && - !isValidFloatArgReg(regArgInit[i])) - { - assert(regArg[i] != regArgInit[i]); - assert(isValidIntArgReg(regArg[i], compiler->info.compCallConv) || isValidFloatArgReg(regArg[i])); - - GetEmitter()->emitIns_Mov(regArgAttr[i], regArgInit[i], regArg[i], false); - - regArgMaskLive &= ~genRegMask(regArg[i]); - regArg[i] = REG_NA; - regArgNum -= 1; - } - } - } - - if (regArgNum > 0) - { - for (int i = MAX_REG_ARG + MAX_FLOAT_REG_ARG - 1; i >= 0; i--) - { - if (regArg[i] != REG_NA) - { - assert(regArg[i] != regArgInit[i]); - - // regArg indexes list - unsigned indexList[MAX_REG_ARG + MAX_FLOAT_REG_ARG]; - int count = 0; // Number of nodes in list - bool loop = false; // List has a loop - - for (unsigned cur = i; regArg[cur] != REG_NA; count++) - { - if (cur == i && count > 0) - { - loop = true; - break; - } - - indexList[count] = cur; - - for (int count2 = 0; count2 < count; count2++) - { - // The list could not have backlinks except last to first case which handled above. - assert(cur != indexList[count2] && "Attempt to move several values on same register."); - } - assert(cur < MAX_REG_ARG + MAX_FLOAT_REG_ARG); - assert(isValidIntArgReg(regArg[cur], compiler->info.compCallConv) || - isValidFloatArgReg(regArg[cur])); - - if (isValidIntArgReg(regArgInit[cur], compiler->info.compCallConv)) - { - cur = regArgInit[cur] - REG_ARG_FIRST; - } - else if (isValidFloatArgReg(regArgInit[cur])) - { - cur = regArgInit[cur] - REG_ARG_FP_FIRST + MAX_REG_ARG; - } - else - { - assert(!"Argument register is neither valid float nor valid int argument register"); - } - } - - if (loop) - { - unsigned tmpArg = indexList[count - 1]; - - GetEmitter()->emitIns_Mov(regArgAttr[tmpArg], rsGetRsvdReg(), regArg[tmpArg], false); - count--; // Decrease count to not access last node which regArgInit points to start node i - assert(count > 0); - } - - for (int cur = count - 1; cur >= 0; cur--) - { - unsigned tmpArg = indexList[cur]; - - GetEmitter()->emitIns_Mov(regArgAttr[tmpArg], regArgInit[tmpArg], regArg[tmpArg], false); - - regArgMaskLive &= ~genRegMask(regArg[tmpArg]); - regArg[tmpArg] = REG_NA; - regArgNum--; - assert(regArgNum >= 0); - }; - - if (loop) - { - unsigned tmpArg = indexList[count]; // count was decreased for loop case - - GetEmitter()->emitIns_Mov(regArgAttr[i], regArg[tmpArg], rsGetRsvdReg(), false); - - regArgMaskLive &= ~genRegMask(regArg[tmpArg]); - regArg[tmpArg] = REG_NA; - regArgNum--; - } - assert(regArgNum >= 0); - } - } - } - - assert(regArgNum == 0); - assert(!regArgMaskLive); -} - #ifdef PROFILING_SUPPORTED //----------------------------------------------------------------------------------- // genProfilingEnterCallback: Generate the profiling function enter callback. diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 4901ee9e3aa086..a2a17e735c9038 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -914,7 +914,7 @@ void CodeGen::genCodeForLongUMod(GenTreeOp* node) // xor edx, edx // div divisor->GetRegNum() // mov eax, temp - const regNumber tempReg = node->GetSingleTempReg(); + const regNumber tempReg = internalRegisters.GetSingle(node); inst_Mov(TYP_INT, tempReg, REG_EAX, /* canSkip */ false); inst_Mov(TYP_INT, REG_EAX, REG_EDX, /* canSkip */ false); instGen_Set_Reg_To_Zero(EA_PTRSIZE, REG_EDX); @@ -1761,7 +1761,7 @@ void CodeGen::genCodeForReturnTrap(GenTreeOp* tree) inst_JMP(EJ_je, skipLabel); // emit the call to the EE-helper that stops for GC (or other reasons) - regNumber tmpReg = tree->GetSingleTempReg(RBM_ALLINT); + regNumber tmpReg = internalRegisters.GetSingle(tree, RBM_ALLINT); assert(genIsValidIntReg(tmpReg)); genEmitHelperCall(CORINFO_HELP_STOP_FOR_GC, 0, EA_UNKNOWN, tmpReg); @@ -2334,7 +2334,7 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode) } else { - regNumber tempXmm = lclNode->GetSingleTempReg(); + regNumber tempXmm = internalRegisters.GetSingle(lclNode); assert(tempXmm != targetReg); inst_Mov(TYP_FLOAT, tempXmm, reg1, /* canSkip */ false); GetEmitter()->emitIns_SIMD_R_R_R(INS_punpckldq, size, targetReg, targetReg, tempXmm); @@ -2675,7 +2675,7 @@ void CodeGen::genCodeForMemmove(GenTreeBlk* tree) if ((size >= simdSize) && (simdSize > 0)) { // Number of SIMD regs needed to save the whole src to regs. - unsigned numberOfSimdRegs = tree->AvailableTempRegCount(RBM_ALLFLOAT); + unsigned numberOfSimdRegs = internalRegisters.Count(tree, RBM_ALLFLOAT); // Lowering takes care to only introduce this node such that we will always have enough // temporary SIMD registers to fully load the source and avoid any potential issues with overlap. @@ -2685,7 +2685,7 @@ void CodeGen::genCodeForMemmove(GenTreeBlk* tree) regNumber tempRegs[LinearScan::MaxInternalCount] = {}; for (unsigned i = 0; i < numberOfSimdRegs; i++) { - tempRegs[i] = tree->ExtractTempReg(RBM_ALLFLOAT); + tempRegs[i] = internalRegisters.Extract(tree, RBM_ALLFLOAT); } auto emitSimdLoadStore = [&](bool load) { @@ -2770,15 +2770,15 @@ void CodeGen::genCodeForMemmove(GenTreeBlk* tree) unsigned loadStoreSize = 1 << BitOperations::Log2(size); if (loadStoreSize == size) { - regNumber tmpReg = tree->GetSingleTempReg(RBM_ALLINT); + regNumber tmpReg = internalRegisters.GetSingle(tree, RBM_ALLINT); emitScalarLoadStore(/* load */ true, loadStoreSize, tmpReg, 0); emitScalarLoadStore(/* load */ false, loadStoreSize, tmpReg, 0); } else { - assert(tree->AvailableTempRegCount() == 2); - regNumber tmpReg1 = tree->ExtractTempReg(RBM_ALLINT); - regNumber tmpReg2 = tree->ExtractTempReg(RBM_ALLINT); + assert(internalRegisters.Count(tree) == 2); + regNumber tmpReg1 = internalRegisters.Extract(tree, RBM_ALLINT); + regNumber tmpReg2 = internalRegisters.Extract(tree, RBM_ALLINT); emitScalarLoadStore(/* load */ true, loadStoreSize, tmpReg1, 0); emitScalarLoadStore(/* load */ true, loadStoreSize, tmpReg2, size - loadStoreSize); emitScalarLoadStore(/* load */ false, loadStoreSize, tmpReg1, 0); @@ -2855,12 +2855,12 @@ void CodeGen::genLclHeap(GenTree* tree) // since we don't need any internal registers. if (compiler->info.compInitMem) { - assert(tree->AvailableTempRegCount() == 0); + assert(internalRegisters.Count(tree) == 0); regCnt = targetReg; } else { - regCnt = tree->GetSingleTempReg(); + regCnt = internalRegisters.GetSingle(tree); // Above, we put the size in targetReg. Now, copy it to our new temp register if necessary. inst_Mov(size->TypeGet(), regCnt, targetReg, /* canSkip */ true); @@ -2954,7 +2954,7 @@ void CodeGen::genLclHeap(GenTree* tree) // via BLK explicitly, so just bump the stack pointer. if ((amount >= compiler->eeGetPageSize()) || (TARGET_POINTER_SIZE == 4)) { - regCnt = tree->GetSingleTempReg(); + regCnt = internalRegisters.GetSingle(tree); instGen_Set_Reg_To_Imm(EA_PTRSIZE, regCnt, -(ssize_t)amount); genStackPointerDynamicAdjustmentWithProbe(regCnt); // lastTouchDelta is dynamic, and can be up to a page. So if we have outgoing arg space, @@ -2971,7 +2971,7 @@ void CodeGen::genLclHeap(GenTree* tree) } // We should not have any temp registers at this point. - assert(tree->AvailableTempRegCount() == 0); + assert(internalRegisters.Count(tree) == 0); if (compiler->info.compInitMem) { @@ -3234,7 +3234,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) #ifdef FEATURE_SIMD if (willUseSimdMov) { - regNumber srcXmmReg = node->GetSingleTempReg(RBM_ALLFLOAT); + regNumber srcXmmReg = internalRegisters.GetSingle(node, RBM_ALLFLOAT); unsigned regSize = compiler->roundDownSIMDSize(size); var_types loadType = compiler->getSIMDTypeForSize(regSize); simd_t vecCon; @@ -3392,7 +3392,7 @@ void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode) // Extend liveness of dstReg in case if it gets killed by the store. gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet()); - const regNumber offsetReg = initBlkNode->GetSingleTempReg(); + const regNumber offsetReg = internalRegisters.GetSingle(initBlkNode); instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE); BasicBlock* loop = genCreateTempLabel(); @@ -3531,7 +3531,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) if ((size >= regSize) && (regSize > 0)) { - regNumber tempReg = node->GetSingleTempReg(RBM_ALLFLOAT); + regNumber tempReg = internalRegisters.GetSingle(node, RBM_ALLFLOAT); instruction simdMov = simdUnalignedMovIns(); @@ -3593,7 +3593,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) // Fill the remainder with normal loads/stores if (size > 0) { - regNumber tempReg = node->GetSingleTempReg(RBM_ALLINT); + regNumber tempReg = internalRegisters.GetSingle(node, RBM_ALLINT); #ifdef TARGET_AMD64 unsigned regSize = REGSIZE_BYTES; @@ -3878,11 +3878,11 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) if (loadSize >= XMM_REGSIZE_BYTES) #endif { - xmmTmpReg = putArgNode->GetSingleTempReg(RBM_ALLFLOAT); + xmmTmpReg = internalRegisters.GetSingle(putArgNode, RBM_ALLFLOAT); } if ((loadSize % XMM_REGSIZE_BYTES) != 0) { - intTmpReg = putArgNode->GetSingleTempReg(RBM_ALLINT); + intTmpReg = internalRegisters.GetSingle(putArgNode, RBM_ALLINT); } #ifdef TARGET_X86 @@ -3934,7 +3934,7 @@ void CodeGen::genStructPutArgRepMovs(GenTreePutArgStk* putArgNode) // Make sure we got the arguments of the cpblk operation in the right registers, and that // 'src' is contained as expected. - assert(putArgNode->gtRsvdRegs == (RBM_RDI | RBM_RCX | RBM_RSI)); + assert(internalRegisters.GetAll(putArgNode) == (RBM_RDI | RBM_RCX | RBM_RSI)); assert(src->isContained()); genConsumePutStructArgStk(putArgNode, REG_RDI, REG_RSI, REG_RCX); @@ -4219,7 +4219,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) { // If the destination of the CpObj is on the stack, make sure we allocated // RCX to emit the movsp (alias for movsd or movsq for 32 and 64 bits respectively). - assert((cpObjNode->gtRsvdRegs & RBM_RCX) != 0); + assert((internalRegisters.GetAll(cpObjNode) & RBM_RCX) != 0); GetEmitter()->emitIns_R_I(INS_mov, EA_4BYTE, REG_RCX, slots); instGen(INS_r_movsp); @@ -4269,7 +4269,7 @@ void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode) { // Otherwise, we can save code-size and improve CQ by emitting // rep movsp (alias for movsd/movsq for x86/x64) - assert((cpObjNode->gtRsvdRegs & RBM_RCX) != 0); + assert((internalRegisters.GetAll(cpObjNode) & RBM_RCX) != 0); GetEmitter()->emitIns_R_I(INS_mov, EA_4BYTE, REG_RCX, nonGcSlotCount); instGen(INS_r_movsp); @@ -4300,7 +4300,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) regNumber idxReg = treeNode->AsOp()->gtOp1->GetRegNum(); regNumber baseReg = treeNode->AsOp()->gtOp2->GetRegNum(); - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); // load the ip-relative offset (which is relative to start of fgFirstBB) GetEmitter()->emitIns_R_ARX(INS_mov, EA_4BYTE, baseReg, baseReg, idxReg, 4, 0); @@ -4427,7 +4427,7 @@ void CodeGen::genLockedInstructions(GenTreeOp* node) // Extend liveness of addr gcInfo.gcMarkRegPtrVal(addr->GetRegNum(), addr->TypeGet()); - const regNumber tmpReg = node->GetSingleTempReg(); + const regNumber tmpReg = internalRegisters.GetSingle(node); GetEmitter()->emitIns_R_AR(INS_mov, size, REG_RAX, addr->GetRegNum(), 0); BasicBlock* loop = genCreateTempLabel(); genDefineTempLabel(loop); @@ -5306,7 +5306,7 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node) regNumber tmpReg = REG_NA; #ifdef TARGET_64BIT - tmpReg = node->GetSingleTempReg(); + tmpReg = internalRegisters.GetSingle(node); #endif // Generate the bounds check if necessary. @@ -5356,7 +5356,7 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node) // The VM doesn't allow such large array elements but let's be sure. noway_assert(scale <= INT32_MAX); #else // !TARGET_64BIT - tmpReg = node->GetSingleTempReg(); + tmpReg = internalRegisters.GetSingle(node); #endif // !TARGET_64BIT GetEmitter()->emitIns_R_I(emitter::inst3opImulForReg(tmpReg), EA_PTRSIZE, indexReg, @@ -7239,7 +7239,7 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d // We need to check if the value is not greater than 0xFFFFFFFF but this value // cannot be encoded in an immediate operand. Use a right shift to test if the // upper 32 bits are zero. This requires a temporary register. - const regNumber tempReg = cast->GetSingleTempReg(); + const regNumber tempReg = internalRegisters.GetSingle(cast); assert(tempReg != reg); GetEmitter()->emitIns_Mov(INS_mov, EA_8BYTE, tempReg, reg, /* canSkip */ false); GetEmitter()->emitIns_R_I(INS_shr_N, EA_8BYTE, tempReg, 32); @@ -7255,7 +7255,7 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d case GenIntCastDesc::CHECK_INT_RANGE: { // Emit "if ((long)(int)x != x) goto OVERFLOW" - const regNumber regTmp = cast->GetSingleTempReg(); + const regNumber regTmp = internalRegisters.GetSingle(cast); GetEmitter()->emitIns_Mov(INS_movsxd, EA_8BYTE, regTmp, reg, true); GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, regTmp); genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW); @@ -7666,7 +7666,7 @@ void CodeGen::genCkfinite(GenTree* treeNode) regNumber targetReg = treeNode->GetRegNum(); // Extract exponent into a register. - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); genConsumeReg(op1); @@ -8357,17 +8357,17 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk) unsigned prevFieldOffset = currentOffset; regNumber intTmpReg = REG_NA; regNumber simdTmpReg = REG_NA; - if (putArgStk->AvailableTempRegCount() != 0) + if (internalRegisters.Count(putArgStk) != 0) { - regMaskTP rsvdRegs = putArgStk->gtRsvdRegs; + regMaskTP rsvdRegs = internalRegisters.GetAll(putArgStk); if ((rsvdRegs & RBM_ALLINT) != 0) { - intTmpReg = putArgStk->GetSingleTempReg(RBM_ALLINT); + intTmpReg = internalRegisters.GetSingle(putArgStk, RBM_ALLINT); assert(genIsValidIntReg(intTmpReg)); } if ((rsvdRegs & RBM_ALLFLOAT) != 0) { - simdTmpReg = putArgStk->GetSingleTempReg(RBM_ALLFLOAT); + simdTmpReg = internalRegisters.GetSingle(putArgStk, RBM_ALLFLOAT); assert(genIsValidFloatReg(simdTmpReg)); } assert(genCountBits(rsvdRegs) == (unsigned)((intTmpReg == REG_NA) ? 0 : 1) + ((simdTmpReg == REG_NA) ? 0 : 1)); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index a32867660a01c3..0c812ffd935dbb 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2193,7 +2193,7 @@ const char* Compiler::compRegVarName(regNumber reg, bool displayVar, bool isFloa // consecutive calls before printing static int index = 0; // for circular index into the name array - index = (index + 1) % 2; // circular reuse of index + index ^= 1; // circular reuse of index sprintf_s(nameVarReg[index], NAME_VAR_REG_BUFFER_LEN, "%s'%s'", getRegName(reg), VarNameToStr(varName)); return nameVarReg[index]; @@ -2791,11 +2791,13 @@ void Compiler::compInitOptions(JitFlags* jitFlags) fgPgoHaveWeights = false; fgPgoSynthesized = false; fgPgoConsistent = false; + fgPgoDynamic = false; if (jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT)) { - fgPgoQueryResult = info.compCompHnd->getPgoInstrumentationResults(info.compMethodHnd, &fgPgoSchema, - &fgPgoSchemaCount, &fgPgoData, &fgPgoSource); + fgPgoQueryResult = + info.compCompHnd->getPgoInstrumentationResults(info.compMethodHnd, &fgPgoSchema, &fgPgoSchemaCount, + &fgPgoData, &fgPgoSource, &fgPgoDynamic); // a failed result that also has a non-NULL fgPgoSchema // indicates that the ILSize for the method no longer matches @@ -2818,6 +2820,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags) fgPgoData = nullptr; fgPgoSchema = nullptr; fgPgoDisabled = true; + fgPgoDynamic = false; } #ifdef DEBUG // Optionally, enable use of profile data for only some methods. @@ -4085,7 +4088,18 @@ void Compiler::compSetOptimizationLevel() { info.compCompHnd->setMethodAttribs(info.compMethodHnd, CORINFO_FLG_SWITCHED_TO_MIN_OPT); opts.jitFlags->Clear(JitFlags::JIT_FLAG_TIER1); + opts.jitFlags->Clear(JitFlags::JIT_FLAG_BBOPT); compSwitchedToMinOpts = true; + + // We may have read PGO data. Clear it out because we won't be using it. + // + fgPgoFailReason = "method switched to min-opts"; + fgPgoQueryResult = E_FAIL; + fgPgoHaveWeights = false; + fgPgoData = nullptr; + fgPgoSchema = nullptr; + fgPgoDisabled = true; + fgPgoDynamic = false; } #ifdef DEBUG @@ -4629,11 +4643,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl // DoPhase(this, PHASE_IMPORTATION, &Compiler::fgImport); - // Drop back to just checking profile likelihoods. - // - activePhaseChecks &= ~PhaseChecks::CHECK_PROFILE; - activePhaseChecks |= PhaseChecks::CHECK_LIKELIHOODS; - // If this is a failed inline attempt, we're done. // if (compIsForInlining() && compInlineResult->IsFailure()) @@ -4704,6 +4713,11 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl // Record "start" values for post-inlining cycles and elapsed time. RecordStateAtEndOfInlining(); + // Drop back to just checking profile likelihoods. + // + activePhaseChecks &= ~PhaseChecks::CHECK_PROFILE; + activePhaseChecks |= PhaseChecks::CHECK_LIKELIHOODS; + // Transform each GT_ALLOCOBJ node into either an allocation helper call or // local variable allocation on the stack. ObjectAllocator objectAllocator(this); // PHASE_ALLOCATE_OBJECTS @@ -8053,6 +8067,7 @@ if (!inlineInfo && compileFlags->Set(JitFlags::JIT_FLAG_MIN_OPT); compileFlags->Clear(JitFlags::JIT_FLAG_SIZE_OPT); compileFlags->Clear(JitFlags::JIT_FLAG_SPEED_OPT); + compileFlags->Clear(JitFlags::JIT_FLAG_BBOPT); goto START; } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 819c20629de134..47ba6143c54666 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1594,7 +1594,7 @@ enum class ProfileChecks : unsigned int { CHECK_NONE = 0, CHECK_HASLIKELIHOOD = 1 << 0, // check all FlowEdges for hasLikelihood - CHECK_LIKELIHOODSUM = 1 << 1, // check block succesor likelihoods sum to 1 + CHECK_LIKELIHOODSUM = 1 << 1, // check block succesor likelihoods sum to 1 CHECK_LIKELY = 1 << 2, // fully check likelihood based weights RAISE_ASSERT = 1 << 3, // assert on check failure CHECK_ALL_BLOCKS = 1 << 4, // check blocks even if bbHasProfileWeight is false @@ -2793,6 +2793,9 @@ class Compiler EHblkDsc* ehIsBlockHndLast(BasicBlock* block); bool ehIsBlockEHLast(BasicBlock* block); + template + void ehUpdateTryLasts(GetTryLast getTryLast, SetTryLast setTryLast); + bool ehBlockHasExnFlowDsc(BasicBlock* block); // Return the region index of the most nested EH region this block is in. @@ -3188,13 +3191,17 @@ class Compiler CorInfoType simdBaseJitType, unsigned simdSize); -#if defined(TARGET_XARCH) - GenTree* gtNewSimdCvtNode(var_types type, - GenTree* op1, - CorInfoType simdTargetBaseJitType, - CorInfoType simdSourceBaseJitType, - unsigned simdSize); -#endif //TARGET_XARCH + GenTree* gtNewSimdCvtNode(var_types type, + GenTree* op1, + CorInfoType simdTargetBaseJitType, + CorInfoType simdSourceBaseJitType, + unsigned simdSize); + + GenTree* gtNewSimdCvtNativeNode(var_types type, + GenTree* op1, + CorInfoType simdTargetBaseJitType, + CorInfoType simdSourceBaseJitType, + unsigned simdSize); GenTree* gtNewSimdCreateBroadcastNode( var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize); @@ -3473,6 +3480,7 @@ class Compiler #if defined(TARGET_ARM64) GenTree* gtNewSimdConvertVectorToMaskNode(var_types type, GenTree* node, CorInfoType simdBaseJitType, unsigned simdSize); GenTree* gtNewSimdConvertMaskToVectorNode(GenTreeHWIntrinsic* node, var_types type); + GenTree* gtNewSimdAllTrueMaskNode(CorInfoType simdBaseJitType, unsigned simdSize); #endif //------------------------------------------------------------------------ @@ -4520,6 +4528,11 @@ class Compiler CORINFO_THIS_TRANSFORM constraintCallThisTransform, NamedIntrinsic* pIntrinsicName, bool* isSpecialIntrinsic = nullptr); + GenTree* impEstimateIntrinsic(CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* sig, + CorInfoType callJitType, + NamedIntrinsic intrinsicName, + bool tailCall); GenTree* impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, @@ -5166,7 +5179,6 @@ class Compiler bool fgModified; // True if the flow graph has been modified recently bool fgPredsComputed; // Have we computed the bbPreds list bool fgOptimizedFinally; // Did we optimize any try-finallys? - bool fgCanonicalizedFirstBB; // TODO-Quirk: did we end up canonicalizing first BB? bool fgHasSwitch; // any BBJ_SWITCH jumps? @@ -5277,6 +5289,7 @@ class Compiler // The number of separate return points in the method. unsigned fgReturnCount; + unsigned fgThrowCount; PhaseStatus fgAddInternal(); @@ -5929,7 +5942,7 @@ class Compiler void fgReplaceEhfSuccessor(BasicBlock* block, BasicBlock* oldSucc, BasicBlock* newSucc); void fgRemoveEhfSuccessor(BasicBlock* block, const unsigned succIndex); - + void fgRemoveEhfSuccessor(FlowEdge* succEdge); void fgReplaceJumpTarget(BasicBlock* block, BasicBlock* oldTarget, BasicBlock* newTarget); @@ -6050,6 +6063,8 @@ class Compiler bool fgComputeCalledCount(weight_t returnWeight); bool fgReorderBlocks(bool useProfile); + void fgDoReversePostOrderLayout(); + void fgMoveColdBlocks(); bool fgFuncletsAreCold(); @@ -6070,9 +6085,10 @@ class Compiler PhaseStatus fgSetBlockOrder(); bool fgHasCycleWithoutGCSafePoint(); - template + template unsigned fgRunDfs(VisitPreorder assignPreorder, VisitPostorder assignPostorder, VisitEdge visitEdge); + template FlowGraphDfsTree* fgComputeDfs(); void fgInvalidateDfsTree(); @@ -6218,7 +6234,7 @@ class Compiler void fgLinkBasicBlocks(); - unsigned fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget); + void fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget); void fgCheckBasicBlockControlFlow(); @@ -6281,6 +6297,7 @@ class Compiler unsigned fgPgoInlineeNoPgoSingleBlock; bool fgPgoHaveWeights; bool fgPgoSynthesized; + bool fgPgoDynamic; bool fgPgoConsistent; #ifdef DEBUG diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 022a92bd740a3f..d8844c2e35afb8 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -623,12 +623,13 @@ BasicBlockVisit BasicBlock::VisitEHSuccs(Compiler* comp, TFunc func) // Arguments: // comp - Compiler instance // func - Callback +// useProfile - If true, determines the order of successors visited using profile data // // Returns: // Whether or not the visiting was aborted. // template -BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func) +BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func, const bool useProfile /* = false */) { switch (bbKind) { @@ -662,10 +663,22 @@ BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func) return VisitEHSuccs(comp, func); case BBJ_COND: - RETURN_ON_ABORT(func(GetFalseTarget())); - - if (!TrueEdgeIs(GetFalseEdge())) + if (TrueEdgeIs(GetFalseEdge())) { + RETURN_ON_ABORT(func(GetFalseTarget())); + } + else if (useProfile && (GetTrueEdge()->getLikelihood() < GetFalseEdge()->getLikelihood())) + { + // When building an RPO-based block layout, we want to visit the unlikely successor first + // so that in the DFS computation, the likely successor will be processed right before this block, + // meaning the RPO-based layout will enable fall-through into the likely successor. + // + RETURN_ON_ABORT(func(GetTrueTarget())); + RETURN_ON_ABORT(func(GetFalseTarget())); + } + else + { + RETURN_ON_ABORT(func(GetFalseTarget())); RETURN_ON_ABORT(func(GetTrueTarget())); } @@ -696,8 +709,8 @@ BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func) // VisitRegularSuccs: Visit regular successors of this block. // // Arguments: -// comp - Compiler instance -// func - Callback +// comp - Compiler instance +// func - Callback // // Returns: // Whether or not the visiting was aborted. @@ -4745,6 +4758,7 @@ inline bool Compiler::compCanHavePatchpoints(const char** reason) // VisitPreorder - Functor type that takes a BasicBlock* and its preorder number // VisitPostorder - Functor type that takes a BasicBlock* and its postorder number // VisitEdge - Functor type that takes two BasicBlock*. +// useProfile - If true, determines order of successors visited using profile data // // Parameters: // visitPreorder - Functor to visit block in its preorder @@ -4755,7 +4769,7 @@ inline bool Compiler::compCanHavePatchpoints(const char** reason) // Returns: // Number of blocks visited. // -template +template unsigned Compiler::fgRunDfs(VisitPreorder visitPreorder, VisitPostorder visitPostorder, VisitEdge visitEdge) { BitVecTraits traits(fgBBNumMax + 1, this); @@ -4768,7 +4782,7 @@ unsigned Compiler::fgRunDfs(VisitPreorder visitPreorder, VisitPostorder visitPos auto dfsFrom = [&](BasicBlock* firstBB) { BitVecOps::AddElemD(&traits, visited, firstBB->bbNum); - blocks.Emplace(this, firstBB); + blocks.Emplace(this, firstBB, useProfile); visitPreorder(firstBB, preOrderIndex++); while (!blocks.Empty()) @@ -4780,7 +4794,7 @@ unsigned Compiler::fgRunDfs(VisitPreorder visitPreorder, VisitPostorder visitPos { if (BitVecOps::TryAddElemD(&traits, visited, succ->bbNum)) { - blocks.Emplace(this, succ); + blocks.Emplace(this, succ, useProfile); visitPreorder(succ, preOrderIndex++); } diff --git a/src/coreclr/jit/copyprop.cpp b/src/coreclr/jit/copyprop.cpp index bb645b26bb4902..11bce9e358e3d3 100644 --- a/src/coreclr/jit/copyprop.cpp +++ b/src/coreclr/jit/copyprop.cpp @@ -230,18 +230,16 @@ bool Compiler::optCopyProp( continue; } - if (tree->OperIs(GT_LCL_VAR)) + var_types newLclType = newLclVarDsc->TypeGet(); + if (!newLclVarDsc->lvNormalizeOnLoad()) { - var_types newLclType = newLclVarDsc->TypeGet(); - if (!newLclVarDsc->lvNormalizeOnLoad()) - { - newLclType = genActualType(newLclType); - } + newLclType = genActualType(newLclType); + } - if (newLclType != tree->TypeGet()) - { - continue; - } + var_types oldLclType = tree->OperIs(GT_LCL_VAR) ? tree->TypeGet() : varDsc->TypeGet(); + if (newLclType != oldLclType) + { + continue; } #ifdef DEBUG diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 40a729dd70fee2..4fb37df5149111 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -4020,6 +4020,8 @@ emitAttr emitter::emitGetBaseMemOpSize(instrDesc* id) const case INS_subss: case INS_ucomiss: case INS_vbroadcastss: + case INS_vcvttss2usi32: + case INS_vcvttss2usi64: case INS_vfmadd132ss: case INS_vfmadd213ss: case INS_vfmadd231ss: @@ -4067,6 +4069,8 @@ emitAttr emitter::emitGetBaseMemOpSize(instrDesc* id) const case INS_subsd: case INS_ucomisd: case INS_vbroadcastsd: + case INS_vcvttsd2usi32: + case INS_vcvttsd2usi64: case INS_vfmadd132sd: case INS_vfmadd213sd: case INS_vfmadd231sd: diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 81331547b4a924..65a6e098b2976a 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -7869,15 +7869,15 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR var_types type = indir->AsStoreInd()->Data()->TypeGet(); if (type == TYP_FLOAT) { - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); emitIns_Mov(INS_vmov_f2i, EA_4BYTE, tmpReg, dataReg, /* canSkip */ false); emitInsLoadStoreOp(INS_str, EA_4BYTE, tmpReg, indir, 0); return; } else if (type == TYP_DOUBLE) { - regNumber tmpReg1 = indir->ExtractTempReg(); - regNumber tmpReg2 = indir->GetSingleTempReg(); + regNumber tmpReg1 = codeGen->internalRegisters.Extract(indir); + regNumber tmpReg2 = codeGen->internalRegisters.GetSingle(indir); emitIns_R_R_R(INS_vmov_d2i, EA_8BYTE, tmpReg1, tmpReg2, dataReg); emitInsLoadStoreOp(INS_str, EA_4BYTE, tmpReg1, indir, 0); emitInsLoadStoreOp(INS_str, EA_4BYTE, tmpReg2, indir, 4); @@ -7889,15 +7889,15 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR var_types type = indir->TypeGet(); if (type == TYP_FLOAT) { - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); emitInsLoadStoreOp(INS_ldr, EA_4BYTE, tmpReg, indir, 0); emitIns_Mov(INS_vmov_i2f, EA_4BYTE, dataReg, tmpReg, /* canSkip */ false); return; } else if (type == TYP_DOUBLE) { - regNumber tmpReg1 = indir->ExtractTempReg(); - regNumber tmpReg2 = indir->GetSingleTempReg(); + regNumber tmpReg1 = codeGen->internalRegisters.Extract(indir); + regNumber tmpReg2 = codeGen->internalRegisters.GetSingle(indir); emitInsLoadStoreOp(INS_ldr, EA_4BYTE, tmpReg1, indir, 0); emitInsLoadStoreOp(INS_ldr, EA_4BYTE, tmpReg2, indir, 4); emitIns_R_R_R(INS_vmov_i2d, EA_8BYTE, dataReg, tmpReg1, tmpReg2); @@ -7940,7 +7940,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR if (offset != 0) { - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); // If the LEA produces a GCREF or BYREF, we need to be careful to mark any temp register // computed with the base register as a BYREF. @@ -8023,7 +8023,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR else { // We require a tmpReg to hold the offset - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); // First load/store tmpReg with the large offset constant codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset); @@ -8175,7 +8175,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, { if (isMulOverflow) { - regNumber extraReg = dst->GetSingleTempReg(); + regNumber extraReg = codeGen->internalRegisters.GetSingle(dst); assert(extraReg != dst->GetRegNum()); if ((dst->gtFlags & GTF_UNSIGNED) != 0) diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 181b9706e41611..3c988633e798b9 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -14243,7 +14243,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR if (offset != 0) { - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); emitAttr addType = varTypeIsGC(memBase) ? EA_BYREF : EA_PTRSIZE; @@ -14350,7 +14350,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR else { // We require a tmpReg to hold the offset - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); // First load/store tmpReg with the large offset constant codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset); @@ -14490,7 +14490,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, { if (isMulOverflow) { - regNumber extraReg = dst->GetSingleTempReg(); + regNumber extraReg = codeGen->internalRegisters.GetSingle(dst); assert(extraReg != dst->GetRegNum()); if ((dst->gtFlags & GTF_UNSIGNED) != 0) @@ -16996,7 +16996,7 @@ void emitter::emitStoreSimd12ToLclOffset(unsigned varNum, unsigned offset, regNu emitIns_S_R(INS_str, EA_8BYTE, dataReg, varNum, offset); // Extract upper 4-bytes from data - regNumber tmpReg = tmpRegProvider->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(tmpRegProvider); emitIns_R_R_I(INS_mov, EA_4BYTE, tmpReg, dataReg, 2); // 4-byte write diff --git a/src/coreclr/jit/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp index 1b90b26ba799af..0c8485a459b5a8 100644 --- a/src/coreclr/jit/emitarm64sve.cpp +++ b/src/coreclr/jit/emitarm64sve.cpp @@ -347,7 +347,7 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) const static insFormat formatEncode4J[4] = {IF_SVE_BV_2A, IF_SVE_BV_2A_A, IF_SVE_CP_3A, IF_SVE_CQ_3A}; const static insFormat formatEncode4K[4] = {IF_SVE_IF_4A, IF_SVE_IF_4A_A, IF_SVE_IM_3A, IF_SVE_IN_4A}; const static insFormat formatEncode4L[4] = {IF_SVE_IZ_4A, IF_SVE_IZ_4A_A, IF_SVE_JB_4A, IF_SVE_JM_3A}; - const static insFormat formatEncode3A[3] = {IF_SVE_AB_3A, IF_SVE_AT_3A, IF_SVE_EC_1A}; + const static insFormat formatEncode3A[3] = {IF_SVE_AA_3A, IF_SVE_AT_3A, IF_SVE_EC_1A}; const static insFormat formatEncode3B[3] = {IF_SVE_BH_3A, IF_SVE_BH_3B, IF_SVE_BH_3B_A}; const static insFormat formatEncode3C[3] = {IF_SVE_BW_2A, IF_SVE_CB_2A, IF_SVE_EB_1A}; const static insFormat formatEncode3D[3] = {IF_SVE_BR_3A, IF_SVE_BR_3B, IF_SVE_CI_3A}; @@ -371,7 +371,7 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) const static insFormat formatEncode3V[3] = {IF_SVE_JA_4A, IF_SVE_JB_4A, IF_SVE_JM_3A}; const static insFormat formatEncode2AA[2] = {IF_SVE_ID_2A, IF_SVE_IE_2A}; const static insFormat formatEncode2AB[2] = {IF_SVE_JG_2A, IF_SVE_JH_2A}; - const static insFormat formatEncode2AC[2] = {IF_SVE_AD_3A, IF_SVE_ED_1A}; + const static insFormat formatEncode2AC[2] = {IF_SVE_AA_3A, IF_SVE_ED_1A}; const static insFormat formatEncode2AD[2] = {IF_SVE_AB_3B, IF_SVE_AT_3B}; const static insFormat formatEncode2AE[2] = {IF_SVE_CG_2A, IF_SVE_CJ_2A}; const static insFormat formatEncode2AF[2] = {IF_SVE_AE_3A, IF_SVE_BD_3A}; @@ -387,7 +387,7 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) const static insFormat formatEncode2AP[2] = {IF_SVE_GY_3B, IF_SVE_HA_3A}; const static insFormat formatEncode2AQ[2] = {IF_SVE_GO_3A, IF_SVE_HC_3A}; const static insFormat formatEncode2AR[2] = {IF_SVE_AP_3A, IF_SVE_CZ_4A}; - const static insFormat formatEncode2AT[2] = {IF_SVE_AB_3A, IF_SVE_EC_1A}; + const static insFormat formatEncode2AT[2] = {IF_SVE_AA_3A, IF_SVE_EC_1A}; const static insFormat formatEncode2AU[2] = {IF_SVE_AH_3A, IF_SVE_BI_2A}; const static insFormat formatEncode2AV[2] = {IF_SVE_BM_1A, IF_SVE_BN_1A}; const static insFormat formatEncode2AW[2] = {IF_SVE_BO_1A, IF_SVE_BP_1A}; @@ -2185,7 +2185,7 @@ void emitter::emitInsSve_R_R(instruction ins, case INS_sve_uunpkhi: case INS_sve_uunpklo: assert(insScalableOptsNone(sopt)); - assert(insOptsScalableAtLeastHalf(opt)); + assert(insOptsScalableWide(opt)); assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); assert(isScalableVectorSize(size)); @@ -2919,7 +2919,10 @@ void emitter::emitInsSve_R_R_R(instruction ins, if (sopt == INS_SCALABLE_OPTS_UNPREDICATED) { - assert(opt == INS_OPTS_SCALABLE_D); + // The instruction only has a .D variant. However, this doesn't matter as + // it operates on bits not lanes. Effectively this means all standard opt + // sizes are supported. + assert(insOptsScalableStandard(opt)); assert(isVectorRegister(reg2)); // nnnnn fmt = IF_SVE_AU_3A; } @@ -2947,7 +2950,7 @@ void emitter::emitInsSve_R_R_R(instruction ins, { assert(isLowPredicateRegister(reg2)); assert(insScalableOptsNone(sopt)); - fmt = IF_SVE_AB_3A; + fmt = IF_SVE_AA_3A; } break; @@ -2994,7 +2997,7 @@ void emitter::emitInsSve_R_R_R(instruction ins, assert(isVectorRegister(reg3)); assert(insOptsScalableStandard(opt)); assert(insScalableOptsNone(sopt)); - fmt = IF_SVE_AD_3A; + fmt = IF_SVE_AA_3A; break; case INS_sve_mul: @@ -3060,7 +3063,6 @@ void emitter::emitInsSve_R_R_R(instruction ins, break; case INS_sve_saddv: - case INS_sve_uaddv: assert(isFloatReg(reg1)); assert(isLowPredicateRegister(reg2)); assert(isVectorRegister(reg3)); @@ -3069,6 +3071,15 @@ void emitter::emitInsSve_R_R_R(instruction ins, fmt = IF_SVE_AI_3A; break; + case INS_sve_uaddv: + assert(isFloatReg(reg1)); + assert(isLowPredicateRegister(reg2)); + assert(isVectorRegister(reg3)); + assert(insOptsScalableStandard(opt)); + assert(insScalableOptsNone(sopt)); + fmt = IF_SVE_AI_3A; + break; + case INS_sve_addqv: unreached(); // TODO-SVE: Not yet supported. assert(isVectorRegister(reg1)); @@ -3720,7 +3731,7 @@ void emitter::emitInsSve_R_R_R(instruction ins, else if (sopt == INS_SCALABLE_OPTS_WITH_SIMD_SCALAR) { assert(isFloatReg(reg1)); - assert(isValidVectorElemsize(size)); + assert(isScalableVectorSize(size)); fmt = IF_SVE_CN_3A; } else @@ -3740,7 +3751,7 @@ void emitter::emitInsSve_R_R_R(instruction ins, if (sopt == INS_SCALABLE_OPTS_UNPREDICATED) { assert(ins == INS_sve_mov); - assert(opt == INS_OPTS_SCALABLE_D); + assert(insOptsScalableStandard(opt)); assert(isVectorRegister(reg1)); // ddddd assert(isVectorRegister(reg2)); // nnnnn assert(isVectorRegister(reg3)); // mmmmm @@ -4059,7 +4070,7 @@ void emitter::emitInsSve_R_R_R(instruction ins, assert(isLowPredicateRegister(reg2)); assert(isVectorRegister(reg3)); assert(insOptsScalableFloat(opt)); - assert(isValidVectorElemsizeSveFloat(size)); + assert(isScalableVectorSize(size)); assert(insScalableOptsNone(sopt)); fmt = IF_SVE_HE_3A; break; @@ -4069,7 +4080,7 @@ void emitter::emitInsSve_R_R_R(instruction ins, assert(isLowPredicateRegister(reg2)); assert(isVectorRegister(reg3)); assert(insOptsScalableFloat(opt)); - assert(isValidVectorElemsizeSveFloat(size)); + assert(isScalableVectorSize(size)); assert(insScalableOptsNone(sopt)); fmt = IF_SVE_HJ_3A; break; @@ -4349,8 +4360,11 @@ void emitter::emitInsSve_R_R_R(instruction ins, break; case INS_sve_ld1b: + case INS_sve_ld1sb: case INS_sve_ld1h: + case INS_sve_ld1sh: case INS_sve_ld1w: + case INS_sve_ld1sw: case INS_sve_ld1d: return emitIns_R_R_R_I(ins, size, reg1, reg2, reg3, 0, opt); @@ -8006,11 +8020,9 @@ void emitter::emitIns_PRFOP_R_R_I(instruction ins, case IF_SVE_HP_3B: case IF_SVE_AR_4A: case IF_SVE_BV_2A_A: - case IF_SVE_AB_3A: case IF_SVE_ET_3A: case IF_SVE_HU_4A: case IF_SVE_HL_3B: - case IF_SVE_AD_3A: case IF_SVE_AB_3B: case IF_SVE_AE_3A: case IF_SVE_EU_3A: @@ -9894,10 +9906,9 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) switch (fmt) { // Scalable. - case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations (predicated) - case IF_SVE_AB_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer add/subtract vectors (predicated) + case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations + integer add/subtract + // vectors + SVE integer min/max/difference (predicated) case IF_SVE_AC_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer divide vectors (predicated) - case IF_SVE_AD_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer min/max/difference (predicated) case IF_SVE_AE_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer multiply vectors (predicated) case IF_SVE_AF_3A: // ........xx...... ...gggnnnnnddddd -- SVE bitwise logical reduction (predicated) case IF_SVE_AG_3A: // ........xx...... ...gggnnnnnddddd -- SVE bitwise logical reduction (quadwords) @@ -11794,7 +11805,6 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) case IF_SVE_BJ_2A: // ........xx...... ......nnnnnddddd -- SVE floating-point exponential accelerator case IF_SVE_CG_2A: // ........xx...... ......nnnnnddddd -- SVE reverse vector elements - case IF_SVE_CH_2A: // ........xx...... ......nnnnnddddd -- SVE unpack vector elements case IF_SVE_HF_2A: // ........xx...... ......nnnnnddddd -- SVE floating-point reciprocal estimate (unpredicated) code = emitInsCodeSve(ins, fmt); code |= insEncodeReg_V<4, 0>(id->idReg1()); // ddddd @@ -11803,6 +11813,14 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) dst += emitOutput_Instr(dst, code); break; + case IF_SVE_CH_2A: // ........xx...... ......nnnnnddddd -- SVE unpack vector elements + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V<4, 0>(id->idReg1()); // ddddd + code |= insEncodeReg_V<9, 5>(id->idReg2()); // nnnnn + code |= insEncodeSveElemsize(optGetSveElemsize((insOpts)(id->idInsOpt() + 1))); // xx + dst += emitOutput_Instr(dst, code); + break; + case IF_SVE_BF_2A: // ........xx.xxiii ......nnnnnddddd -- SVE bitwise shift by immediate (unpredicated) case IF_SVE_FT_2A: // ........xx.xxiii ......nnnnnddddd -- SVE2 bitwise shift and insert case IF_SVE_FU_2A: // ........xx.xxiii ......nnnnnddddd -- SVE2 bitwise shift right and accumulate @@ -12539,9 +12557,8 @@ void emitter::emitInsSveSanityCheck(instrDesc* id) break; // Scalable. - case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations (predicated) - case IF_SVE_AB_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer add/subtract vectors (predicated) - case IF_SVE_AD_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer min/max/difference (predicated) + case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations + integer add/subtract + // vectors + SVE integer min/max/difference (predicated) case IF_SVE_AE_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer multiply vectors (predicated) case IF_SVE_AN_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise shift by vector (predicated) case IF_SVE_CM_3A: // ........xx...... ...gggmmmmmddddd -- SVE conditionally broadcast element to vector @@ -12605,7 +12622,7 @@ void emitter::emitInsSveSanityCheck(instrDesc* id) assert(isVectorRegister(id->idReg1())); // ddddd assert(isLowPredicateRegister(id->idReg2())); // ggg assert(isVectorRegister(id->idReg3())); // mmmmm - assert(isValidVectorElemsize(id->idOpSize())); + assert(isScalableVectorSize(id->idOpSize())); break; // Scalable to FP SIMD scalar. @@ -12615,7 +12632,7 @@ void emitter::emitInsSveSanityCheck(instrDesc* id) assert(isVectorRegister(id->idReg1())); // ddddd assert(isLowPredicateRegister(id->idReg2())); // ggg assert(isVectorRegister(id->idReg3())); // mmmmm - assert(isValidVectorElemsizeSveFloat(id->idOpSize())); + assert(isScalableVectorSize(id->idOpSize())); break; // Scalable to general register. @@ -13208,11 +13225,20 @@ void emitter::emitInsSveSanityCheck(instrDesc* id) // Scalable, widening to scalar SIMD. case IF_SVE_AI_3A: // ........xx...... ...gggnnnnnddddd -- SVE integer add reduction (predicated) - assert(insOptsScalableWide(id->idInsOpt())); // xx + switch (id->idIns()) + { + case INS_sve_saddv: + assert(insOptsScalableWide(id->idInsOpt())); // xx + break; + + default: + assert(insOptsScalableStandard(id->idInsOpt())); // xx + break; + } assert(isVectorRegister(id->idReg1())); // ddddd assert(isLowPredicateRegister(id->idReg2())); // ggg assert(isVectorRegister(id->idReg3())); // mmmmm - assert(isValidVectorElemsizeWidening(id->idOpSize())); + assert(isScalableVectorSize(id->idOpSize())); break; // Scalable, possibly FP. @@ -14367,13 +14393,18 @@ void emitter::emitInsSveSanityCheck(instrDesc* id) break; case IF_SVE_BJ_2A: // ........xx...... ......nnnnnddddd -- SVE floating-point exponential accelerator - case IF_SVE_CH_2A: // ........xx...... ......nnnnnddddd -- SVE unpack vector elements case IF_SVE_HF_2A: // ........xx...... ......nnnnnddddd -- SVE floating-point reciprocal estimate (unpredicated) assert(insOptsScalableAtLeastHalf(id->idInsOpt())); assert(isVectorRegister(id->idReg1())); assert(isVectorRegister(id->idReg2())); break; + case IF_SVE_CH_2A: // ........xx...... ......nnnnnddddd -- SVE unpack vector elements + assert(insOptsScalableWide(id->idInsOpt())); + assert(isVectorRegister(id->idReg1())); + assert(isVectorRegister(id->idReg2())); + break; + case IF_SVE_BF_2A: // ........xx.xxiii ......nnnnnddddd -- SVE bitwise shift by immediate (unpredicated) case IF_SVE_FT_2A: // ........xx.xxiii ......nnnnnddddd -- SVE2 bitwise shift and insert case IF_SVE_FU_2A: // ........xx.xxiii ......nnnnnddddd -- SVE2 bitwise shift right and accumulate @@ -14458,10 +14489,9 @@ void emitter::emitDispInsSveHelp(instrDesc* id) bitMaskImm bmi; // ., /M, ., . - case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations (predicated) - case IF_SVE_AB_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer add/subtract vectors (predicated) + case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations + integer add/subtract + // vectors + SVE integer min/max/difference (predicated) case IF_SVE_AC_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer divide vectors (predicated) - case IF_SVE_AD_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer min/max/difference (predicated) case IF_SVE_AE_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer multiply vectors (predicated) case IF_SVE_AN_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise shift by vector (predicated) case IF_SVE_EP_3A: // ........xx...... ...gggmmmmmddddd -- SVE2 integer halving add/subtract (predicated) @@ -16211,8 +16241,8 @@ void emitter::emitDispInsSveHelp(instrDesc* id) case IF_SVE_HH_2A: // ................ ......nnnnnddddd -- SVE2 FP8 upconverts // ., . case IF_SVE_CH_2A: // ........xx...... ......nnnnnddddd -- SVE unpack vector elements - emitDispSveReg(id->idReg1(), id->idInsOpt(), true); - emitDispSveReg(id->idReg2(), (insOpts)((unsigned)id->idInsOpt() - 1), false); + emitDispSveReg(id->idReg1(), (insOpts)(id->idInsOpt() + 1), true); + emitDispSveReg(id->idReg2(), id->idInsOpt(), false); break; // ., . @@ -16316,16 +16346,32 @@ void emitter::getInsSveExecutionCharacteristics(instrDesc* id, insExecutionChara switch (id->idInsFmt()) { // Predicate logical - case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations (predicated) - result.insLatency = PERFSCORE_LATENCY_1C; - result.insThroughput = PERFSCORE_THROUGHPUT_1C; + case IF_SVE_AA_3A: // ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations + integer add/subtract + // vectors + SVE integer min/max/difference (predicated) + switch (ins) + { + case INS_sve_add: + case INS_sve_sub: + case INS_sve_subr: + case INS_sve_sabd: + case INS_sve_smax: + case INS_sve_smin: + case INS_sve_uabd: + case INS_sve_umax: + case INS_sve_umin: + result.insLatency = PERFSCORE_LATENCY_2C; + result.insThroughput = PERFSCORE_THROUGHPUT_2X; + break; + + default: + result.insLatency = PERFSCORE_LATENCY_1C; + result.insThroughput = PERFSCORE_THROUGHPUT_1C; + break; + } break; // Arithmetic, basic - case IF_SVE_AB_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer add/subtract vectors (predicated) case IF_SVE_EP_3A: // ........xx...... ...gggmmmmmddddd -- SVE2 integer halving add/subtract (predicated) - // Max/min, basic and pairwise - case IF_SVE_AD_3A: // ........xx...... ...gggmmmmmddddd -- SVE integer min/max/difference (predicated) result.insLatency = PERFSCORE_LATENCY_2C; result.insThroughput = PERFSCORE_THROUGHPUT_2X; break; diff --git a/src/coreclr/jit/emitfmtsarm64sve.h b/src/coreclr/jit/emitfmtsarm64sve.h index cd27f567478cf0..672f6ab529b006 100644 --- a/src/coreclr/jit/emitfmtsarm64sve.h +++ b/src/coreclr/jit/emitfmtsarm64sve.h @@ -138,10 +138,8 @@ IF_DEF(SVE_2BS, IS_NONE, NONE) // Instruction has 2 possible encoding types, ty *****************************************************************************/ IF_DEF(SVE_AA_3A, IS_NONE, NONE) // SVE_AA_3A ........xx...... ...gggmmmmmddddd -- SVE bitwise logical operations (predicated) -IF_DEF(SVE_AB_3A, IS_NONE, NONE) // SVE_AB_3A ........xx...... ...gggmmmmmddddd -- SVE integer add/subtract vectors (predicated) IF_DEF(SVE_AB_3B, IS_NONE, NONE) // SVE_AB_3B ................ ...gggmmmmmddddd -- SVE integer add/subtract vectors (predicated) IF_DEF(SVE_AC_3A, IS_NONE, NONE) // SVE_AC_3A ........xx...... ...gggmmmmmddddd -- SVE integer divide vectors (predicated) -IF_DEF(SVE_AD_3A, IS_NONE, NONE) // SVE_AD_3A ........xx...... ...gggmmmmmddddd -- SVE integer min/max/difference (predicated) IF_DEF(SVE_AE_3A, IS_NONE, NONE) // SVE_AE_3A ........xx...... ...gggmmmmmddddd -- SVE integer multiply vectors (predicated) IF_DEF(SVE_AF_3A, IS_NONE, NONE) // SVE_AF_3A ........xx...... ...gggnnnnnddddd -- SVE bitwise logical reduction (predicated) IF_DEF(SVE_AG_3A, IS_NONE, NONE) // SVE_AG_3A ........xx...... ...gggnnnnnddddd -- SVE bitwise logical reduction (quadwords) diff --git a/src/coreclr/jit/emitloongarch64.cpp b/src/coreclr/jit/emitloongarch64.cpp index c69ea7c5a36e6f..43281e536e8b31 100644 --- a/src/coreclr/jit/emitloongarch64.cpp +++ b/src/coreclr/jit/emitloongarch64.cpp @@ -3848,8 +3848,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } } -#ifdef DEBUG - if (emitComp->opts.disAsm || emitComp->verbose) + if (emitComp->opts.disAsm INDEBUG(|| emitComp->verbose)) { code_t* cp = (code_t*)(*dp + writeableOffset); while ((BYTE*)cp != dstRW) @@ -3859,6 +3858,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } } +#ifdef DEBUG if (emitComp->compDebugBreak) { // For example, set JitBreakEmitOutputInstr=a6 will break when this method is called for @@ -3882,8 +3882,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) /*****************************************************************************/ /*****************************************************************************/ -#ifdef DEBUG - // clang-format off static const char* const RegNames[] = { @@ -3964,19 +3962,21 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) { const BYTE* insAdr = addr - writeableOffset; - bool disOpcode = !emitComp->opts.disDiffable; - bool disAddr = emitComp->opts.disAddr; - if (disAddr) +#ifdef DEBUG + if (emitComp->opts.disAddr) { printf(" 0x%llx", insAdr); } printf(" "); - if (disOpcode) + if (!emitComp->opts.disDiffable) { printf("%08X ", code); } +#else + printf(" "); +#endif const int regd = code & 0x1f; const int regj = (code >> 5) & 0x1f; @@ -4190,8 +4190,9 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) return; case DF_F_RG12I: { - tmp = ((code >> 10) & 0xfff); - printf("%s, %s, 0x%x\n", RegNames[regd + 32], RegNames[regj], tmp); + tmp = code << 10; + tmp >>= 20; + printf("%s, %s, %d\n", RegNames[regd + 32], RegNames[regj], tmp); return; } case DF_F_FG: @@ -4539,51 +4540,16 @@ void emitter::emitDispIns( } } +#ifdef DEBUG /***************************************************************************** * * Display a stack frame reference. */ - void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) { - printf("["); - - if (varx < 0) - printf("TEMP_%02u", -varx); - else - emitComp->gtDispLclVar(+varx, false); - - if (disp < 0) - printf("-0x%02x", -disp); - else if (disp > 0) - printf("+0x%02x", +disp); - - printf("]"); - - if (varx >= 0 && emitComp->opts.varNames) - { - LclVarDsc* varDsc; - const char* varName; - - assert((unsigned)varx < emitComp->lvaCount); - varDsc = emitComp->lvaTable + varx; - varName = emitComp->compLocalVarName(varx, offs); - - if (varName) - { - printf("'%s", varName); - - if (disp < 0) - printf("-%d", -disp); - else if (disp > 0) - printf("+%d", +disp); - - printf("'"); - } - } + NYI_LOONGARCH64("emitDispFrameRef-----unused on LoongArch64."); } - -#endif // DEBUG +#endif // Generate code for a load or store operation with a potentially complex addressing mode // This method handles the case of a GT_IND with contained GT_LEA op1 of the x86 form [base + index*sccale + offset] @@ -4620,7 +4586,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR if (offset != 0) { - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); if (isValidSimm12(offset)) { @@ -4761,7 +4727,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR else { // We require a tmpReg to hold the offset - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); // First load/store tmpReg with the large offset constant emitIns_I_la(EA_PTRSIZE, tmpReg, offset); @@ -5092,7 +5058,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, if ((dst->gtFlags & GTF_UNSIGNED) == 0) { - saveOperReg2 = dst->GetSingleTempReg(); + saveOperReg2 = codeGen->internalRegisters.GetSingle(dst); assert((saveOperReg2 != REG_RA) && (saveOperReg2 != REG_R21)); assert(REG_RA != regOp1); assert(saveOperReg2 != regOp2); diff --git a/src/coreclr/jit/emitloongarch64.h b/src/coreclr/jit/emitloongarch64.h index 135f9cf4006735..bae6d188ca1f79 100644 --- a/src/coreclr/jit/emitloongarch64.h +++ b/src/coreclr/jit/emitloongarch64.h @@ -19,10 +19,6 @@ struct CnsVal bool cnsReloc; }; -#ifdef DEBUG -/************************************************************************/ -/* Debug-only routines to display instructions */ -/************************************************************************/ enum insDisasmFmt { DF_G_INVALID = 0, @@ -108,7 +104,6 @@ code_t emitGetInsMask(int ins); insDisasmFmt emitGetInsFmt(instruction ins); void emitDispInst(instruction ins); void emitDisInsName(code_t code, const BYTE* addr, instrDesc* id); -#endif // DEBUG void emitIns_J_cond_la(instruction ins, BasicBlock* dst, regNumber reg1 = REG_R0, regNumber reg2 = REG_R0); void emitIns_I_la(emitAttr attr, regNumber reg, ssize_t imm); @@ -333,7 +328,7 @@ enum EmitCallType EC_FUNC_TOKEN, // Direct call to a helper/static/nonvirtual/global method // EC_FUNC_TOKEN_INDIR, // Indirect call to a helper/static/nonvirtual/global method - // EC_FUNC_ADDR, // Direct call to an absolute address + // EC_FUNC_ADDR, // Direct call to an absolute address EC_INDIR_R, // Indirect call via register diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index d78fc0e9d5b29b..932c9a1125b016 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -4463,7 +4463,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR if (offset != 0) { - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); if (isValidSimm12(offset)) { @@ -4496,7 +4496,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg)); noway_assert(tmpReg != index->GetRegNum()); - regNumber scaleReg = indir->GetSingleTempReg(); + regNumber scaleReg = codeGen->internalRegisters.GetSingle(indir); // Then load/store dataReg from/to [tmpReg + index*scale] emitIns_R_R_I(INS_slli, addType, scaleReg, index->GetRegNum(), lsl); emitIns_R_R_R(INS_add, addType, tmpReg, tmpReg, scaleReg); @@ -4605,7 +4605,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR else { // We require a tmpReg to hold the offset - regNumber tmpReg = indir->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(indir); // First load/store tmpReg with the large offset constant emitLoadImmediate(EA_PTRSIZE, tmpReg, offset); @@ -4771,7 +4771,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, assert(ins == INS_addi || ins == INS_addiw || ins == INS_andi || ins == INS_ori || ins == INS_xori); - regNumber tempReg = needCheckOv ? dst->ExtractTempReg() : REG_NA; + regNumber tempReg = needCheckOv ? codeGen->internalRegisters.Extract(dst) : REG_NA; if (needCheckOv) { @@ -4823,7 +4823,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, } else { - regNumber tempReg = needCheckOv ? dst->ExtractTempReg() : REG_NA; + regNumber tempReg = needCheckOv ? codeGen->internalRegisters.Extract(dst) : REG_NA; switch (dst->OperGet()) { @@ -4897,7 +4897,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, } else { - regNumber tempReg2 = dst->ExtractTempReg(); + regNumber tempReg2 = codeGen->internalRegisters.Extract(dst); assert(tempReg2 != dstReg); assert(tempReg2 != src1Reg); assert(tempReg2 != src2Reg); @@ -5003,7 +5003,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, else { tempReg1 = REG_RA; - tempReg2 = dst->ExtractTempReg(); + tempReg2 = codeGen->internalRegisters.Extract(dst); assert(tempReg1 != tempReg2); assert(tempReg1 != saveOperReg1); assert(tempReg2 != saveOperReg2); diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 07e603a70afb7c..262f44c9ac4bbd 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -310,7 +310,7 @@ enum EmitCallType EC_FUNC_TOKEN, // Direct call to a helper/static/nonvirtual/global method // EC_FUNC_TOKEN_INDIR, // Indirect call to a helper/static/nonvirtual/global method - // EC_FUNC_ADDR, // Direct call to an absolute address + // EC_FUNC_ADDR, // Direct call to an absolute address // EC_FUNC_VIRTUAL, // Call to a virtual method (using the vtable) EC_INDIR_R, // Indirect call via register diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 6bf148cf2d8883..6fe7f00dddc359 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -5641,7 +5641,7 @@ void emitter::emitStoreSimd12ToLclOffset(unsigned varNum, unsigned offset, regNu } else { - regNumber tmpReg = tmpRegProvider->GetSingleTempReg(); + regNumber tmpReg = codeGen->internalRegisters.GetSingle(tmpRegProvider); assert(isFloatReg(tmpReg)); // Extract upper 4 bytes from data @@ -10102,7 +10102,7 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) con suffix = 'd'; goto APPEND_SUFFIX; } - rbc = (rbc + 1) % 2; + rbc ^= 1; rb[rbc][0] = 'e'; rb[rbc][1] = rn[1]; rb[rbc][2] = rn[2]; @@ -10133,7 +10133,7 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) con { suffix = 'b'; APPEND_SUFFIX: - rbc = (rbc + 1) % 2; + rbc ^= 1; rb[rbc][0] = rn[0]; rb[rbc][1] = rn[1]; if (rn[2]) @@ -10151,7 +10151,7 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) con } else { - rbc = (rbc + 1) % 2; + rbc ^= 1; rb[rbc][0] = rn[1]; if (reg < 4) { @@ -10168,7 +10168,7 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName) con #endif // TARGET_AMD64 #if defined(TARGET_X86) - rbc = (rbc + 1) % 2; + rbc ^= 1; rb[rbc][0] = rn[1]; rb[rbc][1] = 'l'; strcpy_s(&rb[rbc][2], sizeof(rb[0]) - 2, rn + 3); diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 1638dfec507324..538c49e530ecb1 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -50,6 +50,7 @@ void Compiler::fgInit() fgDomBBcount = 0; fgBBVarSetsInited = false; fgReturnCount = 0; + fgThrowCount = 0; m_dfsTree = nullptr; m_loops = nullptr; @@ -167,7 +168,6 @@ void Compiler::fgInit() fgHistogramInstrumentor = nullptr; fgValueInstrumentor = nullptr; fgPredListSortVector = nullptr; - fgCanonicalizedFirstBB = false; } //------------------------------------------------------------------------ @@ -215,10 +215,41 @@ bool Compiler::fgEnsureFirstBBisScratch() block = BasicBlock::New(this); - // If we have profile data the new block will inherit fgFirstBlock's weight + // If we have profile data determine the weight of the scratch BB + // if (fgFirstBB->hasProfileWeight()) { - block->inheritWeight(fgFirstBB); + // If current entry has preds, sum up those weights + // + weight_t nonEntryWeight = 0; + for (FlowEdge* const edge : fgFirstBB->PredEdges()) + { + nonEntryWeight += edge->getLikelyWeight(); + } + + // entry weight is weight not from any pred + // + weight_t const entryWeight = fgFirstBB->bbWeight - nonEntryWeight; + if (entryWeight <= 0) + { + // If the result is clearly nonsensical, just inherit + // + JITDUMP( + "\fgEnsureFirstBBisScratch: Profile data could not be locally repaired. Data %s inconsistent.\n", + fgPgoConsistent ? "is now" : "was already"); + + if (fgPgoConsistent) + { + Metrics.ProfileInconsistentScratchBB++; + fgPgoConsistent = false; + } + + block->inheritWeight(fgFirstBB); + } + else + { + block->setBBProfileWeight(entryWeight); + } } // The new scratch bb will fall through to the old first bb @@ -3070,19 +3101,18 @@ void Compiler::fgLinkBasicBlocks() // codeSize -- length of the IL stream // jumpTarget -- [in] bit vector of jump targets found by fgFindJumpTargets // -// Returns: -// number of return blocks (BBJ_RETURN) in the method (may be zero) -// // Notes: -// Invoked for prejited and jitted methods, and for all inlinees - -unsigned Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget) +// Invoked for prejitted and jitted methods, and for all inlinees. +// Sets fgReturnCount and fgThrowCount +// +void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget) { - unsigned retBlocks = 0; - const BYTE* codeBegp = codeAddr; - const BYTE* codeEndp = codeAddr + codeSize; - bool tailCall = false; - unsigned curBBoffs = 0; + unsigned retBlocks = 0; + unsigned throwBlocks = 0; + const BYTE* codeBegp = codeAddr; + const BYTE* codeEndp = codeAddr + codeSize; + bool tailCall = false; + unsigned curBBoffs = 0; BasicBlock* curBBdesc; // Keep track of where we are in the scope lists, as we will also @@ -3283,7 +3313,8 @@ unsigned Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, F // can be dispatched as tail calls from the caller. compInlineResult->NoteFatal(InlineObservation::CALLEE_EXPLICIT_TAIL_PREFIX); retBlocks++; - return retBlocks; + fgReturnCount = retBlocks; + return; } FALLTHROUGH; @@ -3386,6 +3417,7 @@ unsigned Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, F case CEE_THROW: case CEE_RETHROW: + throwBlocks++; jmpKind = BBJ_THROW; break; @@ -3568,7 +3600,8 @@ unsigned Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, F fgLinkBasicBlocks(); - return retBlocks; + fgReturnCount = retBlocks; + fgThrowCount = throwBlocks; } /***************************************************************************** @@ -3680,7 +3713,7 @@ void Compiler::fgFindBasicBlocks() /* Now create the basic blocks */ - fgReturnCount = fgMakeBasicBlocks(info.compCode, info.compILCodeSize, jumpTarget); + fgMakeBasicBlocks(info.compCode, info.compILCodeSize, jumpTarget); if (compIsForInlining()) { @@ -4240,7 +4273,7 @@ void Compiler::fgFixEntryFlowForOSR() // if ((fgEntryBB->bbPreds != nullptr) && (fgEntryBB != fgOSREntryBB)) { - JITDUMP("OSR: profile data could not be locally repaired. Data %s inconsisent.\n", + JITDUMP("OSR: profile data could not be locally repaired. Data %s inconsistent.\n", fgPgoConsistent ? "is now" : "was already"); fgPgoConsistent = false; } @@ -5063,17 +5096,28 @@ BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ) fgReplaceJumpTarget(curr, succ, newBlock); // And 'succ' has 'newBlock' as a new predecessor. - FlowEdge* const newEdge = fgAddRefPred(succ, newBlock); - newBlock->SetTargetEdge(newEdge); + FlowEdge* const newSuccEdge = fgAddRefPred(succ, newBlock); + newBlock->SetTargetEdge(newSuccEdge); - // This isn't accurate, but it is complex to compute a reasonable number so just assume that we take the - // branch 50% of the time. - // - // TODO: leverage edge likelihood. + // Set weight for newBlock // - if (!curr->KindIs(BBJ_ALWAYS)) + if (curr->KindIs(BBJ_ALWAYS)) { - newBlock->inheritWeightPercentage(curr, 50); + newBlock->inheritWeight(curr); + } + else + { + if (curr->hasProfileWeight()) + { + FlowEdge* const currNewEdge = fgGetPredForBlock(newBlock, curr); + newBlock->setBBProfileWeight(currNewEdge->getLikelyWeight()); + } + else + { + // Todo: use likelihood even w/o profile? + // + newBlock->inheritWeightPercentage(curr, 50); + } } // The bbLiveIn and bbLiveOut are both equal to the bbLiveIn of 'succ' diff --git a/src/coreclr/jit/fgehopt.cpp b/src/coreclr/jit/fgehopt.cpp index a26eaf0bfa8b3d..743559717e47cb 100644 --- a/src/coreclr/jit/fgehopt.cpp +++ b/src/coreclr/jit/fgehopt.cpp @@ -1229,16 +1229,6 @@ PhaseStatus Compiler::fgCloneFinally() block->setBBProfileWeight(blockWeight * originalScale); JITDUMP("Set weight of " FMT_BB " to " FMT_WT "\n", block->bbNum, block->bbWeight); -#if HANDLER_ENTRY_MUST_BE_IN_HOT_SECTION - // Handle a special case -- some handler entries can't have zero profile count. - // - if (bbIsHandlerBeg(block) && block->isRunRarely()) - { - JITDUMP("Suppressing zero count for " FMT_BB " as it is a handler entry\n", block->bbNum); - block->makeBlockHot(); - } -#endif - BasicBlock* const clonedBlock = blockMap[block]; clonedBlock->setBBProfileWeight(blockWeight * clonedScale); JITDUMP("Set weight of " FMT_BB " to " FMT_WT "\n", clonedBlock->bbNum, clonedBlock->bbWeight); diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index 6812dfbffdb7e9..7a6246a988fda3 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -624,24 +624,86 @@ class SubstitutePlaceholdersAndDevirtualizeWalker : public GenTreeVisitordspTreeID(tree), block->bbNum); + m_compiler->Metrics.InlinerBranchFold++; // We have a constant operand, and should have the all clear to optimize. // Update side effects on the tree, assert there aren't any, and bash to nop. m_compiler->gtUpdateNodeSideEffects(tree); assert((tree->gtFlags & GTF_SIDE_EFFECT) == 0); tree->gtBashToNOP(); - m_madeChanges = true; + m_madeChanges = true; + FlowEdge* removedEdge = nullptr; if (condTree->IsIntegralConst(0)) { - m_compiler->fgRemoveRefPred(block->GetTrueEdge()); + removedEdge = block->GetTrueEdge(); + m_compiler->fgRemoveRefPred(removedEdge); block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetFalseEdge()); } else { - m_compiler->fgRemoveRefPred(block->GetFalseEdge()); + removedEdge = block->GetFalseEdge(); + m_compiler->fgRemoveRefPred(removedEdge); block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetTrueEdge()); } + + // Update profile; make it consistent if possible + // + if (block->hasProfileWeight()) + { + bool repairWasComplete = true; + weight_t const weight = removedEdge->getLikelyWeight(); + + if (weight > 0) + { + // Target block weight will increase. + // + BasicBlock* const target = block->GetTarget(); + assert(target->hasProfileWeight()); + target->setBBProfileWeight(target->bbWeight + weight); + + // Alternate weight will decrease + // + BasicBlock* const alternate = removedEdge->getDestinationBlock(); + assert(alternate->hasProfileWeight()); + weight_t const alternateNewWeight = alternate->bbWeight - weight; + + // If profile weights are consistent, expect at worst a slight underflow. + // + if (m_compiler->fgPgoConsistent && (alternateNewWeight < 0)) + { + assert(m_compiler->fgProfileWeightsEqual(alternateNewWeight, 0)); + } + alternate->setBBProfileWeight(max(0.0, alternateNewWeight)); + + // This will affect profile transitively, so in general + // the profile will become inconsistent. + // + repairWasComplete = false; + + // But we can check for the special case where the + // block's postdominator is target's target (simple + // if/then/else/join). + // + if (target->KindIs(BBJ_ALWAYS)) + { + repairWasComplete = + alternate->KindIs(BBJ_ALWAYS) && alternate->TargetIs(target->GetTarget()); + } + } + + if (!repairWasComplete) + { + JITDUMP("Profile data could not be locally repaired. Data %s inconsistent.\n", + m_compiler->fgPgoConsistent ? "is now" : "was already"); + + if (m_compiler->fgPgoConsistent) + { + m_compiler->Metrics.ProfileInconsistentInlinerBranchFold++; + m_compiler->fgPgoConsistent = false; + } + } + } } } else @@ -692,6 +754,11 @@ PhaseStatus Compiler::fgInline() JitConfig.JitPrintInlinedMethods().contains(info.compMethodHnd, info.compClassHnd, &info.compMethodInfo->args); #endif // DEBUG + if (fgPgoConsistent) + { + Metrics.ProfileConsistentBeforeInline++; + } + noway_assert(fgFirstBB != nullptr); BasicBlock* block = fgFirstBB; @@ -822,6 +889,14 @@ PhaseStatus Compiler::fgInline() fgRenumberBlocks(); } + if (fgPgoConsistent) + { + Metrics.ProfileConsistentAfterInline++; + } + + Metrics.InlineCount = m_inlineStrategy->GetInlineCount(); + Metrics.InlineAttempt = m_inlineStrategy->GetImportCount(); + return madeChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING; } @@ -1590,6 +1665,11 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo) // Update no-return call count optNoReturnCallCount += InlineeCompiler->optNoReturnCallCount; +#ifdef DEBUG + // Update metrics + Metrics.mergeToRoot(InlineeCompiler); +#endif + // Update optMethodFlags #ifdef DEBUG @@ -1606,6 +1686,75 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo) } #endif + // Update profile consistency + // + // If inlinee is inconsistent, root method will be inconsistent too. + // + if (!InlineeCompiler->fgPgoConsistent) + { + if (fgPgoConsistent) + { + JITDUMP("INLINER: profile data in root now inconsistent -- inlinee had inconsistency\n"); + Metrics.ProfileInconsistentInlinee++; + fgPgoConsistent = false; + } + } + + // If we inline a no-return call at a site with profile weight, + // we will introduce inconsistency. + // + if (InlineeCompiler->fgReturnCount == 0) + { + JITDUMP("INLINER: no-return inlinee\n"); + + if (iciBlock->bbWeight > 0) + { + if (fgPgoConsistent) + { + JITDUMP("INLINER: profile data in root now inconsistent -- no-return inlinee at call site in " FMT_BB + " with weight " FMT_WT "\n", + iciBlock->bbNum, iciBlock->bbWeight); + Metrics.ProfileInconsistentNoReturnInlinee++; + fgPgoConsistent = false; + } + } + else + { + // Inlinee scaling should assure this is so. + // + assert(InlineeCompiler->fgFirstBB->bbWeight == 0); + } + } + + // If the call site is not in a try and the callee has a throw, + // we may introduce inconsistency. + // + // Technically we should check if the callee has a throw not in a try, but since + // we can't inline methods with EH yet we don't see those. + // + if (InlineeCompiler->fgThrowCount > 0) + { + JITDUMP("INLINER: may-throw inlinee\n"); + + if (iciBlock->bbWeight > 0) + { + if (fgPgoConsistent) + { + JITDUMP("INLINER: profile data in root now inconsistent -- may-throw inlinee at call site in " FMT_BB + " with weight " FMT_WT "\n", + iciBlock->bbNum, iciBlock->bbWeight); + Metrics.ProfileInconsistentMayThrowInlinee++; + fgPgoConsistent = false; + } + } + else + { + // Inlinee scaling should assure this is so. + // + assert(InlineeCompiler->fgFirstBB->bbWeight == 0); + } + } + // If an inlinee needs GS cookie we need to make sure that the cookie will not be allocated at zero stack offset. // Note that if the root method needs GS cookie then this has already been taken care of. if (!getNeedsGSSecurityCookie() && InlineeCompiler->getNeedsGSSecurityCookie()) diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index c1b919d37830a2..88dd717fab6934 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -731,17 +731,8 @@ PhaseStatus Compiler::fgPostImportationCleanup() // auto addConditionalFlow = [this, entryStateVar, &entryJumpTarget, &addedBlocks](BasicBlock* fromBlock, BasicBlock* toBlock) { - // We may have previously though this try entry was unreachable, but now we're going to - // step through it on the way to the OSR entry. So ensure it has plausible profile weight. - // - if (fgHaveProfileWeights() && !fromBlock->hasProfileWeight()) - { - JITDUMP("Updating block weight for now-reachable try entry " FMT_BB " via " FMT_BB "\n", - fromBlock->bbNum, fgFirstBB->bbNum); - fromBlock->inheritWeight(fgFirstBB); - } - BasicBlock* const newBlock = fgSplitBlockAtBeginning(fromBlock); + newBlock->inheritWeight(fromBlock); fromBlock->SetFlags(BBF_INTERNAL); newBlock->RemoveFlags(BBF_DONT_REMOVE); addedBlocks++; @@ -754,16 +745,40 @@ PhaseStatus Compiler::fgPostImportationCleanup() fgNewStmtAtBeg(fromBlock, jumpIfEntryStateZero); FlowEdge* const osrTryEntryEdge = fgAddRefPred(toBlock, fromBlock); - newBlock->inheritWeight(fromBlock); fromBlock->SetCond(osrTryEntryEdge, normalTryEntryEdge); - // Not sure what the correct edge likelihoods are just yet; - // for now we'll say the OSR path is the likely one. - // - // Todo: can we leverage profile data here to get a better answer? - // - osrTryEntryEdge->setLikelihood(0.9); - normalTryEntryEdge->setLikelihood(0.1); + if (fgHaveProfileWeights()) + { + // We are adding a path from (ultimately) the method entry to "fromBlock" + // Update the profile weight. + // + weight_t const entryWeight = fgFirstBB->bbWeight; + + JITDUMP("Updating block weight for now-reachable try entry " FMT_BB " via " FMT_BB "\n", + fromBlock->bbNum, fgFirstBB->bbNum); + fromBlock->setBBProfileWeight(fromBlock->bbWeight + entryWeight); + + // We updated the weight of fromBlock above. + // + // Set the likelihoods such that the additional weight flows to toBlock + // (and so the "normal path" profile out of fromBlock to newBlock is unaltered) + // + // In some stress cases we may have a zero-weight OSR entry. + // Tolerate this by capping the fromToLikelihood. + // + weight_t const fromWeight = fromBlock->bbWeight; + weight_t const fromToLikelihood = min(1.0, entryWeight / fromWeight); + + osrTryEntryEdge->setLikelihood(fromToLikelihood); + normalTryEntryEdge->setLikelihood(1.0 - fromToLikelihood); + } + else + { + // Just set likelihoods arbitrarily + // + osrTryEntryEdge->setLikelihood(0.9); + normalTryEntryEdge->setLikelihood(0.1); + } entryJumpTarget = fromBlock; }; @@ -3397,9 +3412,22 @@ bool Compiler::fgReorderBlocks(bool useProfile) } } - // If we will be reordering blocks, ensure the false target of a BBJ_COND block is its next block if (useProfile) { + if (JitConfig.JitDoReversePostOrderLayout()) + { + fgDoReversePostOrderLayout(); + fgMoveColdBlocks(); + + // Renumber blocks to facilitate LSRA's order of block visitation + // TODO: Consider removing this, and using traversal order in lSRA + // + fgRenumberBlocks(); + + return true; + } + + // We will be reordering blocks, so ensure the false target of a BBJ_COND block is its next block for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->Next()) { if (block->KindIs(BBJ_COND) && !block->NextIs(block->GetFalseTarget())) @@ -4507,6 +4535,505 @@ bool Compiler::fgReorderBlocks(bool useProfile) #pragma warning(pop) #endif +//----------------------------------------------------------------------------- +// fgDoReversePostOrderLayout: Reorder blocks using a greedy RPO traversal. +// +void Compiler::fgDoReversePostOrderLayout() +{ +#ifdef DEBUG + if (verbose) + { + printf("*************** In fgDoReversePostOrderLayout()\n"); + + printf("\nInitial BasicBlocks"); + fgDispBasicBlocks(verboseTrees); + printf("\n"); + } +#endif // DEBUG + + // Compute DFS of all blocks in the method, using profile data to determine the order successors are visited in + // + FlowGraphDfsTree* const dfsTree = fgComputeDfs(); + + // Fast path: We don't have any EH regions, so just reorder the blocks + // + if (compHndBBtabCount == 0) + { + for (unsigned i = dfsTree->GetPostOrderCount() - 1; i != 0; i--) + { + BasicBlock* const block = dfsTree->GetPostOrder(i); + BasicBlock* const blockToMove = dfsTree->GetPostOrder(i - 1); + fgUnlinkBlock(blockToMove); + fgInsertBBafter(block, blockToMove); + } + + return; + } + + // The RPO will scramble the EH regions, requiring us to correct their state. + // To do so, we will need to determine the new end blocks of each region. + // + struct EHLayoutInfo + { + BasicBlock* tryRegionEnd; + BasicBlock* hndRegionEnd; + bool tryRegionInMainBody; + + // Default constructor provided so we can call ArrayStack::Emplace + // + EHLayoutInfo() = default; + }; + + ArrayStack regions(getAllocator(CMK_ArrayStack), compHndBBtabCount); + + // The RPO will break up call-finally pairs, so save them before re-ordering + // + struct CallFinallyPair + { + BasicBlock* callFinally; + BasicBlock* callFinallyRet; + + // Constructor provided so we can call ArrayStack::Emplace + // + CallFinallyPair(BasicBlock* first, BasicBlock* second) + : callFinally(first) + , callFinallyRet(second) + { + } + }; + + ArrayStack callFinallyPairs(getAllocator()); + + for (EHblkDsc* const HBtab : EHClauses(this)) + { + // Default-initialize a EHLayoutInfo for each EH clause + regions.Emplace(); + + if (HBtab->HasFinallyHandler()) + { + for (BasicBlock* const pred : HBtab->ebdHndBeg->PredBlocks()) + { + assert(pred->KindIs(BBJ_CALLFINALLY)); + if (pred->isBBCallFinallyPair()) + { + callFinallyPairs.Emplace(pred, pred->Next()); + } + } + } + } + + // Reorder blocks + // + for (unsigned i = dfsTree->GetPostOrderCount() - 1; i != 0; i--) + { + BasicBlock* const block = dfsTree->GetPostOrder(i); + BasicBlock* const blockToMove = dfsTree->GetPostOrder(i - 1); + + // Only reorder blocks within the same EH region -- we don't want to make them non-contiguous + // + if (BasicBlock::sameEHRegion(block, blockToMove)) + { + // Don't reorder EH regions with filter handlers -- we want the filter to come first + // + if (block->hasHndIndex() && ehGetDsc(block->getHndIndex())->HasFilter()) + { + continue; + } + + fgUnlinkBlock(blockToMove); + fgInsertBBafter(block, blockToMove); + } + } + + // Fix up call-finally pairs + // + for (int i = 0; i < callFinallyPairs.Height(); i++) + { + const CallFinallyPair& pair = callFinallyPairs.BottomRef(i); + fgUnlinkBlock(pair.callFinallyRet); + fgInsertBBafter(pair.callFinally, pair.callFinallyRet); + } + + // The RPO won't change the entry blocks of any EH regions, but reordering can change the last block in a region + // (for example, by pushing throw blocks unreachable via normal flow to the end of the region). + // First, determine the new EH region ends. + // + + for (BasicBlock* const block : Blocks(fgFirstBB, fgLastBBInMainFunction())) + { + if (block->hasTryIndex()) + { + EHLayoutInfo& layoutInfo = regions.BottomRef(block->getTryIndex()); + layoutInfo.tryRegionEnd = block; + layoutInfo.tryRegionInMainBody = true; + } + + if (block->hasHndIndex()) + { + regions.BottomRef(block->getHndIndex()).hndRegionEnd = block; + } + } + + for (BasicBlock* const block : Blocks(fgFirstFuncletBB)) + { + if (block->hasHndIndex()) + { + regions.BottomRef(block->getHndIndex()).hndRegionEnd = block; + } + + if (block->hasTryIndex()) + { + EHLayoutInfo& layoutInfo = regions.BottomRef(block->getTryIndex()); + + if (!layoutInfo.tryRegionInMainBody) + { + layoutInfo.tryRegionEnd = block; + } + } + } + + // Now, update the EH descriptors, starting with the try regions + // + auto getTryLast = [®ions](const unsigned index) -> BasicBlock* { + return regions.BottomRef(index).tryRegionEnd; + }; + + auto setTryLast = [®ions](const unsigned index, BasicBlock* const block) { + regions.BottomRef(index).tryRegionEnd = block; + }; + + ehUpdateTryLasts(getTryLast, setTryLast); + + // Now, do the handler regions + // + unsigned XTnum = 0; + for (EHblkDsc* const HBtab : EHClauses(this)) + { + // The end of each handler region should have been visited by iterating the blocklist above + // + BasicBlock* const hndEnd = regions.BottomRef(XTnum++).hndRegionEnd; + assert(hndEnd != nullptr); + + // Update the end pointer of this handler region to the new last block + // + HBtab->ebdHndLast = hndEnd; + const unsigned enclosingHndIndex = HBtab->ebdEnclosingHndIndex; + + // If this handler region is nested in another one, we might need to update its enclosing region's end block + // + if (enclosingHndIndex != EHblkDsc::NO_ENCLOSING_INDEX) + { + BasicBlock* const enclosingHndEnd = regions.BottomRef(enclosingHndIndex).hndRegionEnd; + assert(enclosingHndEnd != nullptr); + + // If the enclosing region ends right before the nested region begins, + // extend the enclosing region's last block to the end of the nested region. + // + BasicBlock* const hndBeg = HBtab->HasFilter() ? HBtab->ebdFilter : HBtab->ebdHndBeg; + if (enclosingHndEnd->NextIs(hndBeg)) + { + regions.BottomRef(enclosingHndIndex).hndRegionEnd = hndEnd; + } + } + } +} + +//----------------------------------------------------------------------------- +// fgMoveColdBlocks: Move rarely-run blocks to the end of their respective regions. +// +// Notes: +// Exception handlers are assumed to be cold, so we won't move blocks within them. +// +void Compiler::fgMoveColdBlocks() +{ +#ifdef DEBUG + if (verbose) + { + printf("*************** In fgMoveColdBlocks()\n"); + + printf("\nInitial BasicBlocks"); + fgDispBasicBlocks(verboseTrees); + printf("\n"); + } +#endif // DEBUG + + auto moveColdMainBlocks = [this]() { + // Find the last block in the main body that isn't part of an EH region + // + BasicBlock* lastMainBB; + for (lastMainBB = this->fgLastBBInMainFunction(); lastMainBB != nullptr; lastMainBB = lastMainBB->Prev()) + { + if (!lastMainBB->hasTryIndex() && !lastMainBB->hasHndIndex()) + { + break; + } + } + + // Nothing to do if there are two or fewer non-EH blocks + // + if ((lastMainBB == nullptr) || lastMainBB->IsFirst() || lastMainBB->PrevIs(fgFirstBB)) + { + return; + } + + // Search the main method body for rarely-run blocks to move + // + BasicBlock* prev; + for (BasicBlock* block = lastMainBB->Prev(); block != fgFirstBB; block = prev) + { + prev = block->Prev(); + + // We only want to move cold blocks. + // Also, don't consider blocks in EH regions for now; only move blocks in the main method body. + // Finally, don't move block if it is the beginning of a call-finally pair, + // as we want to keep these pairs contiguous + // (if we encounter the end of a pair below, we'll move the whole pair). + // + if (!block->isRunRarely() || block->hasTryIndex() || block->hasHndIndex() || block->isBBCallFinallyPair()) + { + continue; + } + + this->fgUnlinkBlock(block); + this->fgInsertBBafter(lastMainBB, block); + + // If block is the end of a call-finally pair, prev is the beginning of the pair. + // Move prev to before block to keep the pair contiguous. + // + if (block->KindIs(BBJ_CALLFINALLYRET)) + { + BasicBlock* const callFinally = prev; + prev = prev->Prev(); + assert(callFinally->KindIs(BBJ_CALLFINALLY)); + assert(!callFinally->HasFlag(BBF_RETLESS_CALL)); + this->fgUnlinkBlock(callFinally); + this->fgInsertBBafter(lastMainBB, callFinally); + } + } + + // We have moved all cold main blocks before lastMainBB to after lastMainBB. + // If lastMainBB itself is cold, move it to the end of the method to restore its relative ordering. + // + if (lastMainBB->isRunRarely()) + { + BasicBlock* const newLastMainBB = this->fgLastBBInMainFunction(); + if (lastMainBB != newLastMainBB) + { + BasicBlock* const prev = lastMainBB->Prev(); + this->fgUnlinkBlock(lastMainBB); + this->fgInsertBBafter(newLastMainBB, lastMainBB); + + // Call-finally check + // + if (lastMainBB->KindIs(BBJ_CALLFINALLYRET)) + { + assert(prev->KindIs(BBJ_CALLFINALLY)); + assert(!prev->HasFlag(BBF_RETLESS_CALL)); + assert(prev != newLastMainBB); + this->fgUnlinkBlock(prev); + this->fgInsertBBafter(newLastMainBB, prev); + } + } + } + }; + + moveColdMainBlocks(); + + // No EH regions + // + if (compHndBBtabCount == 0) + { + return; + } + + // We assume exception handlers are cold, so we won't bother moving blocks within them. + // We will move blocks only within try regions. + // First, determine where each try region ends, without considering nested regions. + // We will use these end blocks as insertion points. + // + BasicBlock** const tryRegionEnds = new (this, CMK_Generic) BasicBlock* [compHndBBtabCount] {}; + + for (BasicBlock* const block : Blocks(fgFirstBB, fgLastBBInMainFunction())) + { + if (block->hasTryIndex()) + { + tryRegionEnds[block->getTryIndex()] = block; + } + } + + // Search all try regions in the main method body for cold blocks to move + // + BasicBlock* prev; + for (BasicBlock* block = fgLastBBInMainFunction(); block != fgFirstBB; block = prev) + { + prev = block->Prev(); + + // Only consider rarely-run blocks in try regions. + // If we have such a block that is also part of an exception handler, don't bother moving it. + // Finally, don't move block if it is the beginning of a call-finally pair, + // as we want to keep these pairs contiguous + // (if we encounter the end of a pair below, we'll move the whole pair). + // + if (!block->hasTryIndex() || !block->isRunRarely() || block->hasHndIndex() || block->isBBCallFinallyPair()) + { + continue; + } + + const unsigned tryIndex = block->getTryIndex(); + EHblkDsc* const HBtab = ehGetDsc(tryIndex); + + // Don't move the beginning of a try region. + // Also, if this try region's entry is cold, don't bother moving its blocks. + // + if ((HBtab->ebdTryBeg == block) || (HBtab->ebdTryBeg->isRunRarely())) + { + continue; + } + + BasicBlock* const insertionPoint = tryRegionEnds[tryIndex]; + assert(insertionPoint != nullptr); + + // Don't move the end of this try region + // + if (block == insertionPoint) + { + continue; + } + + fgUnlinkBlock(block); + fgInsertBBafter(insertionPoint, block); + + // Keep call-finally pairs contiguous + // + if (block->KindIs(BBJ_CALLFINALLYRET)) + { + BasicBlock* const callFinally = prev; + prev = prev->Prev(); + assert(callFinally->KindIs(BBJ_CALLFINALLY)); + assert(!callFinally->HasFlag(BBF_RETLESS_CALL)); + fgUnlinkBlock(callFinally); + fgInsertBBafter(insertionPoint, callFinally); + } + } + + // Before updating EH descriptors, find the new try region ends + // + for (unsigned XTnum = 0; XTnum < compHndBBtabCount; XTnum++) + { + BasicBlock* const tryEnd = tryRegionEnds[XTnum]; + + // This try region isn't in the main method body + // + if (tryEnd == nullptr) + { + continue; + } + + // If we moved cold blocks to the end of this try region, + // search for the new end block + // + BasicBlock* newTryEnd = tryEnd; + for (BasicBlock* const block : Blocks(tryEnd, fgLastBBInMainFunction())) + { + if (!BasicBlock::sameTryRegion(tryEnd, block)) + { + break; + } + + newTryEnd = block; + } + + // We moved cold blocks to the end of this try region, but the old end block is cold, too. + // Move the old end block to the end of the region to preserve its relative ordering. + // + if ((tryEnd != newTryEnd) && tryEnd->isRunRarely() && !tryEnd->hasHndIndex()) + { + BasicBlock* const prev = tryEnd->Prev(); + fgUnlinkBlock(tryEnd); + fgInsertBBafter(newTryEnd, tryEnd); + + // Keep call-finally pairs contiguous + // + if (tryEnd->KindIs(BBJ_CALLFINALLYRET)) + { + assert(prev->KindIs(BBJ_CALLFINALLY)); + assert(!prev->HasFlag(BBF_RETLESS_CALL)); + fgUnlinkBlock(prev); + fgInsertBBafter(newTryEnd, prev); + } + } + else + { + // Otherwise, just update the try region end + // + tryRegionEnds[XTnum] = newTryEnd; + } + } + + // Now, update EH descriptors + // + auto getTryLast = [tryRegionEnds](const unsigned index) -> BasicBlock* { + return tryRegionEnds[index]; + }; + + auto setTryLast = [tryRegionEnds](const unsigned index, BasicBlock* const block) { + tryRegionEnds[index] = block; + }; + + ehUpdateTryLasts(getTryLast, setTryLast); +} + +//------------------------------------------------------------- +// ehUpdateTryLasts: Iterates EH descriptors, updating each try region's +// end block as determined by getTryLast. +// +// Type parameters: +// GetTryLast - Functor type that takes an EH index, +// and returns the corresponding region's new try end block +// SetTryLast - Functor type that takes an EH index and a BasicBlock*, +// and updates some internal state tracking the new try end block of each EH region +// +// Parameters: +// getTryLast - Functor to get new try end block for an EH region +// setTryLast - Functor to update the new try end block for an EH region +// +template +void Compiler::ehUpdateTryLasts(GetTryLast getTryLast, SetTryLast setTryLast) +{ + unsigned XTnum = 0; + for (EHblkDsc* const HBtab : EHClauses(this)) + { + BasicBlock* const tryEnd = getTryLast(XTnum++); + + if (tryEnd == nullptr) + { + continue; + } + + // Update the end pointer of this try region to the new last block + // + HBtab->ebdTryLast = tryEnd; + const unsigned enclosingTryIndex = HBtab->ebdEnclosingTryIndex; + + // If this try region is nested in another one, we might need to update its enclosing region's end block + // + if (enclosingTryIndex != EHblkDsc::NO_ENCLOSING_INDEX) + { + BasicBlock* const enclosingTryEnd = getTryLast(enclosingTryIndex); + + // If multiple EH descriptors map to the same try region, + // then the enclosing region's last block might be null in the table, so set it here. + // Similarly, if the enclosing region ends right before the nested region begins, + // extend the enclosing region's last block to the end of the nested region. + // + if ((enclosingTryEnd == nullptr) || enclosingTryEnd->NextIs(HBtab->ebdTryBeg)) + { + setTryLast(enclosingTryIndex, tryEnd); + } + } + } +} + //------------------------------------------------------------- // fgUpdateFlowGraphPhase: run flow graph optimization as a // phase, with no tail duplication diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp index 79cd63e3ac3b51..1afd6bcda76316 100644 --- a/src/coreclr/jit/fgprofile.cpp +++ b/src/coreclr/jit/fgprofile.cpp @@ -18,26 +18,15 @@ // true if so // // Note: -// This now returns true for inlinees. We might consider preserving the -// old behavior for crossgen, since crossgen BBINSTRs still do inlining -// and don't instrument the inlinees. +// In most cases it is more appropriate to call fgHaveProfileWeights, +// since that tells you if blocks have profile-based weights. // -// Thus if BBINSTR and BBOPT do the same inlines (which can happen) -// profile data for an inlinee (if available) will not fully reflect -// the behavior of the inlinee when called from this method. +// This method literally checks if the runtime had a profile schema, +// from which we can derive weights. // -// If this inlinee was not inlined by the BBINSTR run then the -// profile data for the inlinee will reflect this method's influence. -// -// * for ALWAYS_INLINE and FORCE_INLINE cases it is unlikely we'll find -// any profile data, as BBINSTR and BBOPT callers will both inline; -// only indirect callers will invoke the instrumented version to run. -// * for DISCRETIONARY_INLINE cases we may or may not find relevant -// data, depending, but chances are the data is relevant. -// -// TieredPGO data comes from Tier0 methods, which currently do not do -// any inlining; thus inlinee profile data should be available and -// representative. +// Schema-based data comes from Tier0 methods, which currently do not do +// any inlining; thus inlinee profile data should be available and +// representative. // bool Compiler::fgHaveProfileData() { @@ -47,6 +36,9 @@ bool Compiler::fgHaveProfileData() //------------------------------------------------------------------------ // fgHaveProfileWeights: Check if we have a profile that has weights. // +// Notes: +// These weights may come from instrumentation or from synthesis. +// bool Compiler::fgHaveProfileWeights() { return fgPgoHaveWeights; @@ -149,22 +141,39 @@ void Compiler::fgApplyProfileScale() JITDUMP(" ... no callee profile data, will use non-pgo weight to scale\n"); } - // Ostensibly this should be fgCalledCount for the callee, but that's not available - // as it requires some analysis. + // Determine the weight of the first block preds, if any. + // (only happens if the first block is a loop head). // - // For most callees it will be the same as the entry block count. - // - // Note when/if we early do normalization this may need to change. + weight_t firstBlockPredWeight = 0; + for (FlowEdge* const firstBlockPred : fgFirstBB->PredEdges()) + { + firstBlockPredWeight += firstBlockPred->getLikelyWeight(); + } + + // Determine the "input" weight for the callee // weight_t calleeWeight = fgFirstBB->bbWeight; - // Callee entry weight is nonzero? + // Callee entry weight is zero or negative (taking backedges into account)? // If so, just choose the smallest plausible weight. // - if (calleeWeight == BB_ZERO_WEIGHT) + if (calleeWeight <= firstBlockPredWeight) { calleeWeight = fgHaveProfileWeights() ? 1.0 : BB_UNITY_WEIGHT; - JITDUMP(" ... callee entry has weight zero, will use weight of " FMT_WT " to scale\n", calleeWeight); + JITDUMP(" ... callee entry has zero or negative weight, will use weight of " FMT_WT " to scale\n", + calleeWeight); + JITDUMP("Profile data could not be scaled consistently. Data %s inconsistent.\n", + fgPgoConsistent ? "is now" : "was already"); + + if (fgPgoConsistent) + { + Metrics.ProfileInconsistentInlineeScale++; + fgPgoConsistent = false; + } + } + else + { + calleeWeight -= firstBlockPredWeight; } // Call site has profile weight? @@ -1689,16 +1698,42 @@ void EfficientEdgeCountInstrumentor::RelocateProbes() { BasicBlock* intermediary = m_comp->fgNewBBbefore(BBJ_ALWAYS, block, /* extendRegion */ true); intermediary->SetFlags(BBF_IMPORTED); - intermediary->inheritWeight(block); FlowEdge* const newEdge = m_comp->fgAddRefPred(block, intermediary); intermediary->SetTargetEdge(newEdge); NewRelocatedProbe(intermediary, probe->source, probe->target, &leader); SetModifiedFlow(); + // Redirect flow and figure out profile impact. + // + // We don't expect to see mixtures of profiled and unprofiled preds, + // but if we do, fall back to our old default behavior. + // + weight_t weight = 0; + bool allPredsHaveProfile = true; + while (criticalPreds.Height() > 0) { BasicBlock* const pred = criticalPreds.Pop(); m_comp->fgReplaceJumpTarget(pred, block, intermediary); + + if (pred->hasProfileWeight()) + { + FlowEdge* const predIntermediaryEdge = m_comp->fgGetPredForBlock(intermediary, pred); + weight += predIntermediaryEdge->getLikelyWeight(); + } + else + { + allPredsHaveProfile = false; + } + } + + if (allPredsHaveProfile) + { + intermediary->setBBProfileWeight(weight); + } + else + { + intermediary->inheritWeight(block); } } } @@ -2811,6 +2846,14 @@ PhaseStatus Compiler::fgInstrumentMethod() // PhaseStatus Compiler::fgIncorporateProfileData() { + // For now we only rely on profile data when optimizing. + // + if (!opts.OptimizationEnabled()) + { + JITDUMP("not optimizing, so not incorporating any profile data\n"); + return PhaseStatus::MODIFIED_NOTHING; + } + // Are we doing profile stress? // if (fgStressBBProf() > 0) @@ -2822,6 +2865,14 @@ PhaseStatus Compiler::fgIncorporateProfileData() return PhaseStatus::MODIFIED_EVERYTHING; } + // For now we only rely on profile data when optimizing. + // + if (!opts.OptimizationEnabled()) + { + JITDUMP("not optimizing, so not incorporating any profile data\n"); + return PhaseStatus::MODIFIED_NOTHING; + } + #ifdef DEBUG // Optionally run synthesis // @@ -2861,6 +2912,14 @@ PhaseStatus Compiler::fgIncorporateProfileData() JITDUMP("BBOPT not set\n"); } + // Is dynamic PGO active? If so, run synthesis. + // + if (fgPgoDynamic) + { + JITDUMP("Dynamic PGO active, synthesizing profile data\n"); + ProfileSynthesis::Run(this, ProfileSynthesisOption::AssignLikelihoods); + } + // Scale the "synthetic" block weights. // fgApplyProfileScale(); @@ -2992,21 +3051,10 @@ PhaseStatus Compiler::fgIncorporateProfileData() // // Notes: // Does inlinee scaling. -// Handles handler entry special case. // void Compiler::fgSetProfileWeight(BasicBlock* block, weight_t profileWeight) { block->setBBProfileWeight(profileWeight); - -#if HANDLER_ENTRY_MUST_BE_IN_HOT_SECTION - // Handle a special case -- some handler entries can't have zero profile count. - // - if (this->bbIsHandlerBeg(block) && block->isRunRarely()) - { - JITDUMP("Suppressing zero count for " FMT_BB " as it is a handler entry\n", block->bbNum); - block->makeBlockHot(); - } -#endif } //------------------------------------------------------------------------ @@ -4773,6 +4821,19 @@ bool Compiler::fgDebugCheckProfileWeights(ProfileChecks checks) verifyIncoming = false; } + // Original entries in OSR methods that also are + // loop headers. + // + // These will frequently have a profile imbalance as + // synthesis will have injected profile weight for + // method entry, but when we transform flow for OSR, + // only the loop back edges remain. + // + if (block == fgEntryBB) + { + verifyIncoming = false; + } + // Handler entries // if (block->hasEHBoundaryIn()) @@ -4935,6 +4996,15 @@ bool Compiler::fgDebugCheckIncomingProfileData(BasicBlock* block, ProfileChecks foundEHPreds = false; } + // We almost certainly won't get the likelihoods on a BBJ_EHFINALLYRET right, + // so special-case BBJ_CALLFINALLYRET incoming flow. + // + if (block->isBBCallFinallyPairTail()) + { + incomingLikelyWeight = block->Prev()->bbWeight; + foundEHPreds = false; + } + bool likelyWeightsValid = true; // If we have EH preds we may not have consistent incoming flow. diff --git a/src/coreclr/jit/fgprofilesynthesis.cpp b/src/coreclr/jit/fgprofilesynthesis.cpp index d7661e5b873fae..b9ff493c87d49f 100644 --- a/src/coreclr/jit/fgprofilesynthesis.cpp +++ b/src/coreclr/jit/fgprofilesynthesis.cpp @@ -146,9 +146,12 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option) m_comp->fgPgoSynthesized = true; m_comp->fgPgoConsistent = !m_approximate; + m_comp->Metrics.ProfileSynthesizedBlendedOrRepaired++; + if (m_approximate) { JITDUMP("Profile is inconsistent. Bypassing post-phase consistency checks.\n"); + m_comp->Metrics.ProfileInconsistentInitially++; } #ifdef DEBUG diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 6ab0977c55c252..151729b0950514 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -3083,17 +3083,12 @@ bool Compiler::fgFuncletsAreCold() // // Notes: // Walk the basic blocks list to determine the first block to place in the -// cold section. This would be the first of a series of rarely executed blocks +// cold section. This would be the first of a series of rarely executed blocks // such that no succeeding blocks are in a try region or an exception handler // or are rarely executed. // PhaseStatus Compiler::fgDetermineFirstColdBlock() { - // Since we may need to create a new transition block - // we assert that it is OK to create new blocks. - // - assert(fgPredsComputed); - assert(fgSafeBasicBlockCreation); assert(fgFirstColdBlock == nullptr); if (!opts.compProcedureSplitting) @@ -3134,15 +3129,6 @@ PhaseStatus Compiler::fgDetermineFirstColdBlock() for (lblk = nullptr, block = fgFirstBB; block != nullptr; lblk = block, block = block->Next()) { - bool blockMustBeInHotSection = false; - -#if HANDLER_ENTRY_MUST_BE_IN_HOT_SECTION - if (bbIsHandlerBeg(block)) - { - blockMustBeInHotSection = true; - } -#endif // HANDLER_ENTRY_MUST_BE_IN_HOT_SECTION - // Make note of if we're in the funclet section, // so we can stop the search early. if (block == fgFirstFuncletBB) @@ -3156,7 +3142,7 @@ PhaseStatus Compiler::fgDetermineFirstColdBlock() // We have a candidate for first cold block // Is this a hot block? - if (blockMustBeInHotSection || (block->isRunRarely() == false)) + if (!block->isRunRarely()) { // We have to restart the search for the first cold block firstColdBlock = nullptr; @@ -3195,7 +3181,7 @@ PhaseStatus Compiler::fgDetermineFirstColdBlock() } // Is this a cold block? - if (!blockMustBeInHotSection && block->isRunRarely()) + if (block->isRunRarely()) { // // If the last block that was hot was a BBJ_COND @@ -4043,8 +4029,8 @@ bool FlowGraphDfsTree::Contains(BasicBlock* block) const // block `descendant` // // Arguments: -// ancestor -- block that is possible ancestor -// descendant -- block that is possible descendant +// ancestor - block that is possible ancestor +// descendant - block that is possible descendant // // Returns: // True if `ancestor` is ancestor of `descendant` in the depth first spanning @@ -4063,6 +4049,9 @@ bool FlowGraphDfsTree::IsAncestor(BasicBlock* ancestor, BasicBlock* descendant) //------------------------------------------------------------------------ // fgComputeDfs: Compute a depth-first search tree for the flow graph. // +// Type parameters: +// useProfile - If true, determines order of successors visited using profile data +// // Returns: // The tree. // @@ -4070,6 +4059,7 @@ bool FlowGraphDfsTree::IsAncestor(BasicBlock* ancestor, BasicBlock* descendant) // Preorder and postorder numbers are assigned into the BasicBlock structure. // The tree returned contains a postorder of the basic blocks. // +template FlowGraphDfsTree* Compiler::fgComputeDfs() { BasicBlock** postOrder = new (this, CMK_DepthFirstSearch) BasicBlock*[fgBBcount]; @@ -4095,10 +4085,17 @@ FlowGraphDfsTree* Compiler::fgComputeDfs() } }; - unsigned numBlocks = fgRunDfs(visitPreorder, visitPostorder, visitEdge); + unsigned numBlocks = + fgRunDfs(visitPreorder, + visitPostorder, + visitEdge); return new (this, CMK_DepthFirstSearch) FlowGraphDfsTree(this, postOrder, numBlocks, hasCycle); } +// Add explicit instantiations. +template FlowGraphDfsTree* Compiler::fgComputeDfs(); +template FlowGraphDfsTree* Compiler::fgComputeDfs(); + //------------------------------------------------------------------------ // fgInvalidateDfsTree: Invalidate computed DFS tree and dependent annotations // (like loops, dominators and SSA). @@ -5569,7 +5566,7 @@ bool FlowGraphNaturalLoop::InitBlockEntersLoopOnTrue(BasicBlock* initBlock) // the loop. // // Returns: -// Block with highest bbNum. +// First block in block order contained in the loop. // // Remarks: // Mostly exists as a quirk while transitioning from the old loop @@ -5577,12 +5574,13 @@ bool FlowGraphNaturalLoop::InitBlockEntersLoopOnTrue(BasicBlock* initBlock) // BasicBlock* FlowGraphNaturalLoop::GetLexicallyTopMostBlock() { - BasicBlock* top = m_header; - VisitLoopBlocks([&top](BasicBlock* loopBlock) { - if (loopBlock->bbNum < top->bbNum) - top = loopBlock; - return BasicBlockVisit::Continue; - }); + BasicBlock* top = m_dfsTree->GetCompiler()->fgFirstBB; + + while (!ContainsBlock(top)) + { + top = top->Next(); + assert(top != nullptr); + } return top; } @@ -5592,7 +5590,7 @@ BasicBlock* FlowGraphNaturalLoop::GetLexicallyTopMostBlock() // within the loop. // // Returns: -// Block with highest bbNum. +// Last block in block order contained in the loop. // // Remarks: // Mostly exists as a quirk while transitioning from the old loop @@ -5600,12 +5598,13 @@ BasicBlock* FlowGraphNaturalLoop::GetLexicallyTopMostBlock() // BasicBlock* FlowGraphNaturalLoop::GetLexicallyBottomMostBlock() { - BasicBlock* bottom = m_header; - VisitLoopBlocks([&bottom](BasicBlock* loopBlock) { - if (loopBlock->bbNum > bottom->bbNum) - bottom = loopBlock; - return BasicBlockVisit::Continue; - }); + BasicBlock* bottom = m_dfsTree->GetCompiler()->fgLastBB; + + while (!ContainsBlock(bottom)) + { + bottom = bottom->Prev(); + assert(bottom != nullptr); + } return bottom; } diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 878c02ac1603df..d48fc45868ba22 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -9782,7 +9782,6 @@ GenTree* Compiler::gtCloneExpr(GenTree* tree) /* Make sure to copy back fields that may have been initialized */ copy->CopyRawCosts(tree); - copy->gtRsvdRegs = tree->gtRsvdRegs; copy->CopyReg(tree); return copy; } @@ -11644,7 +11643,7 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_ if (verbose && 0) { printf(" RR="); - dspRegMask(tree->gtRsvdRegs); + dspRegMask(JitTls::GetCompiler()->codeGen->internalRegisters.GetAll(tree)); printf("\n"); } } @@ -18012,7 +18011,7 @@ bool GenTree::canBeContained() const } else if (OperIsHWIntrinsic() && !isContainableHWIntrinsic()) { - return isEvexEmbeddedMaskingCompatibleHWIntrinsic(); + return isEmbeddedMaskingCompatibleHWIntrinsic(); } return true; @@ -19909,24 +19908,26 @@ bool GenTree::isEvexCompatibleHWIntrinsic() const } //------------------------------------------------------------------------ -// isEvexEmbeddedMaskingCompatibleHWIntrinsic: Checks if the intrinsic is compatible +// isEmbeddedMaskingCompatibleHWIntrinsic : Checks if the intrinsic is compatible // with the EVEX embedded masking form for its intended lowering instruction. // // Return Value: // true if the intrisic node lowering instruction has an EVEX embedded masking // -bool GenTree::isEvexEmbeddedMaskingCompatibleHWIntrinsic() const +bool GenTree::isEmbeddedMaskingCompatibleHWIntrinsic() const { -#if defined(TARGET_XARCH) if (OperIsHWIntrinsic()) { +#if defined(TARGET_XARCH) // TODO-AVX512F-CQ: Expand this to the full set of APIs and make it table driven // using IsEmbMaskingCompatible. For now, however, limit it to some explicit ids // for prototyping purposes. return (AsHWIntrinsic()->GetHWIntrinsicId() == NI_AVX512F_Add); +#elif defined(TARGET_ARM64) + return HWIntrinsicInfo::IsEmbeddedMaskedOperation(AsHWIntrinsic()->GetHWIntrinsicId()) || + HWIntrinsicInfo::IsOptionalEmbeddedMaskedOperation(AsHWIntrinsic()->GetHWIntrinsicId()); +#endif } -#endif // TARGET_XARCH - return false; } @@ -21350,7 +21351,6 @@ GenTree* Compiler::gtNewSimdCeilNode(var_types type, GenTree* op1, CorInfoType s return gtNewSimdHWIntrinsicNode(type, op1, intrinsic, simdBaseJitType, simdSize); } -#if defined(TARGET_XARCH) GenTree* Compiler::gtNewSimdCvtNode(var_types type, GenTree* op1, CorInfoType simdTargetBaseJitType, @@ -21368,12 +21368,128 @@ GenTree* Compiler::gtNewSimdCvtNode(var_types type, assert(varTypeIsIntegral(simdTargetBaseType)); assert(IsBaselineSimdIsaSupportedDebugOnly()); + +#if defined(TARGET_XARCH) assert(IsBaselineVector512IsaSupportedDebugOnly() || ((simdTargetBaseType == TYP_INT) && ((simdSize == 16 && compIsaSupportedDebugOnly(InstructionSet_SSE41)) || (simdSize == 32 && compIsaSupportedDebugOnly(InstructionSet_AVX))))); + GenTree* fixupVal; + + if (IsBaselineVector512IsaSupportedOpportunistically()) + { + /*Generate the control table for VFIXUPIMMSD/SS + - For conversion to unsigned + // QNAN: 0b1000: Saturate to Zero + // SNAN: 0b1000: Saturate to Zero + // ZERO: 0b0000 + // +ONE: 0b0000 + // -INF: 0b1000: Saturate to Zero + // +INF: 0b0000 + // -VAL: 0b1000: Saturate to Zero + // +VAL: 0b0000 + - For conversion to signed + // QNAN: 0b1000: Saturate to Zero + // SNAN: 0b1000: Saturate to Zero + // ZERO: 0b0000 + // +ONE: 0b0000 + // -INF: 0b0000 + // +INF: 0b0000 + // -VAL: 0b0000 + // +VAL: 0b0000 + */ + int32_t iconVal = varTypeIsUnsigned(simdTargetBaseType) ? 0x08080088 : 0x00000088; + GenTree* tblCon = gtNewSimdCreateBroadcastNode(type, gtNewIconNode(iconVal), simdTargetBaseJitType, simdSize); + + // We need op1Clone to run fixup + GenTree* op1Clone = fgMakeMultiUse(&op1); + + // run vfixupimmsd base on table and no flags reporting + fixupVal = gtNewSimdHWIntrinsicNode(type, op1, op1Clone, tblCon, gtNewIconNode(0), NI_AVX512F_Fixup, + simdSourceBaseJitType, simdSize); + } + else + { + // Zero out NaN values from the input. + // mask1 contains the output either 0xFFFFFFFF or 0. + // FixupVal zeros out any NaN values in the input by ANDing input with mask1. + GenTree* op1Clone1 = fgMakeMultiUse(&op1); + GenTree* op1Clone2 = fgMakeMultiUse(&op1); + GenTree* mask1 = gtNewSimdCmpOpNode(GT_EQ, type, op1, op1Clone1, simdSourceBaseJitType, simdSize); + fixupVal = gtNewSimdBinOpNode(GT_AND, type, op1Clone2, mask1, simdSourceBaseJitType, simdSize); + } + + if (varTypeIsSigned(simdTargetBaseType)) + { + GenTree* maxVal; + GenTree* maxValDup; + if (varTypeIsLong(simdTargetBaseType)) + { + int64_t actualMaxVal = INT64_MAX; + maxVal = gtNewDconNode(static_cast(actualMaxVal), simdSourceBaseType); + maxVal = gtNewSimdCreateBroadcastNode(type, maxVal, simdSourceBaseJitType, simdSize); + maxValDup = + gtNewSimdCreateBroadcastNode(type, gtNewLconNode(actualMaxVal), simdTargetBaseJitType, simdSize); + } + else + { + ssize_t actualMaxVal = INT32_MAX; + maxVal = gtNewDconNode(static_cast(actualMaxVal), simdSourceBaseType); + maxVal = gtNewSimdCreateBroadcastNode(type, maxVal, simdSourceBaseJitType, simdSize); + maxValDup = + gtNewSimdCreateBroadcastNode(type, gtNewIconNode(actualMaxVal), simdTargetBaseJitType, simdSize); + } + + // we will be using the input value twice + GenTree* fixupValDup = fgMakeMultiUse(&fixupVal); + + // compare with max value of integer/long + fixupVal = gtNewSimdCmpOpNode(GT_GE, type, fixupVal, maxVal, simdSourceBaseJitType, simdSize); + + // cast it + GenTree* castNode = + gtNewSimdCvtNativeNode(type, fixupValDup, simdTargetBaseJitType, simdSourceBaseJitType, simdSize); + + // use the fixupVal mask with input value and max value to blend + return gtNewSimdCndSelNode(type, fixupVal, maxValDup, castNode, simdTargetBaseJitType, simdSize); + } + else + { + return gtNewSimdCvtNativeNode(type, fixupVal, simdTargetBaseJitType, simdSourceBaseJitType, simdSize); + } +#elif defined(TARGET_ARM64) + return gtNewSimdCvtNativeNode(type, op1, simdTargetBaseJitType, simdSourceBaseJitType, simdSize); +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 +} + +GenTree* Compiler::gtNewSimdCvtNativeNode(var_types type, + GenTree* op1, + CorInfoType simdTargetBaseJitType, + CorInfoType simdSourceBaseJitType, + unsigned simdSize) +{ + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + var_types simdSourceBaseType = JitType2PreciseVarType(simdSourceBaseJitType); + var_types simdTargetBaseType = JitType2PreciseVarType(simdTargetBaseJitType); + assert(varTypeIsFloating(simdSourceBaseType)); + assert(varTypeIsIntegral(simdTargetBaseType)); + + assert(IsBaselineSimdIsaSupportedDebugOnly()); + // Generate intrinsic needed for conversion NamedIntrinsic hwIntrinsicID = NI_Illegal; + +#if defined(TARGET_XARCH) + assert(IsBaselineVector512IsaSupportedDebugOnly() || + ((simdTargetBaseType == TYP_INT) && + ((simdSize == 16) || (simdSize == 32 && compIsaSupportedDebugOnly(InstructionSet_AVX))))); + switch (simdSourceBaseJitType) { case CORINFO_TYPE_FLOAT: @@ -21389,21 +21505,25 @@ GenTree* Compiler::gtNewSimdCvtNode(var_types type, hwIntrinsicID = NI_AVX512F_ConvertToVector512Int32WithTruncation; break; } + case 32: { hwIntrinsicID = NI_AVX_ConvertToVector256Int32WithTruncation; break; } + case 16: { hwIntrinsicID = NI_SSE2_ConvertToVector128Int32WithTruncation; break; } + default: unreached(); } break; } + case CORINFO_TYPE_UINT: { switch (simdSize) @@ -21413,26 +21533,31 @@ GenTree* Compiler::gtNewSimdCvtNode(var_types type, hwIntrinsicID = NI_AVX512F_ConvertToVector512UInt32WithTruncation; break; } + case 32: { hwIntrinsicID = NI_AVX512F_VL_ConvertToVector256UInt32WithTruncation; break; } + case 16: { hwIntrinsicID = NI_AVX512F_VL_ConvertToVector128UInt32WithTruncation; break; } + default: unreached(); } break; } + default: unreached(); } break; } + case CORINFO_TYPE_DOUBLE: { switch (simdTargetBaseJitType) @@ -21446,21 +21571,25 @@ GenTree* Compiler::gtNewSimdCvtNode(var_types type, hwIntrinsicID = NI_AVX512DQ_ConvertToVector512Int64WithTruncation; break; } + case 32: { hwIntrinsicID = NI_AVX512DQ_VL_ConvertToVector256Int64WithTruncation; break; } + case 16: { hwIntrinsicID = NI_AVX512DQ_VL_ConvertToVector128Int64WithTruncation; break; } + default: unreached(); } break; } + case CORINFO_TYPE_ULONG: { switch (simdSize) @@ -21470,115 +21599,95 @@ GenTree* Compiler::gtNewSimdCvtNode(var_types type, hwIntrinsicID = NI_AVX512DQ_ConvertToVector512UInt64WithTruncation; break; } + case 32: { hwIntrinsicID = NI_AVX512DQ_VL_ConvertToVector256UInt64WithTruncation; break; } + case 16: { hwIntrinsicID = NI_AVX512DQ_VL_ConvertToVector128UInt64WithTruncation; break; } + default: unreached(); } break; } + default: unreached(); } break; } + default: unreached(); } - assert(hwIntrinsicID != NI_Illegal); - - GenTree* fixupVal; +#elif defined(TARGET_ARM64) + assert((simdSize == 8) || (simdSize == 16)); - if (IsBaselineVector512IsaSupportedOpportunistically()) + switch (simdSourceBaseJitType) { - /*Generate the control table for VFIXUPIMMSD/SS - - For conversion to unsigned - // QNAN: 0b1000: Saturate to Zero - // SNAN: 0b1000: Saturate to Zero - // ZERO: 0b0000 - // +ONE: 0b0000 - // -INF: 0b1000: Saturate to Zero - // +INF: 0b0000 - // -VAL: 0b1000: Saturate to Zero - // +VAL: 0b0000 - - For conversion to signed - // QNAN: 0b1000: Saturate to Zero - // SNAN: 0b1000: Saturate to Zero - // ZERO: 0b0000 - // +ONE: 0b0000 - // -INF: 0b0000 - // +INF: 0b0000 - // -VAL: 0b0000 - // +VAL: 0b0000 - */ - int32_t iconVal = varTypeIsUnsigned(simdTargetBaseType) ? 0x08080088 : 0x00000088; - GenTree* tblCon = gtNewSimdCreateBroadcastNode(type, gtNewIconNode(iconVal), simdTargetBaseJitType, simdSize); - - // We need op1Clone to run fixup - GenTree* op1Clone = fgMakeMultiUse(&op1); + case CORINFO_TYPE_FLOAT: + { + switch (simdTargetBaseJitType) + { + case CORINFO_TYPE_INT: + { + hwIntrinsicID = NI_AdvSimd_ConvertToInt32RoundToZero; + break; + } - // run vfixupimmsd base on table and no flags reporting - fixupVal = gtNewSimdHWIntrinsicNode(type, op1, op1Clone, tblCon, gtNewIconNode(0), NI_AVX512F_Fixup, - simdSourceBaseJitType, simdSize); - } - else - { - // Zero out NaN values from the input. - // mask1 contains the output either 0xFFFFFFFF or 0. - // FixupVal zeros out any NaN values in the input by ANDing input with mask1. - GenTree* op1Clone1 = fgMakeMultiUse(&op1); - GenTree* op1Clone2 = fgMakeMultiUse(&op1); - GenTree* mask1 = gtNewSimdCmpOpNode(GT_EQ, type, op1, op1Clone1, simdSourceBaseJitType, simdSize); - fixupVal = gtNewSimdBinOpNode(GT_AND, type, op1Clone2, mask1, simdSourceBaseJitType, simdSize); - } + case CORINFO_TYPE_UINT: + { + hwIntrinsicID = NI_AdvSimd_ConvertToUInt32RoundToZero; + break; + } - if (varTypeIsSigned(simdTargetBaseType)) - { - GenTree* maxVal; - GenTree* maxValDup; - if (varTypeIsLong(simdTargetBaseType)) - { - int64_t actualMaxVal = INT64_MAX; - maxVal = gtNewDconNode(static_cast(actualMaxVal), simdSourceBaseType); - maxVal = gtNewSimdCreateBroadcastNode(type, maxVal, simdSourceBaseJitType, simdSize); - maxValDup = - gtNewSimdCreateBroadcastNode(type, gtNewLconNode(actualMaxVal), simdTargetBaseJitType, simdSize); - } - else - { - ssize_t actualMaxVal = INT32_MAX; - maxVal = gtNewDconNode(static_cast(actualMaxVal), simdSourceBaseType); - maxVal = gtNewSimdCreateBroadcastNode(type, maxVal, simdSourceBaseJitType, simdSize); - maxValDup = - gtNewSimdCreateBroadcastNode(type, gtNewIconNode(actualMaxVal), simdTargetBaseJitType, simdSize); + default: + unreached(); + } + break; } - // we will be using the input value twice - GenTree* fixupValDup = fgMakeMultiUse(&fixupVal); + case CORINFO_TYPE_DOUBLE: + { + switch (simdTargetBaseJitType) + { + case CORINFO_TYPE_LONG: + { + hwIntrinsicID = (simdSize == 8) ? NI_AdvSimd_Arm64_ConvertToInt64RoundToZeroScalar + : NI_AdvSimd_Arm64_ConvertToInt64RoundToZero; + break; + } - // compare with max value of integer/long - fixupVal = gtNewSimdCmpOpNode(GT_GE, type, fixupVal, maxVal, simdSourceBaseJitType, simdSize); + case CORINFO_TYPE_ULONG: + { + hwIntrinsicID = (simdSize == 8) ? NI_AdvSimd_Arm64_ConvertToUInt64RoundToZeroScalar + : NI_AdvSimd_Arm64_ConvertToUInt64RoundToZero; + break; + } - // cast it - GenTree* castNode = gtNewSimdHWIntrinsicNode(type, fixupValDup, hwIntrinsicID, simdSourceBaseJitType, simdSize); + default: + unreached(); + } + break; + } - // use the fixupVal mask with input value and max value to blend - return gtNewSimdCndSelNode(type, fixupVal, maxValDup, castNode, simdTargetBaseJitType, simdSize); - } - else - { - return gtNewSimdHWIntrinsicNode(type, fixupVal, hwIntrinsicID, simdSourceBaseJitType, simdSize); + default: + unreached(); } +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 + + assert(hwIntrinsicID != NI_Illegal); + return gtNewSimdHWIntrinsicNode(type, op1, hwIntrinsicID, simdSourceBaseJitType, simdSize); } -#endif // TARGET_XARCH GenTree* Compiler::gtNewSimdCmpOpNode( genTreeOps op, var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize) @@ -26398,6 +26507,30 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const break; case NI_Sve_LoadVector: + case NI_Sve_LoadVectorByteZeroExtendToInt16: + case NI_Sve_LoadVectorByteZeroExtendToInt32: + case NI_Sve_LoadVectorByteZeroExtendToInt64: + case NI_Sve_LoadVectorByteZeroExtendToUInt16: + case NI_Sve_LoadVectorByteZeroExtendToUInt32: + case NI_Sve_LoadVectorByteZeroExtendToUInt64: + case NI_Sve_LoadVectorInt16SignExtendToInt32: + case NI_Sve_LoadVectorInt16SignExtendToInt64: + case NI_Sve_LoadVectorInt16SignExtendToUInt32: + case NI_Sve_LoadVectorInt16SignExtendToUInt64: + case NI_Sve_LoadVectorInt32SignExtendToInt64: + case NI_Sve_LoadVectorInt32SignExtendToUInt64: + case NI_Sve_LoadVectorSByteSignExtendToInt16: + case NI_Sve_LoadVectorSByteSignExtendToInt32: + case NI_Sve_LoadVectorSByteSignExtendToInt64: + case NI_Sve_LoadVectorSByteSignExtendToUInt16: + case NI_Sve_LoadVectorSByteSignExtendToUInt32: + case NI_Sve_LoadVectorSByteSignExtendToUInt64: + case NI_Sve_LoadVectorUInt16ZeroExtendToInt32: + case NI_Sve_LoadVectorUInt16ZeroExtendToInt64: + case NI_Sve_LoadVectorUInt16ZeroExtendToUInt32: + case NI_Sve_LoadVectorUInt16ZeroExtendToUInt64: + case NI_Sve_LoadVectorUInt32ZeroExtendToInt64: + case NI_Sve_LoadVectorUInt32ZeroExtendToUInt64: addr = Op(2); break; #endif // TARGET_ARM64 @@ -27586,75 +27719,14 @@ regMaskTP ReturnTypeDesc::GetABIReturnRegs(CorInfoCallConvExtension callConv) co } //------------------------------------------------------------------------ -// The following functions manage the gtRsvdRegs set of temporary registers -// created by LSRA during code generation. - -//------------------------------------------------------------------------ -// AvailableTempRegCount: return the number of available temporary registers in the (optional) given set -// (typically, RBM_ALLINT or RBM_ALLFLOAT). -// -// Arguments: -// mask - (optional) Check for available temporary registers only in this set. -// -// Return Value: -// Count of available temporary registers in given set. -// -unsigned GenTree::AvailableTempRegCount(regMaskTP mask /* = (regMaskTP)-1 */) const -{ - return genCountBits(gtRsvdRegs & mask); -} - -//------------------------------------------------------------------------ -// GetSingleTempReg: There is expected to be exactly one available temporary register -// in the given mask in the gtRsvdRegs set. Get that register. No future calls to get -// a temporary register are expected. Removes the register from the set, but only in -// DEBUG to avoid doing unnecessary work in non-DEBUG builds. +// GetNum: Get the SSA number for a given field. // -// Arguments: -// mask - (optional) Get an available temporary register only in this set. -// -// Return Value: -// Available temporary register in given mask. -// -regNumber GenTree::GetSingleTempReg(regMaskTP mask /* = (regMaskTP)-1 */) -{ - regMaskTP availableSet = gtRsvdRegs & mask; - assert(genCountBits(availableSet) == 1); - regNumber tempReg = genRegNumFromMask(availableSet); - INDEBUG(gtRsvdRegs &= ~availableSet;) // Remove the register from the set, so it can't be used again. - return tempReg; -} - -//------------------------------------------------------------------------ -// ExtractTempReg: Find the lowest number temporary register from the gtRsvdRegs set -// that is also in the optional given mask (typically, RBM_ALLINT or RBM_ALLFLOAT), -// and return it. Remove this register from the temporary register set, so it won't -// be returned again. -// -// Arguments: -// mask - (optional) Extract an available temporary register only in this set. -// -// Return Value: -// Available temporary register in given mask. -// -regNumber GenTree::ExtractTempReg(regMaskTP mask /* = (regMaskTP)-1 */) -{ - regMaskTP availableSet = gtRsvdRegs & mask; - assert(genCountBits(availableSet) >= 1); - regNumber tempReg = genFirstRegNumFromMask(availableSet); - gtRsvdRegs ^= genRegMask(tempReg); - return tempReg; -} - -//------------------------------------------------------------------------ -// GetNum: Get the SSA number for a given field. -// -// Arguments: -// compiler - The Compiler instance -// index - The field index +// Arguments: +// compiler - The Compiler instance +// index - The field index // -// Return Value: -// The SSA number corresponding to the field at "index". +// Return Value: +// The SSA number corresponding to the field at "index". // unsigned SsaNumInfo::GetNum(Compiler* compiler, unsigned index) const { diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index c6369121809520..7dbfef174994e6 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -557,9 +557,9 @@ enum GenTreeFlags : unsigned int GTF_MDARRLOWERBOUND_NONFAULTING = 0x20000000, // GT_MDARR_LOWER_BOUND -- An MD array lower bound operation that cannot fault. Same as GT_IND_NONFAULTING. -#if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) +#ifdef FEATURE_HW_INTRINSICS GTF_HW_EM_OP = 0x10000000, // GT_HWINTRINSIC -- node is used as an operand to an embedded mask -#endif // TARGET_XARCH && FEATURE_HW_INTRINSICS +#endif // FEATURE_HW_INTRINSICS }; inline constexpr GenTreeFlags operator ~(GenTreeFlags a) @@ -956,12 +956,6 @@ struct GenTree ValueNumPair gtVNPair; - regMaskSmall gtRsvdRegs; // set of fixed trashed registers - - unsigned AvailableTempRegCount(regMaskTP mask = (regMaskTP)-1) const; - regNumber GetSingleTempReg(regMaskTP mask = (regMaskTP)-1); - regNumber ExtractTempReg(regMaskTP mask = (regMaskTP)-1); - void SetVNsFromNode(GenTree* tree) { gtVNPair = tree->gtVNPair; @@ -1465,7 +1459,7 @@ struct GenTree bool isContainableHWIntrinsic() const; bool isRMWHWIntrinsic(Compiler* comp); bool isEvexCompatibleHWIntrinsic() const; - bool isEvexEmbeddedMaskingCompatibleHWIntrinsic() const; + bool isEmbeddedMaskingCompatibleHWIntrinsic() const; #else bool isCommutativeHWIntrinsic() const { @@ -1487,7 +1481,7 @@ struct GenTree return false; } - bool isEvexEmbeddedMaskingCompatibleHWIntrinsic() const + bool isEmbeddedMaskingCompatibleHWIntrinsic() const { return false; } @@ -1770,6 +1764,7 @@ struct GenTree inline bool IsVectorZero() const; inline bool IsVectorCreate() const; inline bool IsVectorAllBitsSet() const; + inline bool IsMaskAllBitsSet() const; inline bool IsVectorConst(); inline uint64_t GetIntegralVectorConstElement(size_t index, var_types simdBaseType); @@ -2226,7 +2221,7 @@ struct GenTree gtFlags &= ~GTF_ICON_HDL_MASK; } -#if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) +#ifdef FEATURE_HW_INTRINSICS bool IsEmbMaskOp() { @@ -2240,7 +2235,7 @@ struct GenTree gtFlags |= GTF_HW_EM_OP; } -#endif // TARGET_XARCH && FEATURE_HW_INTRINSICS +#endif // FEATURE_HW_INTRINSICS static bool HandleKindDataIsInvariant(GenTreeFlags flags); @@ -9238,6 +9233,32 @@ inline bool GenTree::IsVectorAllBitsSet() const return false; } +inline bool GenTree::IsMaskAllBitsSet() const +{ +#ifdef TARGET_ARM64 + static_assert_no_msg(AreContiguous(NI_Sve_CreateTrueMaskByte, NI_Sve_CreateTrueMaskDouble, + NI_Sve_CreateTrueMaskInt16, NI_Sve_CreateTrueMaskInt32, + NI_Sve_CreateTrueMaskInt64, NI_Sve_CreateTrueMaskSByte, + NI_Sve_CreateTrueMaskSingle, NI_Sve_CreateTrueMaskUInt16, + NI_Sve_CreateTrueMaskUInt32, NI_Sve_CreateTrueMaskUInt64)); + + if (OperIsHWIntrinsic()) + { + NamedIntrinsic id = AsHWIntrinsic()->GetHWIntrinsicId(); + if (id == NI_Sve_ConvertMaskToVector) + { + GenTree* op1 = AsHWIntrinsic()->Op(1); + assert(op1->OperIsHWIntrinsic()); + id = op1->AsHWIntrinsic()->GetHWIntrinsicId(); + } + return ((id == NI_Sve_CreateTrueMaskAll) || + ((id >= NI_Sve_CreateTrueMaskByte) && (id <= NI_Sve_CreateTrueMaskUInt64))); + } + +#endif + return false; +} + //------------------------------------------------------------------- // IsVectorConst: returns true if this node is a HWIntrinsic that represents a constant. // diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 17d6a6d4830077..b9dca67a1356c2 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -307,9 +307,8 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stm // null-check basic block GenTree* fastPathValue = gtNewIndir(TYP_I_IMPL, gtCloneExpr(slotPtrTree), GTF_IND_NONFAULTING); // Save dictionary slot to a local (to be used by fast path) - GenTree* fastPathValueClone = - opts.OptimizationEnabled() ? fgMakeMultiUse(&fastPathValue) : gtCloneExpr(fastPathValue); - GenTree* nullcheckOp = gtNewOperNode(GT_EQ, TYP_INT, fastPathValue, gtNewIconNode(0, TYP_I_IMPL)); + GenTree* fastPathValueClone = fgMakeMultiUse(&fastPathValue); + GenTree* nullcheckOp = gtNewOperNode(GT_EQ, TYP_INT, fastPathValue, gtNewIconNode(0, TYP_I_IMPL)); nullcheckOp->gtFlags |= GTF_RELOP_JMP_USED; // nullcheckBb conditionally jumps to fallbackBb, but we need to initialize fallbackBb last diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 53970ef4a7460b..3187c3e5c2e044 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1396,6 +1396,36 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, GenTree* op3 = nullptr; GenTree* op4 = nullptr; + switch (numArgs) + { + case 4: + op4 = getArgForHWIntrinsic(sigReader.GetOp4Type(), sigReader.op4ClsHnd); + op4 = addRangeCheckIfNeeded(intrinsic, op4, mustExpand, immLowerBound, immUpperBound); + op3 = getArgForHWIntrinsic(sigReader.GetOp3Type(), sigReader.op3ClsHnd); + op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); + op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); + break; + + case 3: + op3 = getArgForHWIntrinsic(sigReader.GetOp3Type(), sigReader.op3ClsHnd); + op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); + op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); + break; + + case 2: + op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); + op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand, immLowerBound, immUpperBound); + op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); + break; + + case 1: + op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); + break; + + default: + break; + } + switch (numArgs) { case 0: @@ -1407,8 +1437,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, case 1: { - op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); - if ((category == HW_Category_MemoryLoad) && op1->OperIs(GT_CAST)) { // Although the API specifies a pointer, if what we have is a BYREF, that's what @@ -1467,10 +1495,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, case 2: { - op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); - op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand, immLowerBound, immUpperBound); - op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); - retNode = isScalar ? gtNewScalarHWIntrinsicNode(nodeRetType, op1, op2, intrinsic) : gtNewSimdHWIntrinsicNode(nodeRetType, op1, op2, intrinsic, simdBaseJitType, simdSize); @@ -1515,6 +1539,17 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, } break; + case NI_Sve_CreateWhileLessThanMask8Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask8Bit: + case NI_Sve_CreateWhileLessThanMask16Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask16Bit: + case NI_Sve_CreateWhileLessThanMask32Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask32Bit: + case NI_Sve_CreateWhileLessThanMask64Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask64Bit: + retNode->AsHWIntrinsic()->SetAuxiliaryJitType(sigReader.op1JitType); + break; + default: break; } @@ -1524,10 +1559,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, case 3: { - op3 = getArgForHWIntrinsic(sigReader.GetOp3Type(), sigReader.op3ClsHnd); - op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); - op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); - #ifdef TARGET_ARM64 if (intrinsic == NI_AdvSimd_LoadAndInsertScalar) { @@ -1569,12 +1600,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, case 4: { - op4 = getArgForHWIntrinsic(sigReader.GetOp4Type(), sigReader.op4ClsHnd); - op4 = addRangeCheckIfNeeded(intrinsic, op4, mustExpand, immLowerBound, immUpperBound); - op3 = getArgForHWIntrinsic(sigReader.GetOp3Type(), sigReader.op3ClsHnd); - op2 = getArgForHWIntrinsic(sigReader.GetOp2Type(), sigReader.op2ClsHnd); - op1 = getArgForHWIntrinsic(sigReader.GetOp1Type(), sigReader.op1ClsHnd); - assert(!isScalar); retNode = gtNewSimdHWIntrinsicNode(nodeRetType, op1, op2, op3, op4, intrinsic, simdBaseJitType, simdSize); @@ -1591,10 +1616,22 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, } #if defined(TARGET_ARM64) - if (HWIntrinsicInfo::IsMaskedOperation(intrinsic)) + if (HWIntrinsicInfo::IsExplicitMaskedOperation(intrinsic)) { assert(numArgs > 0); GenTree* op1 = retNode->AsHWIntrinsic()->Op(1); + if (intrinsic == NI_Sve_ConditionalSelect) + { + if (op1->IsVectorAllBitsSet() || op1->IsMaskAllBitsSet()) + { + return retNode->AsHWIntrinsic()->Op(2); + } + else if (op1->IsVectorZero()) + { + return retNode->AsHWIntrinsic()->Op(3); + } + } + if (!varTypeIsMask(op1)) { // Op1 input is a vector. HWInstrinsic requires a mask. diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index 5ca302e126f32a..82cf179c742f4f 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -58,7 +58,6 @@ enum HWIntrinsicCategory : uint8_t HW_Category_ShiftLeftByImmediate, HW_Category_ShiftRightByImmediate, HW_Category_SIMDByIndexedElement, - HW_Category_EnumPattern, // Helper intrinsics // - do not directly correspond to a instruction, such as Vector64.AllBitsSet @@ -186,11 +185,18 @@ enum HWIntrinsicFlag : unsigned int HW_Flag_ReturnsPerElementMask = 0x10000, // The intrinsic uses a mask in arg1 to select elements present in the result - HW_Flag_MaskedOperation = 0x20000, + HW_Flag_ExplicitMaskedOperation = 0x20000, // The intrinsic uses a mask in arg1 to select elements present in the result, and must use a low register. HW_Flag_LowMaskedOperation = 0x40000, + // The intrinsic can optionally use a mask in arg1 to select elements present in the result, which is not present in + // the API call + HW_Flag_OptionalEmbeddedMaskedOperation = 0x80000, + + // The intrinsic uses a mask in arg1 to select elements present in the result, which is not present in the API call + HW_Flag_EmbeddedMaskedOperation = 0x100000, + #else #error Unsupported platform #endif @@ -225,6 +231,11 @@ enum HWIntrinsicFlag : unsigned int // The intrinsic is an embedded masking incompatible intrinsic HW_Flag_EmbMaskingIncompatible = 0x20000000, +#elif defined(TARGET_ARM64) + + // The intrinsic has an enum operand. Using this implies HW_Flag_HasImmediateOperand. + HW_Flag_HasEnumOperand = 0x1000000, + #endif // TARGET_XARCH HW_Flag_CanBenefitFromConstantProp = 0x80000000, @@ -860,7 +871,7 @@ struct HWIntrinsicInfo static bool HasImmediateOperand(NamedIntrinsic id) { const HWIntrinsicFlag flags = lookupFlags(id); - return (flags & HW_Flag_HasImmediateOperand) != 0; + return ((flags & HW_Flag_HasImmediateOperand) != 0) || HasEnumOperand(id); } static bool IsScalable(NamedIntrinsic id) @@ -872,7 +883,7 @@ struct HWIntrinsicInfo static bool IsMaskedOperation(NamedIntrinsic id) { const HWIntrinsicFlag flags = lookupFlags(id); - return ((flags & HW_Flag_MaskedOperation) != 0) || IsLowMaskedOperation(id); + return IsLowMaskedOperation(id) || IsOptionalEmbeddedMaskedOperation(id) || IsExplicitMaskedOperation(id); } static bool IsLowMaskedOperation(NamedIntrinsic id) @@ -881,6 +892,30 @@ struct HWIntrinsicInfo return (flags & HW_Flag_LowMaskedOperation) != 0; } + static bool IsOptionalEmbeddedMaskedOperation(NamedIntrinsic id) + { + const HWIntrinsicFlag flags = lookupFlags(id); + return (flags & HW_Flag_OptionalEmbeddedMaskedOperation) != 0; + } + + static bool IsEmbeddedMaskedOperation(NamedIntrinsic id) + { + const HWIntrinsicFlag flags = lookupFlags(id); + return (flags & HW_Flag_EmbeddedMaskedOperation) != 0; + } + + static bool IsExplicitMaskedOperation(NamedIntrinsic id) + { + const HWIntrinsicFlag flags = lookupFlags(id); + return (flags & HW_Flag_ExplicitMaskedOperation) != 0; + } + + static bool HasEnumOperand(NamedIntrinsic id) + { + const HWIntrinsicFlag flags = lookupFlags(id); + return (flags & HW_Flag_HasEnumOperand) != 0; + } + #endif // TARGET_ARM64 static bool HasSpecialSideEffect(NamedIntrinsic id) diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 8e3288f75d7090..90dde12bde8220 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -290,6 +290,10 @@ void HWIntrinsicInfo::lookupImmBounds( case NI_Sve_CreateTrueMaskUInt16: case NI_Sve_CreateTrueMaskUInt32: case NI_Sve_CreateTrueMaskUInt64: + case NI_Sve_Count16BitElements: + case NI_Sve_Count32BitElements: + case NI_Sve_Count64BitElements: + case NI_Sve_Count8BitElements: immLowerBound = (int)SVE_PATTERN_POW2; immUpperBound = (int)SVE_PATTERN_ALL; break; @@ -621,28 +625,28 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } case NI_Vector64_ConvertToInt32: + case NI_Vector64_ConvertToInt32Native: case NI_Vector128_ConvertToInt32: + case NI_Vector128_ConvertToInt32Native: { assert(sig->numArgs == 1); assert(simdBaseType == TYP_FLOAT); - op1 = impSIMDPopStack(); - retNode = - gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_ConvertToInt32RoundToZero, simdBaseJitType, simdSize); + op1 = impSIMDPopStack(); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_INT, simdBaseJitType, simdSize); break; } case NI_Vector64_ConvertToInt64: + case NI_Vector64_ConvertToInt64Native: case NI_Vector128_ConvertToInt64: + case NI_Vector128_ConvertToInt64Native: { assert(sig->numArgs == 1); assert(simdBaseType == TYP_DOUBLE); - intrinsic = (simdSize == 8) ? NI_AdvSimd_Arm64_ConvertToInt64RoundToZeroScalar - : NI_AdvSimd_Arm64_ConvertToInt64RoundToZero; - op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_LONG, simdBaseJitType, simdSize); break; } @@ -658,28 +662,28 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } case NI_Vector64_ConvertToUInt32: + case NI_Vector64_ConvertToUInt32Native: case NI_Vector128_ConvertToUInt32: + case NI_Vector128_ConvertToUInt32Native: { assert(sig->numArgs == 1); assert(simdBaseType == TYP_FLOAT); op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_ConvertToUInt32RoundToZero, simdBaseJitType, - simdSize); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_UINT, simdBaseJitType, simdSize); break; } case NI_Vector64_ConvertToUInt64: + case NI_Vector64_ConvertToUInt64Native: case NI_Vector128_ConvertToUInt64: + case NI_Vector128_ConvertToUInt64Native: { assert(sig->numArgs == 1); assert(simdBaseType == TYP_DOUBLE); - intrinsic = (simdSize == 8) ? NI_AdvSimd_Arm64_ConvertToUInt64RoundToZeroScalar - : NI_AdvSimd_Arm64_ConvertToUInt64RoundToZero; - op1 = impSIMDPopStack(); - retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_ULONG, simdBaseJitType, simdSize); break; } @@ -2222,9 +2226,8 @@ GenTree* Compiler::gtNewSimdConvertVectorToMaskNode(var_types type, assert(varTypeIsSIMD(node)); // ConvertVectorToMask uses cmpne which requires an embedded mask. - GenTree* embeddedMask = gtNewSimdHWIntrinsicNode(TYP_MASK, NI_Sve_CreateTrueMaskAll, simdBaseJitType, simdSize); - return gtNewSimdHWIntrinsicNode(TYP_MASK, embeddedMask, node, NI_Sve_ConvertVectorToMask, simdBaseJitType, - simdSize); + GenTree* trueMask = gtNewSimdAllTrueMaskNode(simdBaseJitType, simdSize); + return gtNewSimdHWIntrinsicNode(TYP_MASK, trueMask, node, NI_Sve_ConvertVectorToMask, simdBaseJitType, simdSize); } //------------------------------------------------------------------------ @@ -2246,4 +2249,19 @@ GenTree* Compiler::gtNewSimdConvertMaskToVectorNode(GenTreeHWIntrinsic* node, va node->GetSimdSize()); } +//------------------------------------------------------------------------ +// gtNewSimdEmbeddedMaskNode: Create an embedded mask +// +// Arguments: +// simdBaseJitType -- the base jit type of the nodes being masked +// simdSize -- the simd size of the nodes being masked +// +// Return Value: +// The mask +// +GenTree* Compiler::gtNewSimdAllTrueMaskNode(CorInfoType simdBaseJitType, unsigned simdSize) +{ + return gtNewSimdHWIntrinsicNode(TYP_MASK, NI_Sve_CreateTrueMaskAll, simdBaseJitType, simdSize); +} + #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 9a3a98e087a274..6098d39e6efbc2 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -99,7 +99,7 @@ CodeGen::HWIntrinsicImmOpHelper::HWIntrinsicImmOpHelper(CodeGen* codeGen, GenTre // using the same approach as in hwintrinsicxarch.cpp - adding an additional indirection level in form of a // branch table. assert(!HWIntrinsicInfo::GeneratesMultipleIns(intrin->GetHWIntrinsicId())); - branchTargetReg = intrin->GetSingleTempReg(); + branchTargetReg = codeGen->internalRegisters.GetSingle(intrin); } endLabel = codeGen->genCreateTempLabel(); @@ -380,7 +380,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) emitShift(intrin.op2, op1Reg); } } - else if (intrin.category == HW_Category_EnumPattern) + else if (HWIntrinsicInfo::HasEnumOperand(intrin.id)) { assert(hasImmediateOperand); @@ -401,6 +401,168 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) unreached(); } } + else if (intrin.numOperands >= 2 && intrin.op2->IsEmbMaskOp()) + { + // Handle case where op2 is operation that needs embedded mask + GenTree* op2 = intrin.op2; + assert(intrin.id == NI_Sve_ConditionalSelect); + assert(op2->OperIsHWIntrinsic()); + assert(op2->isContained()); + + // Get the registers and intrinsics that needs embedded mask + const HWIntrinsic intrinEmbMask(op2->AsHWIntrinsic()); + instruction insEmbMask = HWIntrinsicInfo::lookupIns(intrinEmbMask.id, intrinEmbMask.baseType); + const bool instrIsRMW = op2->isRMWHWIntrinsic(compiler); + + regNumber maskReg = op1Reg; + regNumber embMaskOp1Reg = REG_NA; + regNumber embMaskOp2Reg = REG_NA; + regNumber falseReg = op3Reg; + + switch (intrinEmbMask.numOperands) + { + case 2: + assert(intrinEmbMask.op2 != nullptr); + embMaskOp2Reg = intrinEmbMask.op2->GetRegNum(); + FALLTHROUGH; + + case 1: + assert(intrinEmbMask.op1 != nullptr); + embMaskOp1Reg = intrinEmbMask.op1->GetRegNum(); + break; + + default: + unreached(); + } + + switch (intrinEmbMask.numOperands) + { + case 1: + assert(!instrIsRMW); + + if (targetReg != falseReg) + { + // If targetReg is not the same as `falseReg` then need to move + // the `falseReg` to `targetReg`. + + if (intrin.op3->isContained()) + { + assert(intrin.op3->IsVectorZero()); + if (intrin.op1->isContained() || intrin.op1->IsMaskAllBitsSet()) + { + // We already skip importing ConditionalSelect if op1 == trueAll, however + // if we still see it here, it is because we wrapped the predicated instruction + // inside ConditionalSelect. + // As such, no need to move the `falseReg` to `targetReg` + // because the predicated instruction will eventually set it. + } + else + { + // If falseValue is zero, just zero out those lanes of targetReg using `movprfx` + // and /Z + GetEmitter()->emitIns_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, targetReg, + opt); + } + } + else if (targetReg == embMaskOp1Reg) + { + // target != falseValue, but we do not want to overwrite target with `embMaskOp1Reg`. + // We will first do the predicate operation and then do conditionalSelect inactive + // elements from falseValue + + // We cannot use use `movprfx` here to move falseReg to targetReg because that will + // overwrite the value of embMaskOp1Reg which is present in targetReg. + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + + GetEmitter()->emitIns_R_R_R_R(INS_sve_sel, emitSize, targetReg, maskReg, targetReg, + falseReg, opt, INS_SCALABLE_OPTS_UNPREDICATED); + break; + } + else + { + // At this point, target != embMaskOp1Reg != falseReg, so just go ahead + // and move the falseReg unpredicated into targetReg. + GetEmitter()->emitIns_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, falseReg); + } + } + + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + break; + + case 2: + + assert(instrIsRMW); + + if (intrin.op3->IsVectorZero()) + { + // If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the + // destination using /Z. + GetEmitter()->emitIns_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + + // Finally, perform the actual "predicated" operation so that `targetReg` is the first operand + // and `embMaskOp2Reg` is the second operand. + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, opt); + } + else if (targetReg != falseReg) + { + // If `targetReg` and `falseReg` are not same, then we need to move it to `targetReg` first + // so the `insEmbMask` operation can be merged on top of it. + + if (falseReg != embMaskOp1Reg) + { + // At the point, targetReg != embMaskOp1Reg != falseReg + if (HWIntrinsicInfo::IsOptionalEmbeddedMaskedOperation(intrinEmbMask.id)) + { + // If the embedded instruction supports optional mask operation, use the "unpredicated" + // version of the instruction, followed by "sel" to select the active lanes. + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, embMaskOp1Reg, + embMaskOp2Reg, opt, INS_SCALABLE_OPTS_UNPREDICATED); + } + else + { + // If the instruction just has "predicated" version, then move the "embMaskOp1Reg" + // into targetReg. Next, do the predicated operation on the targetReg and last, + // use "sel" to select the active lanes based on mask, and set inactive lanes + // to falseReg. + + assert(targetReg != embMaskOp2Reg); + assert(HWIntrinsicInfo::IsEmbeddedMaskedOperation(intrinEmbMask.id)); + + GetEmitter()->emitIns_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, embMaskOp1Reg); + + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, + opt); + } + + GetEmitter()->emitIns_R_R_R_R(INS_sve_sel, emitSize, targetReg, maskReg, targetReg, + falseReg, opt, INS_SCALABLE_OPTS_UNPREDICATED); + break; + } + else if (targetReg != embMaskOp1Reg) + { + // embMaskOp1Reg is same as `falseReg`, but not same as `targetReg`. Move the + // `embMaskOp1Reg` i.e. `falseReg` in `targetReg`, using "unpredicated movprfx", so the + // subsequent `insEmbMask` operation can be merged on top of it. + GetEmitter()->emitIns_R_R(INS_sve_movprfx, EA_SCALABLE, targetReg, falseReg, opt); + } + + // Finally, perform the actual "predicated" operation so that `targetReg` is the first operand + // and `embMaskOp2Reg` is the second operand. + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, opt); + } + else + { + // Just perform the actual "predicated" operation so that `targetReg` is the first operand + // and `embMaskOp2Reg` is the second operand. + GetEmitter()->emitIns_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, opt); + } + + break; + + default: + unreached(); + } + } else { assert(!hasImmediateOperand); @@ -419,6 +581,14 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) { GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); } + else if (HWIntrinsicInfo::IsScalable(intrin.id)) + { + assert(!node->IsEmbMaskOp()); + // This generates an unpredicated version + // Predicated should be taken care above `intrin.op2->IsEmbMaskOp()` + GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt, + INS_SCALABLE_OPTS_UNPREDICATED); + } else if (isRMW) { if (targetReg != op1Reg) @@ -437,17 +607,24 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; case 3: - assert(isRMW); - if (targetReg != op1Reg) + if (isRMW) { - assert(targetReg != op2Reg); - assert(targetReg != op3Reg); + if (targetReg != op1Reg) + { + assert(targetReg != op2Reg); + assert(targetReg != op3Reg); - GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, /* canSkip */ true); + GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, + /* canSkip */ true); + } + GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op2Reg, op3Reg, opt); + } + else + { + GetEmitter()->emitIns_R_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, op3Reg, opt, + INS_SCALABLE_OPTS_UNPREDICATED); } - GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op2Reg, op3Reg, opt); break; - default: unreached(); } @@ -833,7 +1010,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GenTree* argNode = use.GetNode(); assert(argReg == argNode->GetRegNum()); - argReg = REG_NEXT(argReg); + argReg = getNextSIMDRegWithWraparound(argReg); } assert((ins == INS_st2 && regCount == 2) || (ins == INS_st3 && regCount == 3) || (ins == INS_st4 && regCount == 4)); @@ -883,7 +1060,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GenTree* argNode = use.GetNode(); assert(argReg == argNode->GetRegNum()); - argReg = REG_NEXT(argReg); + argReg = getNextSIMDRegWithWraparound(argReg); } assert((ins == INS_st1_2regs && regCount == 2) || (ins == INS_st2 && regCount == 2) || (ins == INS_st1_3regs && regCount == 3) || (ins == INS_st3 && regCount == 3) || @@ -1034,7 +1211,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) if (intrin.op1->OperIsLocal()) { unsigned varNum = intrin.op1->AsLclVarCommon()->GetLclNum(); - baseReg = node->ExtractTempReg(); + baseReg = internalRegisters.Extract(node); // Load the address of varNum GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, baseReg, varNum, 0); @@ -1054,7 +1231,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) unsigned simdInitTempVarNum = compiler->lvaSIMDInitTempVarNum; noway_assert(simdInitTempVarNum != BAD_VAR_NUM); - baseReg = node->ExtractTempReg(); + baseReg = internalRegisters.Extract(node); // Load the address of simdInitTempVarNum GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, baseReg, simdInitTempVarNum, 0); @@ -1186,7 +1363,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GenTree* argNode = use.GetNode(); assert(argReg == argNode->GetRegNum()); - argReg = REG_NEXT(argReg); + argReg = getNextSIMDRegWithWraparound(argReg); #endif } } @@ -1241,7 +1418,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) assert(argReg == argNode->GetRegNum()); // and they should not interfere with targetReg assert(targetReg != argReg); - argReg = REG_NEXT(argReg); + argReg = getNextSIMDRegWithWraparound(argReg); #endif } } @@ -1295,11 +1472,70 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitIns_R_R_R_I(ins, emitSize, targetReg, op1Reg, op2Reg, 0, opt); break; + case NI_Sve_Count16BitElements: + case NI_Sve_Count32BitElements: + case NI_Sve_Count64BitElements: + case NI_Sve_Count8BitElements: + { + // Instruction has an additional immediate to multiply the result by. Use 1. + assert(hasImmediateOperand); + HWIntrinsicImmOpHelper helper(this, intrin.op1, node); + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + const insSvePattern pattern = (insSvePattern)helper.ImmValue(); + GetEmitter()->emitIns_R_PATTERN_I(ins, emitSize, targetReg, pattern, 1, opt); + } + break; + } + case NI_Sve_CreateTrueMaskAll: // Must use the pattern variant, as the non-pattern varient is SVE2.1. GetEmitter()->emitIns_R_PATTERN(ins, emitSize, targetReg, opt, SVE_PATTERN_ALL); break; + case NI_Sve_CreateWhileLessThanMask8Bit: + case NI_Sve_CreateWhileLessThanMask16Bit: + case NI_Sve_CreateWhileLessThanMask32Bit: + case NI_Sve_CreateWhileLessThanMask64Bit: + { + // Emit size and instruction is based on the scalar operands. + var_types auxType = node->GetAuxiliaryType(); + emitSize = emitActualTypeSize(auxType); + if (varTypeIsUnsigned(auxType)) + { + ins = INS_sve_whilelo; + } + + GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + + case NI_Sve_CreateWhileLessThanOrEqualMask8Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask16Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask32Bit: + case NI_Sve_CreateWhileLessThanOrEqualMask64Bit: + { + // Emit size and instruction is based on the scalar operands. + var_types auxType = node->GetAuxiliaryType(); + emitSize = emitActualTypeSize(auxType); + if (varTypeIsUnsigned(auxType)) + { + ins = INS_sve_whilels; + } + + GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); + break; + } + + case NI_Sve_UnzipEven: + case NI_Sve_UnzipOdd: + case NI_Sve_ZipHigh: + case NI_Sve_ZipLow: + // Use non-predicated version explicitly + GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt, + INS_SCALABLE_OPTS_UNPREDICATED); + break; + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index 79e6b497c368a9..a4b6748f3db531 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -323,8 +323,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) insOpts newInstOptions = AddEmbRoundingMode(instOptions, i); genHWIntrinsic_R_RM(node, ins, simdSize, targetReg, rmOp, newInstOptions); }; - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, lastOp->GetRegNum(), baseReg, offsReg, emitSwCase); break; @@ -335,8 +335,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) insOpts newInstOptions = AddEmbRoundingMode(instOptions, i); genHWIntrinsic_R_R_RM(node, ins, simdSize, newInstOptions); }; - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, lastOp->GetRegNum(), baseReg, offsReg, emitSwCase); break; @@ -524,8 +524,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) // Reflection. However, it // can also occur if the consumer calls it directly and just doesn't pass a // constant value. - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, op2Reg, baseReg, offsReg, emitSwCase); } } @@ -574,8 +574,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) // We emit a fallback case for the scenario when the imm-op is not a constant. This should // normally happen when the intrinsic is called indirectly, such as via Reflection. However, it // can also occur if the consumer calls it directly and just doesn't pass a constant value. - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, op3Reg, baseReg, offsReg, emitSwCase); } } @@ -670,8 +670,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) // We emit a fallback case for the scenario when the imm-op is not a constant. This should // normally happen when the intrinsic is called indirectly, such as via Reflection. However, it // can also occur if the consumer calls it directly and just doesn't pass a constant value. - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, op4Reg, baseReg, offsReg, emitSwCase); } } @@ -1373,8 +1373,8 @@ void CodeGen::genNonTableDrivenHWIntrinsicsJumpTableFallback(GenTreeHWIntrinsic* insOpts newInstOptions = AddEmbRoundingMode(instOptions, i); genHWIntrinsic_R_RM(node, ins, attr, targetReg, rmOp, newInstOptions); }; - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, lastOp->GetRegNum(), baseReg, offsReg, emitSwCase); break; } @@ -1394,8 +1394,8 @@ void CodeGen::genNonTableDrivenHWIntrinsicsJumpTableFallback(GenTreeHWIntrinsic* insOpts newInstOptions = AddEmbRoundingMode(instOptions, i); genHWIntrinsic_R_RM(node, ins, attr, targetReg, rmOp, newInstOptions); }; - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, lastOp->GetRegNum(), baseReg, offsReg, emitSwCase); break; } @@ -1408,8 +1408,8 @@ void CodeGen::genNonTableDrivenHWIntrinsicsJumpTableFallback(GenTreeHWIntrinsic* insOpts newInstOptions = AddEmbRoundingMode(instOptions, i); genHWIntrinsic_R_R_RM(node, ins, EA_8BYTE, newInstOptions); }; - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, lastOp->GetRegNum(), baseReg, offsReg, emitSwCase); break; } @@ -1440,8 +1440,8 @@ void CodeGen::genNonTableDrivenHWIntrinsicsJumpTableFallback(GenTreeHWIntrinsic* insOpts newInstOptions = AddEmbRoundingMode(instOptions, i); genHWIntrinsic_R_R_R_RM(ins, attr, targetReg, op1Reg, op2Reg, op3, newInstOptions); }; - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, lastOp->GetRegNum(), baseReg, offsReg, emitSwCase); break; } @@ -2074,8 +2074,8 @@ void CodeGen::genSSE41Intrinsic(GenTreeHWIntrinsic* node) // We emit a fallback case for the scenario when the imm-op is not a constant. This should // normally happen when the intrinsic is called indirectly, such as via Reflection. However, it // can also occur if the consumer calls it directly and just doesn't pass a constant value. - regNumber baseReg = node->ExtractTempReg(); - regNumber offsReg = node->GetSingleTempReg(); + regNumber baseReg = internalRegisters.Extract(node); + regNumber offsReg = internalRegisters.GetSingle(node); genHWIntrinsicJumpTableFallback(intrinsicId, op2->GetRegNum(), baseReg, offsReg, emitSwCase); } break; @@ -2225,7 +2225,7 @@ void CodeGen::genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node, insOpts instOption regNumber op2Reg = op2->GetRegNum(); regNumber addrBaseReg = REG_NA; regNumber addrIndexReg = REG_NA; - regNumber maskReg = node->ExtractTempReg(RBM_ALLFLOAT); + regNumber maskReg = internalRegisters.Extract(node, RBM_ALLFLOAT); if (numArgs == 5) { @@ -2902,7 +2902,7 @@ void CodeGen::genBMI1OrBMI2Intrinsic(GenTreeHWIntrinsic* node, insOpts instOptio assert(op3Reg != op1Reg); assert(op3Reg != targetReg); assert(op3Reg != REG_EDX); - lowReg = node->GetSingleTempReg(); + lowReg = internalRegisters.GetSingle(node); assert(op3Reg != lowReg); assert(lowReg != targetReg); } diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index f1a48b2d28127c..06feb2816de5ce 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/jit/hwintrinsiclistarm64.h @@ -37,10 +37,14 @@ HARDWARE_INTRINSIC(Vector64, Ceiling, HARDWARE_INTRINSIC(Vector64, ConditionalSelect, 8, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, ConvertToDouble, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, ConvertToInt32, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ConvertToInt32Native, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, ConvertToInt64, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ConvertToInt64Native, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, ConvertToSingle, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, ConvertToUInt32, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ConvertToUInt32Native, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, ConvertToUInt64, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ConvertToUInt64Native, 8, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, Create, 8, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, CreateScalar, 8, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, CreateScalarUnsafe, 8, 1, true, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_invalid, INS_invalid, INS_fmov, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment) @@ -146,10 +150,14 @@ HARDWARE_INTRINSIC(Vector128, Ceiling, HARDWARE_INTRINSIC(Vector128, ConditionalSelect, 16, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, ConvertToDouble, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToInt32, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToInt32Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToInt64, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToInt64Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToSingle, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToUInt32, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToUInt32Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToUInt64, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToUInt64Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, Create, 16, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, CreateScalar, 16, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, true, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_fmov, INS_fmov}, HW_Category_SIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment) diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index ac110c2a0e1b5b..a2af0bec711392 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -17,19 +17,88 @@ // SVE Intrinsics // Sve -HARDWARE_INTRINSIC(Sve, CreateTrueMaskByte, -1, 1, false, {INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskDouble, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskInt16, -1, 1, false, {INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskInt32, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskInt64, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskSByte, -1, 1, false, {INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskSingle, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt16, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt32, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt64, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid}, HW_Category_EnumPattern, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_ReturnsPerElementMask) - -HARDWARE_INTRINSIC(Sve, LoadVector, -1, 2, true, {INS_sve_ld1b, INS_sve_ld1b, INS_sve_ld1h, INS_sve_ld1h, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1d, INS_sve_ld1d, INS_sve_ld1w, INS_sve_ld1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_LowMaskedOperation) - +HARDWARE_INTRINSIC(Sve, Abs, -1, -1, false, {INS_sve_abs, INS_invalid, INS_sve_abs, INS_invalid, INS_sve_abs, INS_invalid, INS_sve_abs, INS_invalid, INS_sve_fabs, INS_sve_fabs}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) +HARDWARE_INTRINSIC(Sve, Add, -1, -1, false, {INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_fadd, INS_sve_fadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AddAcross, -1, 1, true, {INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_faddv, INS_sve_faddv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation) +HARDWARE_INTRINSIC(Sve, And, -1, -1, false, {INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AndAcross, -1, -1, false, {INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ConditionalSelect, -1, 3, true, {INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel, INS_sve_sel}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_SupportsContainment) +HARDWARE_INTRINSIC(Sve, Count16BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cnth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) +HARDWARE_INTRINSIC(Sve, Count32BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) +HARDWARE_INTRINSIC(Sve, Count64BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) +HARDWARE_INTRINSIC(Sve, Count8BitElements, 0, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_cntb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_SpecialCodeGen|HW_Flag_NoFloatingPointUsed) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskByte, -1, 1, false, {INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskDouble, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskInt16, -1, 1, false, {INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskInt32, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskInt64, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskSByte, -1, 1, false, {INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskSingle, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt16, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt32, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateTrueMaskUInt64, -1, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ptrue, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasEnumOperand|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask16Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask32Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask64Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanMask8Bit, -1, 2, false, {INS_invalid, INS_sve_whilelt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask16Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask32Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask64Bit, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, CreateWhileLessThanOrEqualMask8Bit, -1, 2, false, {INS_invalid, INS_sve_whilele, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ReturnsPerElementMask) +HARDWARE_INTRINSIC(Sve, Divide, -1, 2, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sdiv, INS_sve_udiv, INS_sve_sdiv, INS_sve_udiv, INS_sve_fdiv, INS_sve_fdiv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVector, -1, 2, true, {INS_sve_ld1b, INS_sve_ld1b, INS_sve_ld1h, INS_sve_ld1h, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1d, INS_sve_ld1d, INS_sve_ld1w, INS_sve_ld1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt16, -1, 2, false, {INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt16, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorByteZeroExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1b, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToUInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorInt16SignExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sh, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorInt32SignExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorInt32SignExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sw, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt16, -1, 2, false, {INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt16, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorSByteSignExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1sb, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToUInt32, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1h, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Max, -1, -1, false, {INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_fmax, INS_sve_fmax}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, MaxAcross, -1, -1, false, {INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_fmaxv, INS_sve_fmaxv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) +HARDWARE_INTRINSIC(Sve, MaxNumber, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnm, INS_sve_fmaxnm}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, MaxNumberAcross, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnmv, INS_sve_fmaxnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) +HARDWARE_INTRINSIC(Sve, Min, -1, -1, false, {INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_fmin, INS_sve_fmin}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, MinAcross, -1, -1, false, {INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_fminv, INS_sve_fminv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) +HARDWARE_INTRINSIC(Sve, MinNumber, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnm, INS_sve_fminnm}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, MinNumberAcross, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmv, INS_sve_fminnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) +HARDWARE_INTRINSIC(Sve, Multiply, -1, 2, true, {INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, Or, -1, -1, false, {INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, OrAcross, -1, -1, false, {INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, SignExtend16, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sxth, INS_invalid, INS_sve_sxth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, SignExtend32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sxtw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, SignExtend8, -1, -1, false, {INS_invalid, INS_invalid, INS_sve_sxtb, INS_invalid, INS_sve_sxtb, INS_invalid, INS_sve_sxtb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, SignExtendWideningLower, -1, 1, true, {INS_sve_sunpklo, INS_invalid, INS_sve_sunpklo, INS_invalid, INS_sve_sunpklo, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Sve, SignExtendWideningUpper, -1, 1, true, {INS_sve_sunpkhi, INS_invalid, INS_sve_sunpkhi, INS_invalid, INS_sve_sunpkhi, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Sve, Subtract, -1, 2, true, {INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_fsub, INS_sve_fsub}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, UnzipEven, -1, 2, true, {INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, UnzipOdd, -1, 2, true, {INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, Xor, -1, -1, false, {INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, XorAcross, -1, -1, false, {INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ZeroExtend16, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxth, INS_invalid, INS_sve_uxth, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ZeroExtend32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtw, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ZeroExtend8, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ZeroExtendWideningLower, -1, 1, true, {INS_invalid, INS_sve_uunpklo, INS_invalid, INS_sve_uunpklo, INS_invalid, INS_sve_uunpklo, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Sve, ZeroExtendWideningUpper, -1, 1, true, {INS_invalid, INS_sve_uunpkhi, INS_invalid, INS_sve_uunpkhi, INS_invalid, INS_sve_uunpkhi, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Sve, ZipHigh, -1, 2, true, {INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, ZipLow, -1, 2, true, {INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** @@ -38,11 +107,11 @@ HARDWARE_INTRINSIC(Sve, LoadVector, // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Special intrinsics that are generated during importing or lowering -HARDWARE_INTRINSIC(Sve, ConvertMaskToVector, -1, 1, true, {INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov}, HW_Category_Helper, HW_Flag_Scalable|HW_Flag_MaskedOperation) +HARDWARE_INTRINSIC(Sve, ConvertMaskToVector, -1, 1, true, {INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov, INS_sve_mov}, HW_Category_Helper, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation) HARDWARE_INTRINSIC(Sve, ConvertVectorToMask, -1, 2, true, {INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne, INS_sve_cmpne}, HW_Category_Helper, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask|HW_Flag_LowMaskedOperation) - HARDWARE_INTRINSIC(Sve, CreateTrueMaskAll, -1, -1, false, {INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue, INS_sve_ptrue}, HW_Category_Helper, HW_Flag_Scalable|HW_Flag_ReturnsPerElementMask) + #endif // FEATURE_HW_INTRINSIC #undef HARDWARE_INTRINSIC diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index 07bc2e4838c88c..d3f7c575a86667 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -56,10 +56,14 @@ HARDWARE_INTRINSIC(Vector128, Ceiling, HARDWARE_INTRINSIC(Vector128, ConditionalSelect, 16, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, ConvertToDouble, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToInt32, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToInt32Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToInt64, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToInt64Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToSingle, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToUInt32, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToUInt32Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, ConvertToUInt64, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ConvertToUInt64Native, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, Create, 16, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, CreateScalar, 16, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, true, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) @@ -162,10 +166,14 @@ HARDWARE_INTRINSIC(Vector256, Ceiling, HARDWARE_INTRINSIC(Vector256, ConditionalSelect, 32, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, ConvertToDouble, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, ConvertToInt32, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible) +HARDWARE_INTRINSIC(Vector256, ConvertToInt32Native, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, ConvertToInt64, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector256, ConvertToInt64Native, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, ConvertToSingle, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, ConvertToUInt32, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector256, ConvertToUInt32Native, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, ConvertToUInt64, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector256, ConvertToUInt64Native, 32, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, Create, 32, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, CreateScalar, 32, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, CreateScalarUnsafe, 32, 1, true, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_AvxOnlyCompatible) @@ -274,11 +282,15 @@ HARDWARE_INTRINSIC(Vector512, CreateScalar, HARDWARE_INTRINSIC(Vector512, CreateScalarUnsafe, 64, 1, true, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsd_simd}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector512, CreateSequence, 64, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector512, ConvertToDouble, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector512, ConvertToSingle, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector512, ConvertToInt32, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector512, ConvertToInt32Native, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector512, ConvertToInt64, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector512, ConvertToInt64Native, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector512, ConvertToSingle, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector512, ConvertToUInt32, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector512, ConvertToUInt32Native, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector512, ConvertToUInt64, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector512, ConvertToUInt64Native, 64, 1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector512, Divide, 64, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector512, Equals, 64, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector512, EqualsAll, 64, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index fc3c01e4c31d29..553e1bdf78366a 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -1440,58 +1440,59 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_Vector128_ConvertToInt64: - case NI_Vector256_ConvertToInt64: - case NI_Vector512_ConvertToInt64: + case NI_Vector128_ConvertToInt32: + case NI_Vector256_ConvertToInt32: + case NI_Vector512_ConvertToInt32: { assert(sig->numArgs == 1); - assert(simdBaseType == TYP_DOUBLE); - if (IsBaselineVector512IsaSupportedOpportunistically()) + assert(simdBaseType == TYP_FLOAT); + + if (compOpportunisticallyDependsOn(InstructionSet_SSE41)) { op1 = impSIMDPopStack(); - retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_LONG, simdBaseJitType, simdSize); + retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_INT, simdBaseJitType, simdSize); } break; } - case NI_Vector128_ConvertToUInt32: - case NI_Vector256_ConvertToUInt32: - case NI_Vector512_ConvertToUInt32: + case NI_Vector128_ConvertToInt32Native: + case NI_Vector256_ConvertToInt32Native: + case NI_Vector512_ConvertToInt32Native: { assert(sig->numArgs == 1); assert(simdBaseType == TYP_FLOAT); - if (IsBaselineVector512IsaSupportedOpportunistically()) - { - op1 = impSIMDPopStack(); - retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_UINT, simdBaseJitType, simdSize); - } + + op1 = impSIMDPopStack(); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_INT, simdBaseJitType, simdSize); break; } - case NI_Vector128_ConvertToUInt64: - case NI_Vector256_ConvertToUInt64: - case NI_Vector512_ConvertToUInt64: + case NI_Vector128_ConvertToInt64: + case NI_Vector256_ConvertToInt64: + case NI_Vector512_ConvertToInt64: { assert(sig->numArgs == 1); assert(simdBaseType == TYP_DOUBLE); + if (IsBaselineVector512IsaSupportedOpportunistically()) { op1 = impSIMDPopStack(); - retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_ULONG, simdBaseJitType, simdSize); + retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_LONG, simdBaseJitType, simdSize); } break; } - case NI_Vector128_ConvertToInt32: - case NI_Vector256_ConvertToInt32: - case NI_Vector512_ConvertToInt32: + case NI_Vector128_ConvertToInt64Native: + case NI_Vector256_ConvertToInt64Native: + case NI_Vector512_ConvertToInt64Native: { assert(sig->numArgs == 1); - assert(simdBaseType == TYP_FLOAT); - if (compOpportunisticallyDependsOn(InstructionSet_SSE41)) + assert(simdBaseType == TYP_DOUBLE); + + if (IsBaselineVector512IsaSupportedOpportunistically()) { op1 = impSIMDPopStack(); - retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_INT, simdBaseJitType, simdSize); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_LONG, simdBaseJitType, simdSize); } break; } @@ -1545,6 +1546,65 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector128_ConvertToUInt32: + case NI_Vector256_ConvertToUInt32: + case NI_Vector512_ConvertToUInt32: + { + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_FLOAT); + + if (IsBaselineVector512IsaSupportedOpportunistically()) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_UINT, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_ConvertToUInt32Native: + case NI_Vector256_ConvertToUInt32Native: + case NI_Vector512_ConvertToUInt32Native: + { + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_FLOAT); + + if (IsBaselineVector512IsaSupportedOpportunistically()) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_UINT, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_ConvertToUInt64: + case NI_Vector256_ConvertToUInt64: + case NI_Vector512_ConvertToUInt64: + { + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_DOUBLE); + if (IsBaselineVector512IsaSupportedOpportunistically()) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_ULONG, simdBaseJitType, simdSize); + } + break; + } + + case NI_Vector128_ConvertToUInt64Native: + case NI_Vector256_ConvertToUInt64Native: + case NI_Vector512_ConvertToUInt64Native: + { + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_DOUBLE); + + if (IsBaselineVector512IsaSupportedOpportunistically()) + { + op1 = impSIMDPopStack(); + retNode = gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_ULONG, simdBaseJitType, simdSize); + } + break; + } + case NI_Vector128_Create: case NI_Vector256_Create: case NI_Vector512_Create: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 7f2fccf0f97dca..97aa8af7f2d5f8 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5136,9 +5136,14 @@ void Compiler::impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr) // We are unlikely to be able to repair the profile. // For now we don't even try. // - JITDUMP("\nimpResetLeaveBlock: Profile data could not be locally repaired. Data %s inconsisent.\n", + JITDUMP("\nimpResetLeaveBlock: Profile data could not be locally repaired. Data %s inconsistent.\n", fgPgoConsistent ? "is now" : "was already"); - fgPgoConsistent = false; + + if (fgPgoConsistent) + { + Metrics.ProfileInconsistentResetLeave++; + fgPgoConsistent = false; + } } } @@ -7319,6 +7324,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) fgRemoveRefPred(removedEdge); block->SetKindAndTargetEdge(BBJ_ALWAYS, retainedEdge); + Metrics.ImporterBranchFold++; // If we removed an edge carrying profile, try to do a local repair. // @@ -7369,7 +7375,12 @@ void Compiler::impImportBlockCode(BasicBlock* block) { JITDUMP("Profile data could not be locally repaired. Data %s inconsistent.\n", fgPgoConsistent ? "is now" : "was already"); - fgPgoConsistent = false; + + if (fgPgoConsistent) + { + Metrics.ProfileInconsistentImporterBranchFold++; + fgPgoConsistent = false; + } } } } @@ -7615,6 +7626,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) unsigned jumpCnt = block->GetSwitchTargets()->bbsCount; FlowEdge** jumpTab = block->GetSwitchTargets()->bbsDstTab; bool foundVal = false; + Metrics.ImporterSwitchFold++; for (unsigned val = 0; val < jumpCnt; val++, jumpTab++) { @@ -7653,9 +7665,14 @@ void Compiler::impImportBlockCode(BasicBlock* block) // We are unlikely to be able to repair the profile. // For now we don't even try. // - JITDUMP("Profile data could not be locally repaired. Data %s inconsisent.\n", + JITDUMP("Profile data could not be locally repaired. Data %s inconsistent.\n", fgPgoConsistent ? "is now" : "was already"); - fgPgoConsistent = false; + + if (fgPgoConsistent) + { + Metrics.ProfileInconsistentImporterSwitchFold++; + fgPgoConsistent = false; + } } // Create a NOP node @@ -7999,6 +8016,14 @@ void Compiler::impImportBlockCode(BasicBlock* block) /* Append the value to the tree list */ goto SPILL_APPEND; } + else + { + if (op1->IsBoxedValue()) + { + JITDUMP("\n CEE_POP box...\n"); + gtTryRemoveBoxUpstreamEffects(op1); + } + } /* No side effects - just throw the thing away */ } diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 07681c75c0e95c..943c75d2639bf1 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3125,7 +3125,15 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, // To be fixed in https://github.com/dotnet/runtime/pull/77465 const bool tier0opts = !opts.compDbgCode && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT); - if (!mustExpand && tier0opts) + if (tier0opts) + { + // The *Estimate APIs are allowed to differ in behavior across hardware + // so ensure we treat them as "betterToExpand" to get deterministic behavior + + betterToExpand |= (ni == NI_System_Math_ReciprocalEstimate); + betterToExpand |= (ni == NI_System_Math_ReciprocalSqrtEstimate); + } + else if (!mustExpand) { switch (ni) { @@ -3189,9 +3197,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; default: - // Unsafe.* are all small enough to prefer expansions. + // Various intrinsics are all small enough to prefer expansions. + betterToExpand |= ni >= NI_SYSTEM_MATH_START && ni <= NI_SYSTEM_MATH_END; betterToExpand |= ni >= NI_SRCS_UNSAFE_START && ni <= NI_SRCS_UNSAFE_END; - // Same for these betterToExpand |= ni >= NI_PRIMITIVE_START && ni <= NI_PRIMITIVE_END; break; } @@ -4146,6 +4154,13 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; } + case NI_System_Math_ReciprocalEstimate: + case NI_System_Math_ReciprocalSqrtEstimate: + { + retNode = impEstimateIntrinsic(method, sig, callJitType, ni, tailCall); + break; + } + case NI_System_Array_Clone: case NI_System_Collections_Generic_Comparer_get_Default: case NI_System_Collections_Generic_EqualityComparer_get_Default: @@ -5164,12 +5179,16 @@ GenTree* Compiler::impPrimitiveNamedIntrinsic(NamedIntrinsic intrinsic, assert(sig->sigInst.classInstCount == 0); var_types retType = JITtype2varType(sig->retType); - assert(varTypeIsArithmetic(retType)); + + if (!varTypeIsArithmetic(retType)) + { + assert((intrinsic == NI_PRIMITIVE_ConvertToInteger) || (intrinsic == NI_PRIMITIVE_ConvertToIntegerNative)); + return nullptr; + } NamedIntrinsic hwintrinsic = NI_Illegal; CORINFO_ARG_LIST_HANDLE args = sig->args; - assert((sig->numArgs == 1) || (sig->numArgs == 2)); CORINFO_CLASS_HANDLE op1ClsHnd; @@ -5180,6 +5199,113 @@ GenTree* Compiler::impPrimitiveNamedIntrinsic(NamedIntrinsic intrinsic, switch (intrinsic) { + case NI_PRIMITIVE_ConvertToInteger: + case NI_PRIMITIVE_ConvertToIntegerNative: + { + assert(sig->sigInst.methInstCount == 1); + assert(varTypeIsFloating(baseType)); + + var_types tgtType = JitType2PreciseVarType(sig->retType); + retType = genActualType(retType); + bool uns = varTypeIsUnsigned(tgtType) && !varTypeIsSmall(tgtType); + + GenTree* res = nullptr; + GenTree* op1 = nullptr; + +#if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) + if ((intrinsic == NI_PRIMITIVE_ConvertToIntegerNative) && IsBaselineSimdIsaSupported()) + { + NamedIntrinsic hwIntrinsicId = NI_Illegal; + + if (retType == TYP_INT) + { + if (baseType == TYP_FLOAT) + { + if (!uns) + { + hwIntrinsicId = NI_SSE_ConvertToInt32WithTruncation; + } + else if (IsBaselineVector512IsaSupportedOpportunistically()) + { + hwIntrinsicId = NI_AVX512F_ConvertToUInt32WithTruncation; + } + } + else + { + assert(baseType == TYP_DOUBLE); + + if (!uns) + { + hwIntrinsicId = NI_SSE2_ConvertToInt32WithTruncation; + } + else if (IsBaselineVector512IsaSupportedOpportunistically()) + { + hwIntrinsicId = NI_AVX512F_ConvertToUInt32WithTruncation; + } + } + } +#if defined(TARGET_AMD64) + else + { + assert(retType == TYP_LONG); + + if (baseType == TYP_FLOAT) + { + if (!uns) + { + hwIntrinsicId = NI_SSE_X64_ConvertToInt64WithTruncation; + } + else if (IsBaselineVector512IsaSupportedOpportunistically()) + { + hwIntrinsicId = NI_AVX512F_X64_ConvertToUInt64WithTruncation; + } + } + else + { + assert(baseType == TYP_DOUBLE); + + if (!uns) + { + hwIntrinsicId = NI_SSE2_X64_ConvertToInt64WithTruncation; + } + else if (IsBaselineVector512IsaSupportedOpportunistically()) + { + hwIntrinsicId = NI_AVX512F_X64_ConvertToUInt64WithTruncation; + } + } + } +#endif // TARGET_AMD64 + + if (hwIntrinsicId != NI_Illegal) + { + op1 = impPopStack().val; + res = gtNewSimdHWIntrinsicNode(retType, op1, hwIntrinsicId, baseJitType, 16); + + if (varTypeIsSmall(tgtType)) + { + res = gtNewCastNode(TYP_INT, res, /* uns */ false, tgtType); + } + return res; + } + } +#endif // TARGET_XARCH && FEATURE_HW_INTRINSICS + + op1 = impPopStack().val; + + if (varTypeIsSmall(tgtType)) + { + res = gtNewCastNodeL(retType, op1, /* uns */ false, retType); + res = gtFoldExpr(res); + res = gtNewCastNode(TYP_INT, res, /* uns */ false, tgtType); + } + else + { + res = gtNewCastNodeL(retType, op1, /* uns */ false, tgtType); + } + + return gtFoldExpr(res); + } + case NI_PRIMITIVE_Crc32C: { assert(sig->numArgs == 2); @@ -7302,13 +7428,15 @@ bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName) // instructions to directly compute round/ceiling/floor/truncate. case NI_System_Math_Abs: + case NI_System_Math_ReciprocalEstimate: + case NI_System_Math_ReciprocalSqrtEstimate: case NI_System_Math_Sqrt: return true; case NI_System_Math_Ceiling: case NI_System_Math_Floor: - case NI_System_Math_Truncate: case NI_System_Math_Round: + case NI_System_Math_Truncate: return compOpportunisticallyDependsOn(InstructionSet_SSE41); case NI_System_Math_FusedMultiplyAdd: @@ -7323,11 +7451,13 @@ bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName) case NI_System_Math_Abs: case NI_System_Math_Ceiling: case NI_System_Math_Floor: - case NI_System_Math_Truncate: - case NI_System_Math_Round: - case NI_System_Math_Sqrt: case NI_System_Math_Max: case NI_System_Math_Min: + case NI_System_Math_ReciprocalEstimate: + case NI_System_Math_ReciprocalSqrtEstimate: + case NI_System_Math_Round: + case NI_System_Math_Sqrt: + case NI_System_Math_Truncate: return true; case NI_System_Math_FusedMultiplyAdd: @@ -7402,6 +7532,8 @@ bool Compiler::IsMathIntrinsic(NamedIntrinsic intrinsicName) case NI_System_Math_MinMagnitudeNumber: case NI_System_Math_MinNumber: case NI_System_Math_Pow: + case NI_System_Math_ReciprocalEstimate: + case NI_System_Math_ReciprocalSqrtEstimate: case NI_System_Math_Round: case NI_System_Math_Sin: case NI_System_Math_Sinh: @@ -7760,6 +7892,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, // the resulting method would be a generic method of the non-generic SZArrayHelper class. // assert(canDevirtualize); + Metrics.DevirtualizedCall++; JITDUMP(" %s; can devirtualize\n", note); @@ -7988,6 +8121,8 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, // We may end up inlining this call, so the local copy must be marked as "aliased", // making sure the inlinee importer will know when to spill references to its value. lvaGetDesc(localCopyThis->AsLclFld())->lvHasLdAddrOp = true; + Metrics.DevirtualizedCallRemovedBox++; + Metrics.DevirtualizedCallUnboxedEntry++; #if FEATURE_TAILCALL_OPT if (call->IsImplicitTailCall()) @@ -8051,6 +8186,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, derivedMethodAttribs = unboxedMethodAttribs; call->gtArgs.InsertInstParam(this, methodTableArg); + Metrics.DevirtualizedCallUnboxedEntry++; } } else @@ -8066,6 +8202,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call, INDEBUG(call->gtCallDebugFlags |= GTF_CALL_MD_UNBOXED); derivedMethod = unboxedEntryMethod; pDerivedResolvedToken = &dvInfo.resolvedTokenDevirtualizedUnboxedMethod; + Metrics.DevirtualizedCallUnboxedEntry++; } } } @@ -8459,13 +8596,11 @@ void Compiler::impCheckCanInline(GenTreeCall* call, CORINFO_METHOD_HANDLE ftn = pParam->fncHandle; InlineResult* const inlineResult = pParam->result; -#ifdef DEBUG if (JitConfig.JitNoInline()) { inlineResult->NoteFatal(InlineObservation::CALLEE_IS_JIT_NOINLINE); return; } -#endif JITDUMP("\nCheckCanInline: fetching method info for inline candidate %s -- context %p\n", compiler->eeGetMethodName(ftn), compiler->dspPtr(pParam->exactContextHnd)); @@ -8614,6 +8749,119 @@ void Compiler::impCheckCanInline(GenTreeCall* call, } } +//------------------------------------------------------------------------ +// impEstimateIntrinsic: Imports one of the *Estimate intrinsics which are +// explicitly allowed to differ in result based on the hardware they're running +// against +// +// Arguments: +// method - The handle of the method being imported +// callType - The underlying type for the call +// intrinsicName - The intrinsic being imported +// tailCall - true if the method is a tail call; otherwise false +// +GenTree* Compiler::impEstimateIntrinsic(CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* sig, + CorInfoType callJitType, + NamedIntrinsic intrinsicName, + bool tailCall) +{ + var_types callType = JITtype2varType(callJitType); + + assert(varTypeIsFloating(callType)); + assert(sig->numArgs == 1); + +#if defined(FEATURE_HW_INTRINSICS) + // We use compExactlyDependsOn since these are estimate APIs where + // the behavior is explicitly allowed to differ across machines and + // we want to ensure that it gets marked as such in R2R. + + var_types simdType = TYP_UNKNOWN; + NamedIntrinsic intrinsicId = NI_Illegal; + + switch (intrinsicName) + { + case NI_System_Math_ReciprocalEstimate: + { +#if defined(TARGET_XARCH) + if (compExactlyDependsOn(InstructionSet_AVX512F)) + { + simdType = TYP_SIMD16; + intrinsicId = NI_AVX512F_Reciprocal14Scalar; + } + else if ((callType == TYP_FLOAT) && compExactlyDependsOn(InstructionSet_SSE)) + { + simdType = TYP_SIMD16; + intrinsicId = NI_SSE_ReciprocalScalar; + } +#elif defined(TARGET_ARM64) + if (compExactlyDependsOn(InstructionSet_AdvSimd_Arm64)) + { + simdType = TYP_SIMD8; + intrinsicId = NI_AdvSimd_Arm64_ReciprocalEstimateScalar; + } +#endif // TARGET_ARM64 + break; + } + + case NI_System_Math_ReciprocalSqrtEstimate: + { +#if defined(TARGET_XARCH) + if (compExactlyDependsOn(InstructionSet_AVX512F)) + { + simdType = TYP_SIMD16; + intrinsicId = NI_AVX512F_ReciprocalSqrt14Scalar; + } + else if ((callType == TYP_FLOAT) && compExactlyDependsOn(InstructionSet_SSE)) + { + simdType = TYP_SIMD16; + intrinsicId = NI_SSE_ReciprocalSqrtScalar; + } +#elif defined(TARGET_ARM64) + if (compExactlyDependsOn(InstructionSet_AdvSimd_Arm64)) + { + simdType = TYP_SIMD8; + intrinsicId = NI_AdvSimd_Arm64_ReciprocalSquareRootEstimateScalar; + } +#endif // TARGET_ARM64 + break; + } + + default: + { + unreached(); + } + } + + if (intrinsicId != NI_Illegal) + { + unsigned simdSize = 0; + + if (simdType == TYP_SIMD8) + { + simdSize = 8; + } + else + { + assert(simdType == TYP_SIMD16); + simdSize = 16; + } + + GenTree* op1 = impPopStack().val; + + op1 = gtNewSimdCreateScalarUnsafeNode(simdType, op1, callJitType, simdSize); + op1 = gtNewSimdHWIntrinsicNode(simdType, op1, intrinsicId, callJitType, simdSize); + + return gtNewSimdToScalarNode(callType, op1, callJitType, simdSize); + } +#endif // FEATURE_HW_INTRINSICS + + // TODO-CQ: Returning this as an intrinsic blocks inlining and is undesirable + // return impMathIntrinsic(method, sig, callType, intrinsicName, tailCall); + + return nullptr; +} + GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, @@ -10067,6 +10315,19 @@ NamedIntrinsic Compiler::lookupPrimitiveFloatNamedIntrinsic(CORINFO_METHOD_HANDL { result = NI_System_Math_Ceiling; } + else if (strncmp(methodName, "ConvertToInteger", 16) == 0) + { + methodName += 16; + + if (methodName[0] == '\0') + { + result = NI_PRIMITIVE_ConvertToInteger; + } + else if (strcmp(methodName, "Native") == 0) + { + result = NI_PRIMITIVE_ConvertToIntegerNative; + } + } else if (strncmp(methodName, "Cos", 3) == 0) { methodName += 3; @@ -10210,7 +10471,20 @@ NamedIntrinsic Compiler::lookupPrimitiveFloatNamedIntrinsic(CORINFO_METHOD_HANDL case 'R': { - if (strcmp(methodName, "Round") == 0) + if (strncmp(methodName, "Reciprocal", 10) == 0) + { + methodName += 10; + + if (strcmp(methodName, "Estimate") == 0) + { + result = NI_System_Math_ReciprocalEstimate; + } + else if (strcmp(methodName, "SqrtEstimate") == 0) + { + result = NI_System_Math_ReciprocalSqrtEstimate; + } + } + else if (strcmp(methodName, "Round") == 0) { result = NI_System_Math_Round; } diff --git a/src/coreclr/jit/indirectcalltransformer.cpp b/src/coreclr/jit/indirectcalltransformer.cpp index fad60de969d4c3..92cac9245fc638 100644 --- a/src/coreclr/jit/indirectcalltransformer.cpp +++ b/src/coreclr/jit/indirectcalltransformer.cpp @@ -509,6 +509,12 @@ class IndirectCallTransformer (GetChecksCount() == 1) && ((origCall->gtCallMoreFlags & GTF_CALL_M_GUARDED_DEVIRT_EXACT) == 0); if (canChainGdv) { + compiler->Metrics.GDV++; + if (GetChecksCount() > 1) + { + compiler->Metrics.MultiGuessGDV++; + } + const bool isChainedGdv = (origCall->gtCallMoreFlags & GTF_CALL_M_GUARDED_DEVIRT_CHAIN) != 0; if (isChainedGdv) @@ -520,6 +526,7 @@ class IndirectCallTransformer if (isChainedGdv) { + compiler->Metrics.ChainedGDV++; TransformForChainedGdv(); } @@ -691,6 +698,7 @@ class IndirectCallTransformer GenTree* targetMethodTable = compiler->gtNewIconEmbClsHndNode(clsHnd); compare = compiler->gtNewOperNode(GT_NE, TYP_INT, targetMethodTable, methodTable); + compiler->Metrics.ClassGDV++; } else { @@ -725,6 +733,7 @@ class IndirectCallTransformer GenTree* compareTarTree = CreateTreeForLookup(methHnd, lookup); compare = compiler->gtNewOperNode(GT_NE, TYP_INT, compareTarTree, tarTree); } + compiler->Metrics.MethodGDV++; } GenTree* jmpTree = compiler->gtNewOperNode(GT_JTRUE, TYP_VOID, compare); @@ -1052,7 +1061,7 @@ class IndirectCallTransformer // thenBlock = CreateAndInsertBasicBlock(BBJ_ALWAYS, checkBlock); thenBlock->CopyFlags(currBlock, BBF_SPLIT_GAINED); - thenBlock->inheritWeight(currBlock); + thenBlock->inheritWeight(checkBlock); thenBlock->scaleBBWeight(adjustedThenLikelihood); FlowEdge* const thenRemainderEdge = compiler->fgAddRefPred(remainderBlock, thenBlock); thenBlock->SetTargetEdge(thenRemainderEdge); @@ -1214,10 +1223,59 @@ class IndirectCallTransformer checkStmt = nextStmt; } - // Finally, rewire the cold block to jump to the else block, + // Rewire the cold block to jump to the else block, // not fall through to the check block. // compiler->fgRedirectTargetEdge(coldBlock, elseBlock); + + // Update the profile data + // + if (coldBlock->hasProfileWeight()) + { + // Check block + // + FlowEdge* const coldElseEdge = compiler->fgGetPredForBlock(elseBlock, coldBlock); + weight_t newCheckWeight = checkBlock->bbWeight - coldElseEdge->getLikelyWeight(); + + if (newCheckWeight < 0) + { + // If weights were consistent, we expect at worst a slight underflow. + // + if (compiler->fgPgoConsistent) + { + bool const isReasonableUnderflow = Compiler::fgProfileWeightsEqual(newCheckWeight, 0.0); + assert(isReasonableUnderflow); + + if (!isReasonableUnderflow) + { + JITDUMP("Profile data could not be locally repaired. Data %s inconsistent.\n", + compiler->fgPgoConsistent ? "is now" : "was already"); + + if (compiler->fgPgoConsistent) + { + compiler->Metrics.ProfileInconsistentChainedGDV++; + compiler->fgPgoConsistent = false; + } + } + } + + // No matter what, the minimum weight is zero + // + newCheckWeight = 0; + } + checkBlock->setBBProfileWeight(newCheckWeight); + + // Else block + // + FlowEdge* const checkElseEdge = compiler->fgGetPredForBlock(elseBlock, checkBlock); + weight_t const newElseWeight = checkElseEdge->getLikelyWeight() + coldElseEdge->getLikelyWeight(); + elseBlock->setBBProfileWeight(newElseWeight); + + // Then block + // + FlowEdge* const checkThenEdge = compiler->fgGetPredForBlock(thenBlock, checkBlock); + thenBlock->setBBProfileWeight(checkThenEdge->getLikelyWeight()); + } } // When the current candidate has sufficiently high likelihood, scan diff --git a/src/coreclr/jit/inline.h b/src/coreclr/jit/inline.h index 8c1cb56124ad2e..a2aeba6fed7254 100644 --- a/src/coreclr/jit/inline.h +++ b/src/coreclr/jit/inline.h @@ -993,6 +993,12 @@ class InlineStrategy m_ImportCount++; } + // Return number of import attempts + unsigned GetImportCount() const + { + return m_ImportCount; + } + // Inform strategy about the inline decision for a prejit root void NotePrejitDecision(const InlineResult& r) { diff --git a/src/coreclr/jit/instrsarm64sve.h b/src/coreclr/jit/instrsarm64sve.h index fb469c0bfdc101..b017d23a0a1365 100644 --- a/src/coreclr/jit/instrsarm64sve.h +++ b/src/coreclr/jit/instrsarm64sve.h @@ -555,14 +555,14 @@ INST4(stnt1w, "stnt1w", 0, IF_SV // STNT1W {.S }, , [{, #, MUL VL}] SVE_JM_3A 111001010001iiii 111gggnnnnnttttt E510 E000 -// enum name info SVE_AB_3A SVE_AT_3A SVE_EC_1A +// enum name info SVE_AA_3A SVE_AT_3A SVE_EC_1A INST3(add, "add", 0, IF_SVE_3A, 0x04000000, 0x04200000, 0x2520C000 ) - // ADD ., /M, ., . SVE_AB_3A 00000100xx000000 000gggmmmmmddddd 0400 0000 + // ADD ., /M, ., . SVE_AA_3A 00000100xx000000 000gggmmmmmddddd 0400 0000 // ADD ., ., . SVE_AT_3A 00000100xx1mmmmm 000000nnnnnddddd 0420 0000 // ADD ., ., #{, } SVE_EC_1A 00100101xx100000 11hiiiiiiiiddddd 2520 C000 INST3(sub, "sub", 0, IF_SVE_3A, 0x04010000, 0x04200400, 0x2521C000 ) - // SUB ., /M, ., . SVE_AB_3A 00000100xx000001 000gggmmmmmddddd 0401 0000 + // SUB ., /M, ., . SVE_AA_3A 00000100xx000001 000gggmmmmmddddd 0401 0000 // SUB ., ., . SVE_AT_3A 00000100xx1mmmmm 000001nnnnnddddd 0420 0400 // SUB ., ., #{, } SVE_EC_1A 00100101xx100001 11hiiiiiiiiddddd 2521 C000 @@ -926,21 +926,21 @@ INST2(str, "str", 0, IF_SV // STR , [{, #, MUL VL}] SVE_JH_2A 1110010110iiiiii 010iiinnnnnttttt E580 4000 -// enum name info SVE_AD_3A SVE_ED_1A +// enum name info SVE_AA_3A SVE_ED_1A INST2(smax, "smax", 0, IF_SVE_2AC, 0x04080000, 0x2528C000 ) - // SMAX ., /M, ., . SVE_AD_3A 00000100xx001000 000gggmmmmmddddd 0408 0000 + // SMAX ., /M, ., . SVE_AA_3A 00000100xx001000 000gggmmmmmddddd 0408 0000 // SMAX ., ., # SVE_ED_1A 00100101xx101000 110iiiiiiiiddddd 2528 C000 INST2(smin, "smin", 0, IF_SVE_2AC, 0x040A0000, 0x252AC000 ) - // SMIN ., /M, ., . SVE_AD_3A 00000100xx001010 000gggmmmmmddddd 040A 0000 + // SMIN ., /M, ., . SVE_AA_3A 00000100xx001010 000gggmmmmmddddd 040A 0000 // SMIN ., ., # SVE_ED_1A 00100101xx101010 110iiiiiiiiddddd 252A C000 INST2(umax, "umax", 0, IF_SVE_2AC, 0x04090000, 0x2529C000 ) - // UMAX ., /M, ., . SVE_AD_3A 00000100xx001001 000gggmmmmmddddd 0409 0000 + // UMAX ., /M, ., . SVE_AA_3A 00000100xx001001 000gggmmmmmddddd 0409 0000 // UMAX ., ., # SVE_ED_1A 00100101xx101001 110iiiiiiiiddddd 2529 C000 INST2(umin, "umin", 0, IF_SVE_2AC, 0x040B0000, 0x252BC000 ) - // UMIN ., /M, ., . SVE_AD_3A 00000100xx001011 000gggmmmmmddddd 040B 0000 + // UMIN ., /M, ., . SVE_AA_3A 00000100xx001011 000gggmmmmmddddd 040B 0000 // UMIN ., ., # SVE_ED_1A 00100101xx101011 110iiiiiiiiddddd 252B C000 @@ -1094,9 +1094,9 @@ INST2(not, "not", 0, IF_SV // NOT .B, /Z, .B SVE_CZ_4A 001001010000MMMM 01gggg1NNNN0DDDD 2500 4200 -// enum name info SVE_AB_3A SVE_EC_1A +// enum name info SVE_AA_3A SVE_EC_1A INST2(subr, "subr", 0, IF_SVE_2AT, 0x04030000, 0x2523C000 ) - // SUBR ., /M, ., . SVE_AB_3A 00000100xx000011 000gggmmmmmddddd 0403 0000 + // SUBR ., /M, ., . SVE_AA_3A 00000100xx000011 000gggmmmmmddddd 0403 0000 // SUBR ., ., #{, } SVE_EC_1A 00100101xx100011 11hiiiiiiiiddddd 2523 C000 @@ -1882,12 +1882,12 @@ INST1(urhadd, "urhadd", 0, IF_SV // URHADD ., /M, ., . SVE_EP_3A 01000100xx010101 100gggmmmmmddddd 4415 8000 -// enum name info SVE_AD_3A -INST1(sabd, "sabd", 0, IF_SVE_AD_3A, 0x040C0000 ) - // SABD ., /M, ., . SVE_AD_3A 00000100xx001100 000gggmmmmmddddd 040C 0000 +// enum name info SVE_AA_3A +INST1(sabd, "sabd", 0, IF_SVE_AA_3A, 0x040C0000 ) + // SABD ., /M, ., . SVE_AA_3A 00000100xx001100 000gggmmmmmddddd 040C 0000 -INST1(uabd, "uabd", 0, IF_SVE_AD_3A, 0x040D0000 ) - // UABD ., /M, ., . SVE_AD_3A 00000100xx001101 000gggmmmmmddddd 040D 0000 +INST1(uabd, "uabd", 0, IF_SVE_AA_3A, 0x040D0000 ) + // UABD ., /M, ., . SVE_AA_3A 00000100xx001101 000gggmmmmmddddd 040D 0000 // enum name info SVE_FW_3A diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index cc8c8cb717d9ab..11cd55699dc99f 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -470,9 +470,8 @@ class GlobalJitOptions /*****************************************************************************/ -#define CSE_INTO_HANDLERS 0 -#define DUMP_FLOWGRAPHS DEBUG // Support for creating Xml Flowgraph reports in *.fgx files -#define HANDLER_ENTRY_MUST_BE_IN_HOT_SECTION 0 // if 1 we must have all handler entry points in the Hot code section +#define CSE_INTO_HANDLERS 0 +#define DUMP_FLOWGRAPHS DEBUG // Support for creating Xml Flowgraph reports in *.fgx files /*****************************************************************************/ diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 700cd33bd6bf2f..d2ea1deca5166a 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -138,7 +138,6 @@ CONFIG_INTEGER(JitNoForceFallback, W("JitNoForceFallback"), 0) // Set to non-zer // flags. CONFIG_INTEGER(JitNoForwardSub, W("JitNoForwardSub"), 0) // Disables forward sub CONFIG_INTEGER(JitNoHoist, W("JitNoHoist"), 0) -CONFIG_INTEGER(JitNoInline, W("JitNoInline"), 0) // Disables inlining of all methods CONFIG_INTEGER(JitNoMemoryBarriers, W("JitNoMemoryBarriers"), 0) // If 1, don't generate memory barriers CONFIG_INTEGER(JitNoStructPromotion, W("JitNoStructPromotion"), 0) // Disables struct promotion 1 - for all, 2 - for // params. @@ -358,6 +357,9 @@ RELEASE_CONFIG_INTEGER(EnableEHWriteThru, W("EnableEHWriteThru"), 1) // Enable the enregistration of locals that are defined or used in a multireg context. RELEASE_CONFIG_INTEGER(EnableMultiRegLocals, W("EnableMultiRegLocals"), 1) +// Disables inlining of all methods +RELEASE_CONFIG_INTEGER(JitNoInline, W("JitNoInline"), 0) + // Enable EVEX encoding for SIMD instructions when AVX-512VL is available. CONFIG_INTEGER(JitStressEvexEncoding, W("JitStressEvexEncoding"), 0) @@ -754,6 +756,9 @@ RELEASE_CONFIG_INTEGER(JitEnablePhysicalPromotion, W("JitEnablePhysicalPromotion // Enable cross-block local assertion prop RELEASE_CONFIG_INTEGER(JitEnableCrossBlockLocalAssertionProp, W("JitEnableCrossBlockLocalAssertionProp"), 1) +// Do greedy RPO-based layout in Compiler::fgReorderBlocks. +RELEASE_CONFIG_INTEGER(JitDoReversePostOrderLayout, W("JitDoReversePostOrderLayout"), 0); + // JitFunctionFile: Name of a file that contains a list of functions. If the currently compiled function is in the // file, certain other JIT config variables will be active. If the currently compiled function is not in the file, // the specific JIT config variables will not be active. diff --git a/src/coreclr/jit/jithashtable.h b/src/coreclr/jit/jithashtable.h index f699c3eee19d24..7f9153b75864a7 100644 --- a/src/coreclr/jit/jithashtable.h +++ b/src/coreclr/jit/jithashtable.h @@ -233,7 +233,7 @@ class JitHashTable } //------------------------------------------------------------------------ - // Lookup: Get a pointer to the value associated to the specified key. + // LookupPointer: Get a pointer to the value associated to the specified key. // if any. // // Arguments: @@ -261,6 +261,48 @@ class JitHashTable } } + //------------------------------------------------------------------------ + // LookupPointerOrAdd: Get a pointer to the value associated to the specified key. + // If not present, add it with the specified default value and return a pointer to it. + // + // Arguments: + // k - the key + // defaultValue - Default value to add to the table if the key was not present + // + // Return Value: + // A pointer to the value associated with the specified key. + // + Value* LookupPointerOrAdd(Key k, Value defaultValue) + { + CheckGrowth(); + + assert(m_tableSizeInfo.prime != 0); + + unsigned index = GetIndexForKey(k); + + Node* n = m_table[index]; + while (n != nullptr) + { + if (KeyFuncs::Equals(k, n->m_key)) + { + return &n->m_val; + } + + n = n->m_next; + } + + n = new (m_alloc) Node(m_table[index], k, defaultValue); + m_table[index] = n; + m_tableCount++; + return &n->m_val; + } + + enum SetKind + { + None, + Overwrite + }; + //------------------------------------------------------------------------ // Set: Associate the specified value with the specified key. // @@ -279,12 +321,6 @@ class JitHashTable // If the key already exists and kind is Normal // this method will assert // - enum SetKind - { - None, - Overwrite - }; - bool Set(Key k, Value v, SetKind kind = None) { CheckGrowth(); diff --git a/src/coreclr/jit/jitmetadata.cpp b/src/coreclr/jit/jitmetadata.cpp index 905cdb7317d8bb..bdf8a8d06d029e 100644 --- a/src/coreclr/jit/jitmetadata.cpp +++ b/src/coreclr/jit/jitmetadata.cpp @@ -46,6 +46,20 @@ void JitMetrics::report(Compiler* comp) #include "jitmetadatalist.h" } +//------------------------------------------------------------------------ +// JitMetrics::mergeToRoot: Merge inlinee compiler metrics to root compiler instance +// +// Parameters: +// inlineeComp - inlinee compiler instance +// +void JitMetrics::mergeToRoot(Compiler* inlineeComp) +{ + Compiler* const root = inlineeComp->impInlineRoot(); +#define JITMETADATAINFO(name, type, flags) +#define JITMETADATAMETRIC(name, type, flags) root->Metrics.name += inlineeComp->Metrics.name; +#include "jitmetadatalist.h" +} + //------------------------------------------------------------------------ // printMetric: Print a double metric value to jitstdout. // diff --git a/src/coreclr/jit/jitmetadata.h b/src/coreclr/jit/jitmetadata.h index 3b4b324497cc21..5dbd623a86daf3 100644 --- a/src/coreclr/jit/jitmetadata.h +++ b/src/coreclr/jit/jitmetadata.h @@ -23,4 +23,5 @@ class JitMetrics void report(Compiler* comp); void dump(); + void mergeToRoot(Compiler* inlineeComp); }; diff --git a/src/coreclr/jit/jitmetadatalist.h b/src/coreclr/jit/jitmetadatalist.h index f36c15ab9991d6..e077f9f57b2559 100644 --- a/src/coreclr/jit/jitmetadatalist.h +++ b/src/coreclr/jit/jitmetadatalist.h @@ -24,25 +24,52 @@ // and int64_t types supported). Their reporting is handled automatically and // they will be propagated all the way into SPMI replay/diff results. -// Name, type flags -JITMETADATAINFO(MethodFullName, const char*, 0) -JITMETADATAINFO(TieringName, const char*, 0) -JITMETADATAMETRIC(PhysicallyPromotedFields, int, 0) -JITMETADATAMETRIC(LoopsFoundDuringOpts, int, 0) -JITMETADATAMETRIC(LoopsCloned, int, 0) -JITMETADATAMETRIC(LoopsUnrolled, int, 0) -JITMETADATAMETRIC(LoopAlignmentCandidates, int, 0) -JITMETADATAMETRIC(LoopsAligned, int, 0) -JITMETADATAMETRIC(LoopsIVWidened, int, 0) -JITMETADATAMETRIC(WidenedIVs, int, 0) -JITMETADATAMETRIC(VarsInSsa, int, 0) -JITMETADATAMETRIC(HoistedExpressions, int, 0) -JITMETADATAMETRIC(RedundantBranchesEliminated, int, JIT_METADATA_HIGHER_IS_BETTER) -JITMETADATAMETRIC(JumpThreadingsPerformed, int, JIT_METADATA_HIGHER_IS_BETTER) -JITMETADATAMETRIC(CseCount, int, 0) -JITMETADATAMETRIC(BasicBlocksAtCodegen, int, 0) -JITMETADATAMETRIC(PerfScore, double, JIT_METADATA_LOWER_IS_BETTER) -JITMETADATAMETRIC(BytesAllocated, int64_t, JIT_METADATA_LOWER_IS_BETTER) +// Name, type flags +JITMETADATAINFO(MethodFullName, const char*, 0) +JITMETADATAINFO(TieringName, const char*, 0) +JITMETADATAMETRIC(PhysicallyPromotedFields, int, 0) +JITMETADATAMETRIC(LoopsFoundDuringOpts, int, 0) +JITMETADATAMETRIC(LoopsCloned, int, 0) +JITMETADATAMETRIC(LoopsUnrolled, int, 0) +JITMETADATAMETRIC(LoopAlignmentCandidates, int, 0) +JITMETADATAMETRIC(LoopsAligned, int, 0) +JITMETADATAMETRIC(LoopsIVWidened, int, 0) +JITMETADATAMETRIC(WidenedIVs, int, 0) +JITMETADATAMETRIC(VarsInSsa, int, 0) +JITMETADATAMETRIC(HoistedExpressions, int, 0) +JITMETADATAMETRIC(RedundantBranchesEliminated, int, JIT_METADATA_HIGHER_IS_BETTER) +JITMETADATAMETRIC(JumpThreadingsPerformed, int, JIT_METADATA_HIGHER_IS_BETTER) +JITMETADATAMETRIC(CseCount, int, 0) +JITMETADATAMETRIC(BasicBlocksAtCodegen, int, 0) +JITMETADATAMETRIC(PerfScore, double, JIT_METADATA_LOWER_IS_BETTER) +JITMETADATAMETRIC(BytesAllocated, int64_t, JIT_METADATA_LOWER_IS_BETTER) +JITMETADATAMETRIC(ImporterBranchFold, int, 0) +JITMETADATAMETRIC(ImporterSwitchFold, int, 0) +JITMETADATAMETRIC(DevirtualizedCall, int, 0) +JITMETADATAMETRIC(DevirtualizedCallUnboxedEntry, int, 0) +JITMETADATAMETRIC(DevirtualizedCallRemovedBox, int, 0) +JITMETADATAMETRIC(GDV, int, 0) +JITMETADATAMETRIC(ClassGDV, int, 0) +JITMETADATAMETRIC(MethodGDV, int, 0) +JITMETADATAMETRIC(MultiGuessGDV, int, 0) +JITMETADATAMETRIC(ChainedGDV, int, 0) +JITMETADATAMETRIC(InlinerBranchFold, int, 0) +JITMETADATAMETRIC(InlineAttempt, int, 0) +JITMETADATAMETRIC(InlineCount, int, 0) +JITMETADATAMETRIC(ProfileConsistentBeforeInline, int, 0) +JITMETADATAMETRIC(ProfileConsistentAfterInline, int, 0) +JITMETADATAMETRIC(ProfileSynthesizedBlendedOrRepaired, int, 0) +JITMETADATAMETRIC(ProfileInconsistentInitially, int, 0) +JITMETADATAMETRIC(ProfileInconsistentResetLeave, int, 0) +JITMETADATAMETRIC(ProfileInconsistentImporterBranchFold, int, 0) +JITMETADATAMETRIC(ProfileInconsistentImporterSwitchFold, int, 0) +JITMETADATAMETRIC(ProfileInconsistentChainedGDV, int, 0) +JITMETADATAMETRIC(ProfileInconsistentScratchBB, int, 0) +JITMETADATAMETRIC(ProfileInconsistentInlinerBranchFold, int, 0) +JITMETADATAMETRIC(ProfileInconsistentInlineeScale, int, 0) +JITMETADATAMETRIC(ProfileInconsistentInlinee, int, 0) +JITMETADATAMETRIC(ProfileInconsistentNoReturnInlinee, int, 0) +JITMETADATAMETRIC(ProfileInconsistentMayThrowInlinee, int, 0) #undef JITMETADATA #undef JITMETADATAINFO diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index c101955fdea7ed..97986eefee4b27 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -1885,6 +1885,42 @@ void Compiler::lvaClassifyParameterABI() } } } + + for (unsigned lclNum = 0; lclNum < info.compArgsCount; lclNum++) + { + const ABIPassingInformation& abiInfo = lvaGetParameterABIInfo(lclNum); + + if (lvaIsImplicitByRefLocal(lclNum)) + { + assert((abiInfo.NumSegments == 1) && (abiInfo.Segments[0].Size == TARGET_POINTER_SIZE)); + } + else + { + for (unsigned i = 0; i < abiInfo.NumSegments; i++) + { + const ABIPassingSegment& segment = abiInfo.Segments[i]; + assert(segment.Size > 0); + assert(segment.Offset + segment.Size <= lvaLclExactSize(lclNum)); + + if (i > 0) + { + assert(segment.Offset > abiInfo.Segments[i - 1].Offset); + } + + for (unsigned j = 0; j < abiInfo.NumSegments; j++) + { + if (i == j) + { + continue; + } + + const ABIPassingSegment& otherSegment = abiInfo.Segments[j]; + assert((segment.Offset + segment.Size <= otherSegment.Offset) || + (segment.Offset >= otherSegment.Offset + otherSegment.Size)); + } + } + } + } #endif // DEBUG } @@ -5669,23 +5705,52 @@ void Compiler::lvaFixVirtualFrameOffsets() // We set FP to be after LR, FP delta += 2 * REGSIZE_BYTES; } -#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) +#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) else { // FP is used. JITDUMP("--- delta bump %d for FP frame\n", codeGen->genTotalFrameSize() - codeGen->genSPtoFPdelta()); delta += codeGen->genTotalFrameSize() - codeGen->genSPtoFPdelta(); } -#endif // TARGET_AMD64 || TARGET_ARM64 || TARGET_LOONGARCH64 || TARGET_RISCV64 +#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) + else + { + // FP is used. + delta += (compCalleeRegsPushed << 3); + + if ((lvaMonAcquired != BAD_VAR_NUM) && !opts.IsOSR()) + { + int offset = lvaTable[lvaMonAcquired].GetStackOffset() + delta; + lvaTable[lvaMonAcquired].SetStackOffset(offset); + + if (lvaPSPSym != BAD_VAR_NUM) + { + int offset = lvaTable[lvaPSPSym].GetStackOffset() + delta; + lvaTable[lvaPSPSym].SetStackOffset(offset); + delta += TARGET_POINTER_SIZE; + } + + delta += lvaLclSize(lvaMonAcquired); + } + else if (lvaPSPSym != BAD_VAR_NUM) + { + int offset = lvaTable[lvaPSPSym].GetStackOffset() + delta; + lvaTable[lvaPSPSym].SetStackOffset(offset); + delta += TARGET_POINTER_SIZE; + } + + JITDUMP("--- delta bump %d for FP frame\n", delta); + } +#endif // !TARGET_LOONGARCH64 || !TARGET_RISCV64 if (opts.IsOSR()) { -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) +#if defined(TARGET_AMD64) || defined(TARGET_ARM64) // Stack offset includes Tier0 frame. // JITDUMP("--- delta bump %d for OSR + Tier0 frame\n", info.compPatchpointInfo->TotalFrameSize()); delta += info.compPatchpointInfo->TotalFrameSize(); -#endif +#endif // TARGET_AMD64 || TARGET_ARM64 } JITDUMP("--- virtual stack offset to actual stack offset delta is %d\n", delta); @@ -5775,26 +5840,20 @@ void Compiler::lvaFixVirtualFrameOffsets() #endif // FEATURE_FIXED_OUT_ARGS -#if defined(TARGET_ARM64) +#if defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) // We normally add alignment below the locals between them and the outgoing // arg space area. When we store fp/lr(ra) at the bottom, however, this will // be below the alignment. So we should not apply the alignment adjustment to // them. It turns out we always store these at +0 and +8 of the FP, // so instead of dealing with skipping adjustment just for them we just set // them here always. + // For LoongArch64 and RISCV64, the RA is always at fp+8. assert(codeGen->isFramePointerUsed()); if (lvaRetAddrVar != BAD_VAR_NUM) { lvaTable[lvaRetAddrVar].SetStackOffset(REGSIZE_BYTES); } -#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - assert(codeGen->isFramePointerUsed()); - if (lvaRetAddrVar != BAD_VAR_NUM) - { - // For LoongArch64 and RISCV64, the RA is below the fp. see the `genPushCalleeSavedRegisters` - lvaTable[lvaRetAddrVar].SetStackOffset(-REGSIZE_BYTES); - } -#endif // !TARGET_LOONGARCH64 +#endif // !TARGET_ARM64 || !TARGET_LOONGARCH64 || !TARGET_RISCV64 } #ifdef TARGET_ARM @@ -6548,9 +6607,13 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals() // if (opts.IsOSR()) { +#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) + originalFrameStkOffs = info.compPatchpointInfo->TotalFrameSize(); +#else originalFrameSize = info.compPatchpointInfo->TotalFrameSize(); originalFrameStkOffs = stkOffs; stkOffs -= originalFrameSize; +#endif } #ifdef TARGET_XARCH @@ -6606,7 +6669,8 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals() #elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - assert(compCalleeRegsPushed >= 2); + assert(compCalleeRegsPushed >= 2); // always FP/RA. + stkOffs -= (compCalleeRegsPushed << 3); #else // !TARGET_LOONGARCH64 && !TARGET_RISCV64 #ifdef TARGET_ARM @@ -7331,14 +7395,9 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals() } #endif // FEATURE_FIXED_OUT_ARGS -#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - // For LoongArch64 and RISCV64, CalleeSavedRegs are at bottom. - int pushedCount = 0; -#else // compLclFrameSize equals our negated virtual stack offset minus the pushed registers and return address // and the pushed frame pointer register which for some strange reason isn't part of 'compCalleeRegsPushed'. int pushedCount = compCalleeRegsPushed; -#endif #ifdef TARGET_ARM64 if (info.compIsVarArgs) diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp index 521e9891334339..ef3fedf5b31d32 100644 --- a/src/coreclr/jit/liveness.cpp +++ b/src/coreclr/jit/liveness.cpp @@ -1762,8 +1762,8 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR operand->SetUnusedValue(); } - // Special-case PUTARG_STK: since this operator is not considered a value, DCE will not remove - // these nodes. + // Special-case PUTARG_STK: since this operator is not considered a value, DCE will not + // remove these nodes. if (operand->OperIs(GT_PUTARG_STK)) { operand->AsPutArgStk()->gtOp1->SetUnusedValue(); diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index cb8eb5d6a97a0d..28538fc2b9053f 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -8212,6 +8212,117 @@ void Lowering::ContainCheckBitCast(GenTree* node) } } +//------------------------------------------------------------------------ +// TryLowerBlockStoreAsGcBulkCopyCall: Lower a block store node as a CORINFO_HELP_BULK_WRITEBARRIER call +// +// Arguments: +// blkNode - The block store node to lower +// +bool Lowering::TryLowerBlockStoreAsGcBulkCopyCall(GenTreeBlk* blk) +{ + if (comp->opts.OptimizationDisabled()) + { + return false; + } + + // Replace STORE_BLK (struct copy) with CORINFO_HELP_BULK_WRITEBARRIER which performs + // bulk copy for byrefs. + const unsigned bulkCopyThreshold = 4; + if (!blk->OperIs(GT_STORE_BLK) || blk->OperIsInitBlkOp() || blk->IsVolatile() || + (blk->GetLayout()->GetGCPtrCount() < bulkCopyThreshold)) + { + return false; + } + + GenTree* dest = blk->Addr(); + GenTree* data = blk->Data(); + + if (data->OperIs(GT_IND)) + { + if (data->AsIndir()->IsVolatile()) + { + return false; + } + + // Drop GT_IND nodes + BlockRange().Remove(data); + data = data->AsIndir()->Addr(); + } + else + { + assert(data->OperIs(GT_LCL_VAR, GT_LCL_FLD)); + + // Convert local to LCL_ADDR + unsigned lclOffset = data->AsLclVarCommon()->GetLclOffs(); + data->ChangeOper(GT_LCL_ADDR); + data->ChangeType(TYP_I_IMPL); + data->AsLclFld()->SetLclOffs(lclOffset); + data->ClearContained(); + } + + // Size is a constant + GenTreeIntCon* size = comp->gtNewIconNode((ssize_t)blk->GetLayout()->GetSize(), TYP_I_IMPL); + BlockRange().InsertBefore(data, size); + + // A hacky way to safely call fgMorphTree in Lower + GenTree* destPlaceholder = comp->gtNewZeroConNode(dest->TypeGet()); + GenTree* dataPlaceholder = comp->gtNewZeroConNode(genActualType(data)); + GenTree* sizePlaceholder = comp->gtNewZeroConNode(genActualType(size)); + + GenTreeCall* call = comp->gtNewHelperCallNode(CORINFO_HELP_BULK_WRITEBARRIER, TYP_VOID, destPlaceholder, + dataPlaceholder, sizePlaceholder); + comp->fgMorphArgs(call); + + LIR::Range range = LIR::SeqTree(comp, call); + GenTree* rangeStart = range.FirstNode(); + GenTree* rangeEnd = range.LastNode(); + + BlockRange().InsertBefore(blk, std::move(range)); + blk->gtBashToNOP(); + + LIR::Use destUse; + LIR::Use sizeUse; + BlockRange().TryGetUse(destPlaceholder, &destUse); + BlockRange().TryGetUse(sizePlaceholder, &sizeUse); + destUse.ReplaceWith(dest); + sizeUse.ReplaceWith(size); + destPlaceholder->SetUnusedValue(); + sizePlaceholder->SetUnusedValue(); + + LIR::Use dataUse; + BlockRange().TryGetUse(dataPlaceholder, &dataUse); + dataUse.ReplaceWith(data); + dataPlaceholder->SetUnusedValue(); + + LowerRange(rangeStart, rangeEnd); + + // Finally move all GT_PUTARG_* nodes + // Re-use the existing logic for CFG call args here + MoveCFGCallArgs(call); + + BlockRange().Remove(destPlaceholder); + BlockRange().Remove(sizePlaceholder); + BlockRange().Remove(dataPlaceholder); + + // Add implicit nullchecks for dest and data if needed: + // + auto wrapWithNullcheck = [&](GenTree* node) { + if (comp->fgAddrCouldBeNull(node)) + { + LIR::Use nodeUse; + BlockRange().TryGetUse(node, &nodeUse); + GenTree* nodeClone = comp->gtNewLclvNode(nodeUse.ReplaceWithLclVar(comp), genActualType(node)); + GenTree* nullcheck = comp->gtNewNullCheck(nodeClone, comp->compCurBB); + BlockRange().InsertAfter(nodeUse.Def(), nodeClone, nullcheck); + LowerNode(nullcheck); + } + }; + wrapWithNullcheck(dest); + wrapWithNullcheck(data); + + return true; +} + //------------------------------------------------------------------------ // LowerBlockStoreAsHelperCall: Lower a block store node as a memset/memcpy call // @@ -8347,54 +8458,57 @@ void Lowering::LowerBlockStoreAsHelperCall(GenTreeBlk* blkNode) #endif } -struct StoreCoalescingData -{ - var_types targetType; - GenTree* baseAddr; - GenTree* index; - GenTree* value; - uint32_t scale; - int offset; -}; - //------------------------------------------------------------------------ -// GetStoreCoalescingData: given a STOREIND node, get the data needed to perform -// store coalescing including pointer to the previous node. +// GetLoadStoreCoalescingData: given a STOREIND/IND node, get the data needed to perform +// store/load coalescing including pointer to the previous node. // // Arguments: // comp - the compiler instance -// ind - the STOREIND node -// data - [OUT] the data needed for store coalescing +// ind - the STOREIND/IND node +// data - [OUT] the data needed for store/load coalescing // // Return Value: // true if the data was successfully retrieved, false otherwise. -// Basically, false means that we definitely can't do store coalescing. // -static bool GetStoreCoalescingData(Compiler* comp, GenTreeStoreInd* ind, StoreCoalescingData* data) +bool Lowering::GetLoadStoreCoalescingData(GenTreeIndir* ind, LoadStoreCoalescingData* data) const { - // Don't merge volatile stores. + // Don't merge volatile load/stores. if (ind->IsVolatile()) { return false; } - // Data has to be INT_CNS, can be also VEC_CNS in future. - if (!ind->Data()->IsCnsIntOrI() && !ind->Data()->IsVectorConst()) - { - return false; - } + const bool isStore = ind->OperIs(GT_STOREIND, GT_STORE_BLK); + const bool isLoad = ind->OperIs(GT_IND); auto isNodeInvariant = [](Compiler* comp, GenTree* node, bool allowNull) { if (node == nullptr) { return allowNull; } + if (node->OperIsConst()) + { + return true; + } // We can allow bigger trees here, but it's not clear if it's worth it. return node->OperIs(GT_LCL_VAR) && !comp->lvaVarAddrExposed(node->AsLclVar()->GetLclNum()); }; + if (isStore) + { + // For stores, Data() is expected to be an invariant node + if (!isNodeInvariant(comp, ind->Data(), false)) + { + return false; + } + } + else if (!isLoad) + { + return false; + } + data->targetType = ind->TypeGet(); - data->value = ind->Data(); + data->value = isStore ? ind->Data() : nullptr; if (ind->Addr()->OperIs(GT_LEA)) { GenTree* base = ind->Addr()->AsAddrMode()->Base(); @@ -8430,12 +8544,24 @@ static bool GetStoreCoalescingData(Compiler* comp, GenTreeStoreInd* ind, StoreCo // Address is not LEA or local. return false; } + + bool isClosedRange = false; + // Make sure there are no other unexpected nodes in-between. + LIR::ReadOnlyRange range = BlockRange().GetTreeRange(ind, &isClosedRange); + if (!isClosedRange) + { + return false; + } + + data->rangeStart = range.FirstNode(); + data->rangeEnd = range.LastNode(); + return true; } //------------------------------------------------------------------------ -// LowerStoreIndirCoalescing: If the given STOREIND node is followed by a similar -// STOREIND node, try to merge them into a single store of a twice wider type. Example: +// LowerStoreIndirCoalescing: If the given IND/STOREIND node is followed by a similar +// IND/STOREIND node, try to merge them into a single store of a twice wider type. Example: // // * STOREIND int // +--* LCL_VAR byref V00 @@ -8459,7 +8585,7 @@ static bool GetStoreCoalescingData(Compiler* comp, GenTreeStoreInd* ind, StoreCo // Arguments: // ind - the current STOREIND node // -void Lowering::LowerStoreIndirCoalescing(GenTreeStoreInd* ind) +void Lowering::LowerStoreIndirCoalescing(GenTreeIndir* ind) { // LA, RISC-V and ARM32 more likely to recieve a terrible performance hit from // unaligned accesses making this optimization questionable. @@ -8469,12 +8595,9 @@ void Lowering::LowerStoreIndirCoalescing(GenTreeStoreInd* ind) return; } - // TODO-ARM64-CQ: enable TYP_REF if we find a case where it's beneficial. - // The algorithm does support TYP_REF (with null value), but it seems to be not worth - // it on ARM64 where it's pretty efficient to do "stp xzr, xzr, [addr]" to clear two - // items at once. Although, it may be profitable to do "stp q0, q0, [addr]". - if (!varTypeIsIntegral(ind) && !varTypeIsSIMD(ind)) + if (!ind->OperIs(GT_STOREIND, GT_STORE_BLK)) { + // Load coalescing is not yet supported return; } @@ -8492,24 +8615,16 @@ void Lowering::LowerStoreIndirCoalescing(GenTreeStoreInd* ind) // to get a single store of 8 bytes. do { - StoreCoalescingData currData; - StoreCoalescingData prevData; + LoadStoreCoalescingData currData; + LoadStoreCoalescingData prevData; // Get coalescing data for the current STOREIND - if (!GetStoreCoalescingData(comp, ind, &currData)) + if (!GetLoadStoreCoalescingData(ind, &currData)) { return; } - bool isClosedRange = false; - // Now we need to find the very first LIR node representing the current STOREIND - // and make sure that there are no other unexpected nodes in-between. - LIR::ReadOnlyRange currIndRange = BlockRange().GetTreeRange(ind, &isClosedRange); - if (!isClosedRange) - { - return; - } - GenTree* prevTree = currIndRange.FirstNode()->gtPrev; + GenTree* prevTree = currData.rangeStart->gtPrev; // Now we need to find the previous STOREIND, // we can ignore any NOPs or IL_OFFSETs in-between while ((prevTree != nullptr) && prevTree->OperIs(GT_NOP, GT_IL_OFFSET)) @@ -8517,47 +8632,51 @@ void Lowering::LowerStoreIndirCoalescing(GenTreeStoreInd* ind) prevTree = prevTree->gtPrev; } - // It's not a STOREIND - bail out. - if ((prevTree == nullptr) || !prevTree->OperIs(GT_STOREIND)) + // It's not a store - bail out. + if ((prevTree == nullptr) || !prevTree->OperIs(GT_STOREIND, GT_STORE_BLK)) { return; } // Get coalescing data for the previous STOREIND - GenTreeStoreInd* prevInd = prevTree->AsStoreInd(); - if (!GetStoreCoalescingData(comp, prevInd->AsStoreInd(), &prevData)) + GenTreeIndir* prevInd = prevTree->AsIndir(); + if (!GetLoadStoreCoalescingData(prevInd, &prevData)) { return; } - // Same for the previous STOREIND, make sure there are no unexpected nodes around. - LIR::ReadOnlyRange prevIndRange = BlockRange().GetTreeRange(prevInd, &isClosedRange); - if (!isClosedRange) + if (!currData.IsAddressEqual(prevData, /*ignoreOffset*/ true)) { + // Non-offset part of the address is not the same - bail out. return; } - // STOREIND aren't value nodes. - LIR::Use use; - assert(!BlockRange().TryGetUse(prevInd, &use) && !BlockRange().TryGetUse(ind, &use)); + // The same offset means that we're storing to the same location of the same width. + // Just remove the previous store then. + if (prevData.offset == currData.offset) + { + BlockRange().Remove(prevData.rangeStart, prevData.rangeEnd); + continue; + } - // BaseAddr, Index, Scale and Type all have to match. - if ((prevData.scale != currData.scale) || (prevData.targetType != currData.targetType) || - !GenTree::Compare(prevData.baseAddr, currData.baseAddr) || - !GenTree::Compare(prevData.index, currData.index)) + // TODO-ARM64-CQ: enable TYP_REF if we find a case where it's beneficial. + // The algorithm does support TYP_REF (with null value), but it seems to be not worth + // it on ARM64 where it's pretty efficient to do "stp xzr, xzr, [addr]" to clear two + // items at once. Although, it may be profitable to do "stp q0, q0, [addr]". + if (!varTypeIsIntegral(ind) && !varTypeIsSIMD(ind)) { return; } - // At this point we know that we have two consecutive STOREINDs with the same base address, - // index and scale, the only variable thing is the offset (constant) + assert(ind->OperIs(GT_STOREIND)); + assert(prevInd->OperIs(GT_STOREIND)); + assert(prevData.IsStore()); + assert(currData.IsStore()); - // The same offset means that we're storing to the same location of the same width. - // Just remove the previous store then. - if (prevData.offset == currData.offset) + // For now, only constants are supported for data. + if (!prevData.value->OperIsConst() || !currData.value->OperIsConst()) { - BlockRange().Remove(std::move(prevIndRange)); - continue; + return; } // Otherwise, the difference between two offsets has to match the size of the type. @@ -8702,11 +8821,11 @@ void Lowering::LowerStoreIndirCoalescing(GenTreeStoreInd* ind) } // We should not be here for stores requiring write barriers. - assert(!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(ind)); - assert(!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(prevInd)); + assert(!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(ind->AsStoreInd())); + assert(!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(prevInd->AsStoreInd())); // Delete previous STOREIND entirely - BlockRange().Remove(std::move(prevIndRange)); + BlockRange().Remove(prevData.rangeStart, prevData.rangeEnd); // It's not expected to be contained yet, but just in case... ind->Data()->ClearContained(); @@ -8863,6 +8982,27 @@ GenTree* Lowering::LowerIndir(GenTreeIndir* ind) } #endif +#ifdef TARGET_ARM64 + LIR::Use use; + if (ind->OperIs(GT_IND) && ind->IsVolatile() && varTypeIsFloating(ind) && BlockRange().TryGetUse(ind, &use)) + { + // Convert "IND(addr)" to "BitCast(IND(addr))" + // for volatile loads since there is no ldar for SIMD regs + var_types targetType = ind->TypeGet(); + ind->ChangeType(ind->TypeIs(TYP_DOUBLE) ? TYP_LONG : TYP_INT); + + // Now it might be eligible for some addressing modes with LDAPUR: + const bool isContainable = IsInvariantInRange(ind->Addr(), ind); + TryCreateAddrMode(ind->Addr(), isContainable, ind); + + // Wrap the resulting IND into BITCAST: + GenTree* castOp = comp->gtNewBitCastNode(targetType, ind); + BlockRange().InsertAfter(ind, castOp); + use.ReplaceWith(castOp); + return castOp; + } +#endif + // TODO-Cleanup: We're passing isContainable = true but ContainCheckIndir rejects // address containment in some cases so we end up creating trivial (reg + offfset) // or (reg + reg) LEAs that are not necessary. @@ -9413,6 +9553,7 @@ void Lowering::LowerBlockStoreCommon(GenTreeBlk* blkNode) } LowerBlockStore(blkNode); + LowerStoreIndirCoalescing(blkNode); } //------------------------------------------------------------------------ @@ -9515,6 +9656,21 @@ void Lowering::TryRetypingFloatingPointStoreToIntegerStore(GenTree* store) return; } + // Convert "STOREIND(addr, floatVal)" to "STORIND(addr, BitCast(floatVal))" + // for volatile stores since there is no stlr for SIMD regs +#ifdef TARGET_ARM64 + if (store->OperIs(GT_STOREIND) && store->AsStoreInd()->IsVolatile()) + { + GenTreeStoreInd* ind = store->AsStoreInd(); + ind->ChangeType(ind->TypeIs(TYP_DOUBLE) ? TYP_LONG : TYP_INT); + GenTree* castOp = comp->gtNewBitCastNode(ind->TypeGet(), ind->Data()); + BlockRange().InsertAfter(ind->Data(), castOp); + ind->Data() = castOp; + LowerNode(castOp); + return; + } +#endif + // We only want to transform memory stores, not definitions of candidate locals. // if (store->OperIs(GT_STORE_LCL_VAR) && !comp->lvaGetDesc(store->AsLclVar())->lvDoNotEnregister) diff --git a/src/coreclr/jit/lower.h b/src/coreclr/jit/lower.h index 055f425b664566..dc32f7941f53dc 100644 --- a/src/coreclr/jit/lower.h +++ b/src/coreclr/jit/lower.h @@ -315,6 +315,35 @@ class Lowering final : public Phase } #endif // defined(TARGET_XARCH) + struct LoadStoreCoalescingData + { + var_types targetType; + GenTree* baseAddr; + GenTree* index; + GenTree* value; + uint32_t scale; + int offset; + GenTree* rangeStart; + GenTree* rangeEnd; + + bool IsStore() const + { + return value != nullptr; + } + + bool IsAddressEqual(const LoadStoreCoalescingData& other, bool ignoreOffset) const + { + if ((scale != other.scale) || (targetType != other.targetType) || + !GenTree::Compare(baseAddr, other.baseAddr) || !GenTree::Compare(index, other.index)) + { + return false; + } + return ignoreOffset || (offset == other.offset); + } + }; + + bool GetLoadStoreCoalescingData(GenTreeIndir* ind, LoadStoreCoalescingData* data) const; + // Per tree node member functions void LowerStoreIndirCommon(GenTreeStoreInd* ind); GenTree* LowerIndir(GenTreeIndir* ind); @@ -323,7 +352,7 @@ class Lowering final : public Phase void MarkTree(GenTree* root); void UnmarkTree(GenTree* root); void LowerStoreIndir(GenTreeStoreInd* node); - void LowerStoreIndirCoalescing(GenTreeStoreInd* node); + void LowerStoreIndirCoalescing(GenTreeIndir* node); GenTree* LowerAdd(GenTreeOp* node); GenTree* LowerMul(GenTreeOp* mul); bool TryLowerAndNegativeOne(GenTreeOp* node, GenTree** nextNode); @@ -334,6 +363,7 @@ class Lowering final : public Phase void LowerBlockStore(GenTreeBlk* blkNode); void LowerBlockStoreCommon(GenTreeBlk* blkNode); void LowerBlockStoreAsHelperCall(GenTreeBlk* blkNode); + bool TryLowerBlockStoreAsGcBulkCopyCall(GenTreeBlk* blkNode); void LowerLclHeap(GenTree* node); void ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenTree* addr, GenTree* addrParent); void LowerPutArgStkOrSplit(GenTreePutArgStk* putArgNode); diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index cbdc886ee2802b..36b5e08f0afd67 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -737,6 +737,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) if (doCpObj) { + // Try to use bulk copy helper + if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode)) + { + return; + } + assert((dstAddr->TypeGet() == TYP_BYREF) || (dstAddr->TypeGet() == TYP_I_IMPL)); blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll; } @@ -1280,6 +1286,34 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) break; } + if (HWIntrinsicInfo::IsEmbeddedMaskedOperation(intrinsicId)) + { + LIR::Use use; + if (BlockRange().TryGetUse(node, &use)) + { + GenTree* user = use.User(); + // Wrap the intrinsic in ConditionalSelect only if it is not already inside another ConditionalSelect + if (!user->OperIsHWIntrinsic() || (user->AsHWIntrinsic()->GetHWIntrinsicId() != NI_Sve_ConditionalSelect)) + { + CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); + unsigned simdSize = node->GetSimdSize(); + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + GenTree* trueMask = comp->gtNewSimdAllTrueMaskNode(simdBaseJitType, simdSize); + GenTree* trueVal = node; + GenTree* falseVal = comp->gtNewZeroConNode(simdType); + + GenTreeHWIntrinsic* condSelNode = + comp->gtNewSimdHWIntrinsicNode(simdType, trueMask, trueVal, falseVal, NI_Sve_ConditionalSelect, + simdBaseJitType, simdSize); + + BlockRange().InsertBefore(node, trueMask); + BlockRange().InsertBefore(node, falseVal); + BlockRange().InsertAfter(node, condSelNode); + use.ReplaceWith(condSelNode); + } + } + } + ContainCheckHWIntrinsic(node); return node->gtNext; } @@ -3267,6 +3301,10 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_CreateTrueMaskUInt16: case NI_Sve_CreateTrueMaskUInt32: case NI_Sve_CreateTrueMaskUInt64: + case NI_Sve_Count16BitElements: + case NI_Sve_Count32BitElements: + case NI_Sve_Count64BitElements: + case NI_Sve_Count8BitElements: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op1)); if (intrin.op1->IsCnsIntOrI()) @@ -3275,6 +3313,45 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) } break; + case NI_Sve_ConditionalSelect: + { + assert(intrin.numOperands == 3); + GenTree* op1 = intrin.op1; + GenTree* op2 = intrin.op2; + GenTree* op3 = intrin.op3; + + // Handle op1 + if (op1->IsVectorZero()) + { + // When we are merging with zero, we can specialize + // and avoid instantiating the vector constant. + MakeSrcContained(node, op1); + } + + // Handle op2 + if (op2->OperIsHWIntrinsic()) + { + uint32_t maskSize = genTypeSize(node->GetSimdBaseType()); + uint32_t operSize = genTypeSize(op2->AsHWIntrinsic()->GetSimdBaseType()); + + if ((maskSize == operSize) && IsInvariantInRange(op2, node)) + { + MakeSrcContained(node, op2); + op2->MakeEmbMaskOp(); + } + } + + // Handle op3 + if (op3->IsVectorZero()) + { + // When we are merging with zero, we can specialize + // and avoid instantiating the vector constant. + MakeSrcContained(node, op3); + } + + break; + } + default: unreached(); } diff --git a/src/coreclr/jit/lowerloongarch64.cpp b/src/coreclr/jit/lowerloongarch64.cpp index 4e826be0b22574..d3552e478fdfef 100644 --- a/src/coreclr/jit/lowerloongarch64.cpp +++ b/src/coreclr/jit/lowerloongarch64.cpp @@ -370,6 +370,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) // CopyObj or CopyBlk if (doCpObj) { + // Try to use bulk copy helper + if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode)) + { + return; + } + assert((dstAddr->TypeGet() == TYP_BYREF) || (dstAddr->TypeGet() == TYP_I_IMPL)); blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll; } diff --git a/src/coreclr/jit/lowerriscv64.cpp b/src/coreclr/jit/lowerriscv64.cpp index aa8342ee1af5a4..5b0bd99df484f3 100644 --- a/src/coreclr/jit/lowerriscv64.cpp +++ b/src/coreclr/jit/lowerriscv64.cpp @@ -319,6 +319,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) // CopyObj or CopyBlk if (doCpObj) { + // Try to use bulk copy helper + if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode)) + { + return; + } + assert((dstAddr->TypeGet() == TYP_BYREF) || (dstAddr->TypeGet() == TYP_I_IMPL)); blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindCpObjUnroll; } diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 5a9b12ca4aa274..156992b89e9d46 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -457,6 +457,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode) if (doCpObj) { + // Try to use bulk copy helper + if (TryLowerBlockStoreAsGcBulkCopyCall(blkNode)) + { + return; + } + assert((dstAddr->TypeGet() == TYP_BYREF) || (dstAddr->TypeGet() == TYP_I_IMPL)); // If we have a long enough sequence of slots that do not require write barriers then @@ -2970,7 +2976,7 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* node) } //---------------------------------------------------------------------------------------------- -// Lowering::LowerHWIntrinsicCndSel: Lowers an AVX512 TernaryLogic call +// Lowering::LowerHWIntrinsicTernaryLogic: Lowers an AVX512 TernaryLogic call // // Arguments: // node - The hardware intrinsic node. @@ -10137,7 +10143,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) // contained and not a memory operand and know to invoke the special handling // so that the embedded masking can work as expected. - if (op2->isEvexEmbeddedMaskingCompatibleHWIntrinsic()) + if (op2->isEmbeddedMaskingCompatibleHWIntrinsic()) { uint32_t maskSize = genTypeSize(simdBaseType); uint32_t operSize = genTypeSize(op2->AsHWIntrinsic()->GetSimdBaseType()); diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index ebcb21fff18bc3..685186550793b7 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -271,20 +271,31 @@ regMaskTP LinearScan::lowSIMDRegs() #endif } -void LinearScan::updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition) +void LinearScan::updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition, RefPosition* nextKill) { - LsraLocation nextLocation; + LsraLocation nextLocation = nextRefPosition == nullptr ? MaxLocation : nextRefPosition->nodeLocation; - if (nextRefPosition == nullptr) + RefPosition* kill = nextKill; + while ((kill != nullptr) && (kill->nodeLocation < nextLocation)) + { + if ((kill->registerAssignment & genRegMask(regRecord->regNum)) != RBM_NONE) + { + nextLocation = kill->nodeLocation; + break; + } + + kill = kill->nextRefPosition; + } + + if (nextLocation == MaxLocation) { - nextLocation = MaxLocation; fixedRegs &= ~genRegMask(regRecord->regNum); } else { - nextLocation = nextRefPosition->nodeLocation; fixedRegs |= genRegMask(regRecord->regNum); } + nextFixedRef[regRecord->regNum] = nextLocation; } @@ -712,6 +723,8 @@ LinearScan::LinearScan(Compiler* theCompiler) , intervals(theCompiler->getAllocator(CMK_LSRA_Interval)) , allocationPassComplete(false) , refPositions(theCompiler->getAllocator(CMK_LSRA_RefPosition)) + , killHead(nullptr) + , killTail(&killHead) , listNodePool(theCompiler) { availableRegCount = ACTUAL_REG_COUNT; @@ -3948,6 +3961,41 @@ void LinearScan::unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPositio } } +//------------------------------------------------------------------------ +// processKills: Handle that some registers are being killed. +// +// Arguments: +// killRefPosition - The RefPosition for the kill +// +void LinearScan::processKills(RefPosition* killRefPosition) +{ + RefPosition* nextKill = killRefPosition->nextRefPosition; + + regMaskTP killedRegs = killRefPosition->registerAssignment; + while (killedRegs != RBM_NONE) + { + regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs); + RegRecord* regRecord = getRegisterRecord(killedReg); + Interval* assignedInterval = regRecord->assignedInterval; + if (assignedInterval != nullptr) + { + unassignPhysReg(regRecord, assignedInterval->recentRefPosition); + clearConstantReg(regRecord->regNum, assignedInterval->registerType); + makeRegAvailable(regRecord->regNum, assignedInterval->registerType); + } + + assert((nextFixedRef[killedReg] == killRefPosition->nodeLocation) || (killedReg >= AVAILABLE_REG_COUNT)); + RefPosition* regNextRefPos = regRecord->recentRefPosition == nullptr + ? regRecord->firstRefPosition + : regRecord->recentRefPosition->nextRefPosition; + updateNextFixedRef(regRecord, regNextRefPos, nextKill); + } + + regsBusyUntilKill &= ~killRefPosition->registerAssignment; + INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KILL_REGS, nullptr, REG_NA, nullptr, NONE, + killRefPosition->registerAssignment)); +} + //------------------------------------------------------------------------ // spillGCRefs: Spill any GC-type intervals that are currently in registers. // @@ -4865,7 +4913,7 @@ void LinearScan::allocateRegistersMinimal() { RegRecord* physRegRecord = getRegisterRecord(reg); physRegRecord->recentRefPosition = nullptr; - updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition); + updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition, killHead); assert(physRegRecord->assignedInterval == nullptr); } @@ -4886,7 +4934,8 @@ void LinearScan::allocateRegistersMinimal() } #endif // DEBUG - BasicBlock* currentBlock = nullptr; + BasicBlock* currentBlock = nullptr; + RefPosition* nextKill = killHead; LsraLocation prevLocation = MinLocation; regMaskTP regsToFree = RBM_NONE; @@ -4906,8 +4955,6 @@ void LinearScan::allocateRegistersMinimal() for (RefPosition& currentRefPosition : refPositions) { - RefPosition* nextRefPosition = currentRefPosition.nextRefPosition; - // TODO: Can we combine this with the freeing of registers below? It might // mess with the dump, since this was previously being done before the call below // to dumpRegRecords. @@ -5017,7 +5064,7 @@ void LinearScan::allocateRegistersMinimal() } else { - assert((refType == RefTypeBB) || (refType == RefTypeKillGCRefs)); + assert((refType == RefTypeBB) || (refType == RefTypeKill) || (refType == RefTypeKillGCRefs)); } #ifdef DEBUG @@ -5066,65 +5113,59 @@ void LinearScan::allocateRegistersMinimal() continue; } + if (refType == RefTypeKill) + { + assert(nextKill == ¤tRefPosition); + processKills(¤tRefPosition); + nextKill = nextKill->nextRefPosition; + continue; + } + if (refType == RefTypeKillGCRefs) { spillGCRefs(¤tRefPosition); continue; } - if (currentRefPosition.isPhysRegRef) + if (refType == RefTypeFixedReg) { RegRecord* regRecord = currentRefPosition.getReg(); Interval* assignedInterval = regRecord->assignedInterval; - updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition); + updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition, nextKill); - // If this is a FixedReg, disassociate any inactive constant interval from this register. - // Otherwise, do nothing. - if (refType == RefTypeFixedReg) + // This is a FixedReg. Disassociate any inactive constant interval from this register. + if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant) { - if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant) - { - clearConstantReg(regRecord->regNum, assignedInterval->registerType); - regRecord->assignedInterval = nullptr; - spillCost[regRecord->regNum] = 0; + clearConstantReg(regRecord->regNum, assignedInterval->registerType); + regRecord->assignedInterval = nullptr; + spillCost[regRecord->regNum] = 0; #ifdef TARGET_ARM - // Update overlapping floating point register for TYP_DOUBLE - if (assignedInterval->registerType == TYP_DOUBLE) - { - RegRecord* otherRegRecord = findAnotherHalfRegRec(regRecord); - assert(otherRegRecord->assignedInterval == assignedInterval); - otherRegRecord->assignedInterval = nullptr; - spillCost[otherRegRecord->regNum] = 0; - } -#endif // TARGET_ARM - } - regsInUseThisLocation |= currentRefPosition.registerAssignment; - INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FIXED_REG, nullptr, currentRefPosition.assignedReg())); - -#ifdef SWIFT_SUPPORT - if (currentRefPosition.delayRegFree) + // Update overlapping floating point register for TYP_DOUBLE + if (assignedInterval->registerType == TYP_DOUBLE) { - regsInUseNextLocation |= currentRefPosition.registerAssignment; + RegRecord* otherRegRecord = findAnotherHalfRegRec(regRecord); + assert(otherRegRecord->assignedInterval == assignedInterval); + otherRegRecord->assignedInterval = nullptr; + spillCost[otherRegRecord->regNum] = 0; } -#endif // SWIFT_SUPPORT +#endif // TARGET_ARM } - else + regsInUseThisLocation |= currentRefPosition.registerAssignment; + INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FIXED_REG, nullptr, currentRefPosition.assignedReg())); + +#ifdef SWIFT_SUPPORT + if (currentRefPosition.delayRegFree) { - assert(refType == RefTypeKill); - if (assignedInterval != nullptr) - { - unassignPhysReg(regRecord, assignedInterval->recentRefPosition); - clearConstantReg(regRecord->regNum, assignedInterval->registerType); - makeRegAvailable(regRecord->regNum, assignedInterval->registerType); - } - clearRegBusyUntilKill(regRecord->regNum); - INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum)); + regsInUseNextLocation |= currentRefPosition.registerAssignment; } +#endif // SWIFT_SUPPORT continue; } + assert(!currentRefPosition.isPhysRegRef); + regNumber assignedRegister = REG_NA; assert(currentRefPosition.isIntervalRef()); @@ -5532,7 +5573,7 @@ void LinearScan::allocateRegisters() { RegRecord* physRegRecord = getRegisterRecord(reg); physRegRecord->recentRefPosition = nullptr; - updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition); + updateNextFixedRef(physRegRecord, physRegRecord->firstRefPosition, killHead); // Is this an incoming arg register? (Note that we don't, currently, consider reassigning // an incoming arg register as having spill cost.) @@ -5573,7 +5614,8 @@ void LinearScan::allocateRegisters() } #endif // DEBUG - BasicBlock* currentBlock = nullptr; + BasicBlock* currentBlock = nullptr; + RefPosition* nextKill = killHead; LsraLocation prevLocation = MinLocation; regMaskTP regsToFree = RBM_NONE; @@ -5725,7 +5767,7 @@ void LinearScan::allocateRegisters() } else { - assert((refType == RefTypeBB) || (refType == RefTypeKillGCRefs)); + assert((refType == RefTypeBB) || (refType == RefTypeKill) || (refType == RefTypeKillGCRefs)); } #ifdef DEBUG @@ -5781,65 +5823,59 @@ void LinearScan::allocateRegisters() continue; } + if (refType == RefTypeKill) + { + assert(nextKill == ¤tRefPosition); + processKills(¤tRefPosition); + nextKill = nextKill->nextRefPosition; + continue; + } + if (refType == RefTypeKillGCRefs) { spillGCRefs(¤tRefPosition); continue; } - if (currentRefPosition.isPhysRegRef) + if (refType == RefTypeFixedReg) { RegRecord* regRecord = currentRefPosition.getReg(); Interval* assignedInterval = regRecord->assignedInterval; - updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition); + updateNextFixedRef(regRecord, currentRefPosition.nextRefPosition, nextKill); - // If this is a FixedReg, disassociate any inactive constant interval from this register. - // Otherwise, do nothing. - if (refType == RefTypeFixedReg) + // This is a FixedReg. Disassociate any inactive constant interval from this register. + if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant) { - if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant) - { - clearConstantReg(regRecord->regNum, assignedInterval->registerType); - regRecord->assignedInterval = nullptr; - spillCost[regRecord->regNum] = 0; + clearConstantReg(regRecord->regNum, assignedInterval->registerType); + regRecord->assignedInterval = nullptr; + spillCost[regRecord->regNum] = 0; #ifdef TARGET_ARM - // Update overlapping floating point register for TYP_DOUBLE - if (assignedInterval->registerType == TYP_DOUBLE) - { - RegRecord* otherRegRecord = findAnotherHalfRegRec(regRecord); - assert(otherRegRecord->assignedInterval == assignedInterval); - otherRegRecord->assignedInterval = nullptr; - spillCost[otherRegRecord->regNum] = 0; - } -#endif // TARGET_ARM - } - regsInUseThisLocation |= currentRefPosition.registerAssignment; - INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FIXED_REG, nullptr, currentRefPosition.assignedReg())); - -#ifdef SWIFT_SUPPORT - if (currentRefPosition.delayRegFree) + // Update overlapping floating point register for TYP_DOUBLE + if (assignedInterval->registerType == TYP_DOUBLE) { - regsInUseNextLocation |= currentRefPosition.registerAssignment; + RegRecord* otherRegRecord = findAnotherHalfRegRec(regRecord); + assert(otherRegRecord->assignedInterval == assignedInterval); + otherRegRecord->assignedInterval = nullptr; + spillCost[otherRegRecord->regNum] = 0; } -#endif // SWIFT_SUPPORT +#endif // TARGET_ARM } - else + regsInUseThisLocation |= currentRefPosition.registerAssignment; + INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FIXED_REG, nullptr, currentRefPosition.assignedReg())); + +#ifdef SWIFT_SUPPORT + if (currentRefPosition.delayRegFree) { - assert(refType == RefTypeKill); - if (assignedInterval != nullptr) - { - unassignPhysReg(regRecord, assignedInterval->recentRefPosition); - clearConstantReg(regRecord->regNum, assignedInterval->registerType); - makeRegAvailable(regRecord->regNum, assignedInterval->registerType); - } - clearRegBusyUntilKill(regRecord->regNum); - INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum)); + regsInUseNextLocation |= currentRefPosition.registerAssignment; } +#endif // SWIFT_SUPPORT continue; } + assert(!currentRefPosition.isPhysRegRef); + // If this is an exposed use, do nothing - this is merely a placeholder to attempt to // ensure that a register is allocated for the full lifetime. The resolution logic // will take care of moving to the appropriate register if needed. @@ -7391,7 +7427,6 @@ void LinearScan::insertCopyOrReload(BasicBlock* block, GenTree* tree, unsigned m // child needs to be copied or reloaded to that reg. if (parent->IsCopyOrReload()) { - noway_assert(parent->OperGet() == oper); noway_assert(tree->IsMultiRegNode()); GenTreeCopyOrReload* copyOrReload = parent->AsCopyOrReload(); noway_assert(copyOrReload->GetRegNumByIdx(multiRegIdx) == REG_NA); @@ -7972,7 +8007,6 @@ void LinearScan::resolveRegisters() case RefTypeDef: // These are the ones we're interested in break; - case RefTypeKill: case RefTypeFixedReg: // These require no handling at resolution time assert(currentRefPosition->referent != nullptr); @@ -7988,6 +8022,7 @@ void LinearScan::resolveRegisters() currentRefPosition->getInterval()->getVarIndex(compiler))); currentRefPosition->referent->recentRefPosition = currentRefPosition; continue; + case RefTypeKill: case RefTypeKillGCRefs: // No action to take at resolution time, and no interval to update recentRefPosition for. continue; @@ -8106,7 +8141,7 @@ void LinearScan::resolveRegisters() assert(currentRefPosition->isIntervalRef()); if (currentRefPosition->getInterval()->isInternal) { - treeNode->gtRsvdRegs |= currentRefPosition->registerAssignment; + compiler->codeGen->internalRegisters.Add(treeNode, currentRefPosition->registerAssignment); } else { @@ -8918,7 +8953,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) GenTree* switchTable = LIR::AsRange(block).LastNode(); assert(switchTable != nullptr && switchTable->OperGet() == GT_SWITCH_TABLE); - consumedRegs = switchTable->gtRsvdRegs; + consumedRegs = compiler->codeGen->internalRegisters.GetAll(switchTable); GenTree* op1 = switchTable->gtGetOp1(); GenTree* op2 = switchTable->gtGetOp2(); noway_assert(op1 != nullptr && op2 != nullptr); @@ -10937,7 +10972,7 @@ void LinearScan::TupleStyleDump(LsraTupleDumpMode mode) printf("\n Kill: "); killPrinted = true; } - printf(getRegName(currentRefPosition->assignedReg())); + compiler->dumpRegMask(currentRefPosition->registerAssignment); printf(" "); break; case RefTypeFixedReg: @@ -10965,8 +11000,12 @@ void LinearScan::TupleStyleDump(LsraTupleDumpMode mode) printf("\n\n"); } -void LinearScan::dumpLsraAllocationEvent( - LsraDumpEvent event, Interval* interval, regNumber reg, BasicBlock* currentBlock, RegisterScore registerScore) +void LinearScan::dumpLsraAllocationEvent(LsraDumpEvent event, + Interval* interval, + regNumber reg, + BasicBlock* currentBlock, + RegisterScore registerScore, + regMaskTP regMask) { if (!(VERBOSE)) { @@ -11171,6 +11210,15 @@ void LinearScan::dumpLsraAllocationEvent( printf("UVRes %-4s ", getRegName(reg)); break; + case LSRA_EVENT_KILL_REGS: + dumpRefPositionShort(activeRefPosition, currentBlock); + printf("None "); + dspRegMask(regMask); + printf("\n"); + dumpRefPositionShort(activeRefPosition, currentBlock); + printf(" "); + break; + // We currently don't dump anything for these events. case LSRA_EVENT_DEFUSE_FIXED_DELAY_USE: case LSRA_EVENT_SPILL_EXTENDED_LIFETIME: @@ -11560,7 +11608,7 @@ void LinearScan::dumpRefPositionShort(RefPosition* refPosition, BasicBlock* curr } else { - assert(refPosition->refType == RefTypeKillGCRefs); + assert((refPosition->refType == RefTypeKill) || (refPosition->refType == RefTypeKillGCRefs)); // There's no interval or reg name associated with this. printf(regNameFormat, " "); printf(" %s ", getRefTypeShortName(refPosition->refType)); @@ -11726,8 +11774,6 @@ void LinearScan::verifyFreeRegisters(regMaskTP regsToFree) assert(nextIntervalRef[reg] == MaxLocation); assert(spillCost[reg] == 0); } - LsraLocation thisNextFixedRef = physRegRecord->getNextRefLocation(); - assert(nextFixedRef[reg] == thisNextFixedRef); #ifdef TARGET_ARM // If this is occupied by a double interval, skip the corresponding float reg. if ((assignedInterval != nullptr) && (assignedInterval->registerType == TYP_DOUBLE)) @@ -11933,10 +11979,10 @@ void LinearScan::verifyFinalAllocation() break; case RefTypeKill: - assert(regRecord != nullptr); - assert(regRecord->assignedInterval == nullptr); - dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock); + dumpLsraAllocationEvent(LSRA_EVENT_KILL_REGS, nullptr, REG_NA, currentBlock, NONE, + currentRefPosition.registerAssignment); break; + case RefTypeFixedReg: assert(regRecord != nullptr); dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock); @@ -13258,18 +13304,12 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* current else if (refPosition->isFixedRegRef && nextRefPos != nullptr && RefTypeIsUse(nextRefPos->refType) && !nextRefPos->isFixedRegRef && genMaxOneBit(refPosition->registerAssignment)) { - regNumber defReg = refPosition->assignedReg(); - RegRecord* defRegRecord = linearScan->getRegisterRecord(defReg); - - RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition; - assert(currFixedRegRefPosition != nullptr && - currFixedRegRefPosition->nodeLocation == refPosition->nodeLocation); + regNumber defReg = refPosition->assignedReg(); // If there is another fixed reference to this register before the use, change the candidates // on this RefPosition to include that of nextRefPos. - RefPosition* nextFixedRegRefPosition = defRegRecord->getNextRefPosition(); - if (nextFixedRegRefPosition != nullptr && - nextFixedRegRefPosition->nodeLocation <= nextRefPos->getRefEndLocation()) + unsigned nextFixedRegRefLocation = linearScan->getNextFixedRef(defReg, currentInterval->registerType); + if (nextFixedRegRefLocation <= nextRefPos->getRefEndLocation()) { candidates |= nextRefPos->registerAssignment; if (preferences == refPosition->registerAssignment) @@ -13724,18 +13764,12 @@ regMaskTP LinearScan::RegisterSelection::selectMinimal(Interval* else if (refPosition->isFixedRegRef && nextRefPos != nullptr && RefTypeIsUse(nextRefPos->refType) && !nextRefPos->isFixedRegRef && genMaxOneBit(refPosition->registerAssignment)) { - regNumber defReg = refPosition->assignedReg(); - RegRecord* defRegRecord = linearScan->getRegisterRecord(defReg); - - RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition; - assert(currFixedRegRefPosition != nullptr && - currFixedRegRefPosition->nodeLocation == refPosition->nodeLocation); + regNumber defReg = refPosition->assignedReg(); // If there is another fixed reference to this register before the use, change the candidates // on this RefPosition to include that of nextRefPos. - RefPosition* nextFixedRegRefPosition = defRegRecord->getNextRefPosition(); - if (nextFixedRegRefPosition != nullptr && - nextFixedRegRefPosition->nodeLocation <= nextRefPos->getRefEndLocation()) + unsigned nextFixedRegRefLocation = linearScan->getNextFixedRef(defReg, currentInterval->registerType); + if (nextFixedRegRefLocation <= nextRefPos->getRefEndLocation()) { candidates |= nextRefPos->registerAssignment; } diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index 797c9d69c91d8f..09f8b8d63e581a 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1083,8 +1083,7 @@ class LinearScan : public LinearScanInterface // insert refpositions representing prolog zero-inits which will be added later void insertZeroInitRefPositions(); - // add physreg refpositions for a tree node, based on calling convention and instruction selection predictions - void addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, RefType refType, bool isLastUse); + void addKillForRegs(regMaskTP mask, LsraLocation currentLoc); void resolveConflictingDefAndUse(Interval* interval, RefPosition* defRefPosition); @@ -1262,6 +1261,7 @@ class LinearScan : public LinearScanInterface void setIntervalAsSplit(Interval* interval); void spillInterval(Interval* interval, RefPosition* fromRefPosition DEBUGARG(RefPosition* toRefPosition)); + void processKills(RefPosition* killRefPosition); void spillGCRefs(RefPosition* killRefPosition); /***************************************************************************** @@ -1581,6 +1581,7 @@ class LinearScan : public LinearScanInterface LSRA_EVENT_FREE_REGS, LSRA_EVENT_UPPER_VECTOR_SAVE, LSRA_EVENT_UPPER_VECTOR_RESTORE, + LSRA_EVENT_KILL_REGS, // Characteristics of the current RefPosition LSRA_EVENT_INCREMENT_RANGE_END, // ??? @@ -1606,7 +1607,8 @@ class LinearScan : public LinearScanInterface Interval* interval = nullptr, regNumber reg = REG_NA, BasicBlock* currentBlock = nullptr, - RegisterScore registerScore = NONE); + RegisterScore registerScore = NONE, + regMaskTP regMask = RBM_NONE); void validateIntervals(); @@ -1733,6 +1735,11 @@ class LinearScan : public LinearScanInterface // Ordered list of RefPositions RefPositionList refPositions; + // Head of linked list of RefTypeKill ref positions + RefPosition* killHead; + // Tail slot of linked list of RefTypeKill ref positions + RefPosition** killTail; + // Per-block variable location mappings: an array indexed by block number that yields a // pointer to an array of regNumber, one per variable. VarToRegMap* inVarToRegMaps; @@ -1897,7 +1904,7 @@ class LinearScan : public LinearScanInterface regMaskTP fixedRegs; LsraLocation nextFixedRef[REG_COUNT]; - void updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition); + void updateNextFixedRef(RegRecord* regRecord, RefPosition* nextRefPosition, RefPosition* nextKill); LsraLocation getNextFixedRef(regNumber regNum, var_types regType) { LsraLocation loc = nextFixedRef[regNum]; @@ -2055,6 +2062,7 @@ class LinearScan : public LinearScanInterface #endif int BuildPutArgReg(GenTreeUnOp* node); int BuildCall(GenTreeCall* call); + void MarkSwiftErrorBusyForCall(GenTreeCall* call); int BuildCmp(GenTree* tree); int BuildCmpOperands(GenTree* tree); int BuildBlockStore(GenTreeBlk* blkNode); @@ -2717,7 +2725,7 @@ class RefPosition bool IsPhysRegRef() { - return ((refType == RefTypeFixedReg) || (refType == RefTypeKill)); + return (refType == RefTypeFixedReg); } void setRegOptional(bool val) diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index dfcebf4392c53c..6ea3ad27706cea 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1464,6 +1464,10 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou case NI_Sve_CreateTrueMaskUInt16: case NI_Sve_CreateTrueMaskUInt32: case NI_Sve_CreateTrueMaskUInt64: + case NI_Sve_Count16BitElements: + case NI_Sve_Count32BitElements: + case NI_Sve_Count64BitElements: + case NI_Sve_Count8BitElements: needBranchTargetReg = !intrin.op1->isContainedIntOrIImmed(); break; diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index c2b8b74406584e..64bbe23b06a667 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -181,16 +181,24 @@ int LinearScan::BuildCall(GenTreeCall* call) } else if (call->IsR2ROrVirtualStubRelativeIndir()) { - // For R2R and VSD we have stub address in REG_R2R_INDIRECT_PARAM - // and will load call address into the temp register from this register. - regMaskTP candidates = RBM_NONE; if (call->IsFastTailCall()) { - candidates = allRegs(TYP_INT) & RBM_INT_CALLEE_TRASH; + // For R2R and VSD we have stub address in REG_R2R_INDIRECT_PARAM + // and will load call address into the temp register from this register. + regMaskTP candidates = allRegs(TYP_INT) & RBM_INT_CALLEE_TRASH; assert(candidates != RBM_NONE); + buildInternalIntRegisterDefForNode(call, candidates); + } + else + { + // For arm64 we can use lr for non-tailcalls so we skip the + // internal register as a TP optimization. We could do the same for + // arm32, but loading into lr cannot be encoded in 2 bytes, so + // another register is usually better. +#ifdef TARGET_ARM + buildInternalIntRegisterDefForNode(call); +#endif } - - buildInternalIntRegisterDefForNode(call, candidates); } #ifdef TARGET_ARM else @@ -396,23 +404,7 @@ int LinearScan::BuildCall(GenTreeCall* call) #ifdef SWIFT_SUPPORT if (call->HasSwiftErrorHandling()) { - // Tree is a Swift call with error handling; error register should have been killed - assert((killMask & RBM_SWIFT_ERROR) != 0); - - // After a Swift call that might throw returns, we expect the error register to be consumed - // by a GT_SWIFT_ERROR node. However, we want to ensure the error register won't be trashed - // before GT_SWIFT_ERROR can consume it. - // (For example, the PInvoke epilog comes before the error register store.) - // To do so, delay the freeing of the error register until the next node. - // This only works if the next node after the call is the GT_SWIFT_ERROR node. - // (InsertPInvokeCallEpilog should have moved the GT_SWIFT_ERROR node during lowering.) - assert(call->gtNext != nullptr); - assert(call->gtNext->OperIs(GT_SWIFT_ERROR)); - - // We could use RefTypeKill, but RefTypeFixedReg is used less commonly, so the check for delayRegFree - // during register allocation should be cheaper in terms of TP. - RefPosition* pos = newRefPosition(REG_SWIFT_ERROR, currentLoc, RefTypeFixedReg, call, RBM_SWIFT_ERROR); - setDelayFree(pos); + MarkSwiftErrorBusyForCall(call); } #endif // SWIFT_SUPPORT diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 3ee0f88ee2214f..41b375acd43929 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -498,7 +498,7 @@ void LinearScan::associateRefPosWithInterval(RefPosition* rp) } else { - assert((rp->refType == RefTypeBB) || (rp->refType == RefTypeKillGCRefs)); + assert((rp->refType == RefTypeBB) || (rp->refType == RefTypeKillGCRefs) || (rp->refType == RefTypeKill)); } } @@ -570,7 +570,7 @@ RefPosition* LinearScan::newRefPosition(Interval* theInterval, } else { - assert(theRefType == RefTypeBB || theRefType == RefTypeKillGCRefs); + assert(theRefType == RefTypeBB || theRefType == RefTypeKillGCRefs || theRefType == RefTypeKill); } #ifdef DEBUG if (theInterval != nullptr && regType(theInterval->registerType) == FloatRegisterType) @@ -689,18 +689,14 @@ bool LinearScan::isContainableMemoryOp(GenTree* node) } //------------------------------------------------------------------------ -// addRefsForPhysRegMask: Adds RefPositions of the given type for all the registers in 'mask'. +// addKillForRegs: Adds a RefTypeKill ref position for the given registers. // // Arguments: // mask - the mask (set) of registers. // currentLoc - the location at which they should be added -// refType - the type of refposition -// isLastUse - true IFF this is a last use of the register // -void LinearScan::addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, RefType refType, bool isLastUse) +void LinearScan::addKillForRegs(regMaskTP mask, LsraLocation currentLoc) { - assert(refType == RefTypeKill); - // The mask identifies a set of registers that will be used during // codegen. Mark these as modified here, so when we do final frame // layout, we'll know about all these registers. This is especially @@ -712,19 +708,10 @@ void LinearScan::addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, // modified until codegen, which is too late. compiler->codeGen->regSet.rsSetRegsModified(mask DEBUGARG(true)); - for (regMaskTP candidates = mask; candidates != RBM_NONE;) - { - regNumber reg = genFirstRegNumFromMaskAndToggle(candidates); - // This assumes that these are all "special" RefTypes that - // don't need to be recorded on the tree (hence treeNode is nullptr) - RefPosition* pos = newRefPosition(reg, currentLoc, refType, nullptr, - genRegMask(reg)); // This MUST occupy the physical register (obviously) + RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeKill, nullptr, mask); - if (isLastUse) - { - pos->lastUse = true; - } - } + *killTail = pos; + killTail = &pos->nextRefPosition; } //------------------------------------------------------------------------ @@ -1127,7 +1114,7 @@ bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLo if (killMask != RBM_NONE) { - addRefsForPhysRegMask(killMask, currentLoc, RefTypeKill, true); + addKillForRegs(killMask, currentLoc); // TODO-CQ: It appears to be valuable for both fp and int registers to avoid killing the callee // save regs on infrequently executed paths. However, it results in a large number of asmDiffs, @@ -1730,10 +1717,6 @@ int LinearScan::ComputeAvailableSrcCount(GenTree* node) // void LinearScan::buildRefPositionsForNode(GenTree* tree, LsraLocation currentLoc) { - // The set of internal temporary registers used by this node are stored in the - // gtRsvdRegs register mask. Clear it out. - tree->gtRsvdRegs = RBM_NONE; - #ifdef DEBUG if (VERBOSE) { @@ -2550,7 +2533,7 @@ void LinearScan::buildIntervals() if ((block == compiler->fgFirstBB) && compiler->lvaHasAnySwiftStackParamToReassemble()) { assert(compiler->fgFirstBBisScratch()); - addRefsForPhysRegMask(genRegMask(REG_SCRATCH), currentLoc + 1, RefTypeKill, true); + addKillForRegs(genRegMask(REG_SCRATCH), currentLoc + 1); currentLoc += 2; } @@ -2568,7 +2551,7 @@ void LinearScan::buildIntervals() // Poisoning uses REG_SCRATCH for small vars and memset helper for big vars. killed = genRegMask(REG_SCRATCH) | compiler->compHelperCallKillSet(CORINFO_HELP_NATIVE_MEMSET); #endif - addRefsForPhysRegMask(killed, currentLoc + 1, RefTypeKill, true); + addKillForRegs(killed, currentLoc + 1); currentLoc += 2; } @@ -3489,6 +3472,16 @@ int LinearScan::BuildOperandUses(GenTree* node, regMaskTP candidates) if (numArgs != 1) { +#ifdef TARGET_ARM64 + if (HWIntrinsicInfo::IsScalable(hwintrinsic->GetHWIntrinsicId())) + { + for (size_t argNum = 1; argNum <= numArgs; argNum++) + { + BuildOperandUses(hwintrinsic->Op(argNum), candidates); + } + return (int)numArgs; + } +#endif assert(numArgs == 2); assert(hwintrinsic->Op(2)->isContained()); assert(hwintrinsic->Op(2)->IsCnsIntOrI()); @@ -4486,3 +4479,36 @@ int LinearScan::BuildCmpOperands(GenTree* tree) srcCount += BuildOperandUses(op2, op2Candidates); return srcCount; } + +#ifdef SWIFT_SUPPORT +//------------------------------------------------------------------------ +// MarkSwiftErrorBusyForCall: Given a call set the appropriate RefTypeFixedReg +// RefPosition for the Swift error register as delay free to ensure the error +// register does not get allocated by LSRA before it has been consumed. +// +// Arguments: +// call - The call node +// +void LinearScan::MarkSwiftErrorBusyForCall(GenTreeCall* call) +{ + assert(call->HasSwiftErrorHandling()); + // After a Swift call that might throw returns, we expect the error register to be consumed + // by a GT_SWIFT_ERROR node. However, we want to ensure the error register won't be trashed + // before GT_SWIFT_ERROR can consume it. + // (For example, by LSRA allocating the call's result to the same register.) + // To do so, delay the freeing of the error register until the next node. + // This only works if the next node after the call is the GT_SWIFT_ERROR node. + // (LowerNonvirtPinvokeCall should have moved the GT_SWIFT_ERROR node.) + assert(call->gtNext != nullptr); + assert(call->gtNext->OperIs(GT_SWIFT_ERROR)); + + // Conveniently we model the zeroing of the register as a non-standard constant zero argument, + // which will have created a RefPosition corresponding to the use of the error at the location + // of the uses. Marking this RefPosition as delay freed has the effect of keeping the register + // busy at the location of the definition of the call. + RegRecord* swiftErrorRegRecord = getRegisterRecord(REG_SWIFT_ERROR); + assert((swiftErrorRegRecord != nullptr) && (swiftErrorRegRecord->lastRefPosition != nullptr) && + (swiftErrorRegRecord->lastRefPosition->nodeLocation == currentLoc)); + setDelayFree(swiftErrorRegRecord->lastRefPosition); +} +#endif diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 6abc86aab0ed5e..3d19214f8acbdd 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -1380,23 +1380,7 @@ int LinearScan::BuildCall(GenTreeCall* call) #ifdef SWIFT_SUPPORT if (call->HasSwiftErrorHandling()) { - // Tree is a Swift call with error handling; error register should have been killed - assert((killMask & RBM_SWIFT_ERROR) != 0); - - // After a Swift call that might throw returns, we expect the error register to be consumed - // by a GT_SWIFT_ERROR node. However, we want to ensure the error register won't be trashed - // before GT_SWIFT_ERROR can consume it. - // (For example, the PInvoke epilog comes before the error register store.) - // To do so, delay the freeing of the error register until the next node. - // This only works if the next node after the call is the GT_SWIFT_ERROR node. - // (InsertPInvokeCallEpilog should have moved the GT_SWIFT_ERROR node during lowering.) - assert(call->gtNext != nullptr); - assert(call->gtNext->OperIs(GT_SWIFT_ERROR)); - - // We could use RefTypeKill, but RefTypeFixedReg is used less commonly, so the check for delayRegFree - // during register allocation should be cheaper in terms of TP. - RefPosition* pos = newRefPosition(REG_SWIFT_ERROR, currentLoc, RefTypeFixedReg, call, RBM_SWIFT_ERROR); - setDelayFree(pos); + MarkSwiftErrorBusyForCall(call); } #endif // SWIFT_SUPPORT diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index b3eb292677d809..25c0521461d854 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -51,6 +51,8 @@ enum NamedIntrinsic : unsigned short NI_System_Math_MinMagnitudeNumber, NI_System_Math_MinNumber, NI_System_Math_Pow, + NI_System_Math_ReciprocalEstimate, + NI_System_Math_ReciprocalSqrtEstimate, NI_System_Math_Round, NI_System_Math_Sin, NI_System_Math_Sinh, @@ -227,6 +229,8 @@ enum NamedIntrinsic : unsigned short NI_PRIMITIVE_START, + NI_PRIMITIVE_ConvertToInteger, + NI_PRIMITIVE_ConvertToIntegerNative, NI_PRIMITIVE_Crc32C, NI_PRIMITIVE_LeadingZeroCount, NI_PRIMITIVE_Log2, diff --git a/src/coreclr/jit/optimizebools.cpp b/src/coreclr/jit/optimizebools.cpp index 0524fc5d2022c6..f915cf7c349481 100644 --- a/src/coreclr/jit/optimizebools.cpp +++ b/src/coreclr/jit/optimizebools.cpp @@ -1248,7 +1248,7 @@ void OptBoolsDsc::optOptimizeBoolsUpdateTrees() optReturnBlock = true; } - assert(m_cmpOp != NULL && m_c1 != nullptr && m_c2 != nullptr); + assert(m_cmpOp != GT_NONE && m_c1 != nullptr && m_c2 != nullptr); GenTree* cmpOp1 = m_foldOp == GT_NONE ? m_c1 : m_comp->gtNewOperNode(m_foldOp, m_foldType, m_c1, m_c2); if (m_testInfo1.isBool && m_testInfo2.isBool) diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index f2de86fcdef21f..fae61fbf9b1c48 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -234,7 +234,7 @@ void Compiler::optScaleLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk) for (BasicBlock* const curBlk : BasicBlockRangeList(begBlk, endBlk)) { // Don't change the block weight if it came from profile data. - if (curBlk->hasProfileWeight() && fgHaveProfileData()) + if (curBlk->hasProfileWeight() && fgHaveProfileWeights()) { reportBlockWeight(curBlk, "; unchanged: has profile weight"); continue; @@ -5052,7 +5052,7 @@ void Compiler::optHoistCandidate(GenTree* tree, FlowGraphNaturalLoop* loop, LoopHoistContext* hoistCtxt) { - // It must pass the hoistable profitablity tests for this loop level + // It must pass the hoistable profitability tests for this loop level if (!optIsProfitableToHoistTree(tree, loop, hoistCtxt)) { JITDUMP(" ... not profitable to hoist\n"); @@ -5316,8 +5316,6 @@ PhaseStatus Compiler::fgCanonicalizeFirstBB() assert(!fgFirstBBisScratch()); fgEnsureFirstBBisScratch(); - // TODO-Quirk: Remove - fgCanonicalizedFirstBB = true; return PhaseStatus::MODIFIED_EVERYTHING; } diff --git a/src/coreclr/jit/rangecheck.cpp b/src/coreclr/jit/rangecheck.cpp index e1046de8b99863..1fb068068e845c 100644 --- a/src/coreclr/jit/rangecheck.cpp +++ b/src/coreclr/jit/rangecheck.cpp @@ -866,10 +866,37 @@ void RangeCheck::MergeEdgeAssertions(ValueNum normalLclVN, ASSERT_VALARG_TP asse continue; } - // Doesn't tighten the current bound. So skip. - if (pRange->uLimit.IsConstant() && limit.vn != arrLenVN) + // Skip if it doesn't tighten the current bound: + if (pRange->uLimit.IsConstant() && ((cmpOper == GT_LE) || (cmpOper == GT_LT))) { - continue; + if (!limit.IsConstant() && (limit.vn != arrLenVN)) + { + // If our new limit is not constant and doesn't represent the array's length - bail out. + // NOTE: it's fine to replace the current constant limit with a non-constant arrLenVN. + continue; + } + if (limit.IsConstant() && (limit.cns > pRange->uLimit.cns)) + { + // The new constant limit doesn't tighten the current constant bound. + // E.g. current is "X < 10" and the new one is "X < 100" + continue; + } + } + // Same for the lower bound: + if (pRange->lLimit.IsConstant() && ((cmpOper == GT_GE) || (cmpOper == GT_GT))) + { + if (!limit.IsConstant() && (limit.vn != arrLenVN)) + { + // If our new limit is not constant and doesn't represent the array's length - bail out. + // NOTE: it's fine to replace the current constant limit with a non-constant arrLenVN. + continue; + } + if (limit.IsConstant() && (limit.cns < pRange->lLimit.cns)) + { + // The new constant limit doesn't tighten the current constant bound. + // E.g. current is "X > 10" and the new one is "X > 5" + continue; + } } // Check if the incoming limit from assertions tightens the existing upper limit. diff --git a/src/coreclr/jit/regset.h b/src/coreclr/jit/regset.h index dae93baebad306..20b55610594fc6 100644 --- a/src/coreclr/jit/regset.h +++ b/src/coreclr/jit/regset.h @@ -158,8 +158,9 @@ class RegSet regMaskTP _rsMaskVars; // backing store for rsMaskVars property #if defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) + // TODO: the funclet's callee-saved registers should not shared with main function. regMaskTP rsMaskCalleeSaved; // mask of the registers pushed/popped in the prolog/epilog -#endif // TARGET_ARMARCH || TARGET_LOONGARCH64 +#endif // TARGET_ARMARCH || TARGET_LOONGARCH64 || TARGET_RISCV64 public: // TODO-Cleanup: Should be private, but Compiler uses it regMaskTP rsMaskResvd; // mask of the registers that are reserved for special purposes (typically empty) diff --git a/src/coreclr/jit/simdashwintrinsic.cpp b/src/coreclr/jit/simdashwintrinsic.cpp index 9ffd3b7b011d55..c9b227440d4e5d 100644 --- a/src/coreclr/jit/simdashwintrinsic.cpp +++ b/src/coreclr/jit/simdashwintrinsic.cpp @@ -523,20 +523,23 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, return nullptr; } - case NI_VectorT_ConvertToInt64: - case NI_VectorT_ConvertToUInt32: - case NI_VectorT_ConvertToUInt64: + case NI_VectorT_ConvertToInt32: { - if (IsBaselineVector512IsaSupportedOpportunistically()) + if (compOpportunisticallyDependsOn(InstructionSet_SSE41)) { break; } return nullptr; } - case NI_VectorT_ConvertToInt32: + case NI_VectorT_ConvertToInt64: + case NI_VectorT_ConvertToInt64Native: + case NI_VectorT_ConvertToUInt32: + case NI_VectorT_ConvertToUInt32Native: + case NI_VectorT_ConvertToUInt64: + case NI_VectorT_ConvertToUInt64Native: { - if (compOpportunisticallyDependsOn(InstructionSet_SSE41)) + if (IsBaselineVector512IsaSupportedOpportunistically()) { break; } @@ -1175,34 +1178,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, } #if defined(TARGET_XARCH) - - case NI_VectorT_ConvertToInt64: - { - assert(sig->numArgs == 1); - assert(simdBaseType == TYP_DOUBLE); - return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_LONG, simdBaseJitType, simdSize); - } - - case NI_VectorT_ConvertToUInt32: - { - assert(sig->numArgs == 1); - assert(simdBaseType == TYP_FLOAT); - return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_UINT, simdBaseJitType, simdSize); - } - - case NI_VectorT_ConvertToUInt64: - { - assert(sig->numArgs == 1); - assert(simdBaseType == TYP_DOUBLE); - return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_ULONG, simdBaseJitType, simdSize); - } - - case NI_VectorT_ConvertToInt32: - { - assert(simdBaseType == TYP_FLOAT); - return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_INT, simdBaseJitType, simdSize); - } - case NI_VectorT_ConvertToDouble: { assert(sig->numArgs == 1); @@ -1273,43 +1248,71 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, simdSize); } + case NI_VectorT_ConvertToSingle: + { + assert((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT)); + return gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_ConvertToSingle, simdBaseJitType, + simdSize); + } +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 + case NI_VectorT_ConvertToInt32: { + assert(sig->numArgs == 1); assert(simdBaseType == TYP_FLOAT); - return gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_ConvertToInt32RoundToZero, simdBaseJitType, - simdSize); + return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_INT, simdBaseJitType, simdSize); + } + + case NI_VectorT_ConvertToInt32Native: + { + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_FLOAT); + return gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_INT, simdBaseJitType, simdSize); } case NI_VectorT_ConvertToInt64: { + assert(sig->numArgs == 1); assert(simdBaseType == TYP_DOUBLE); - return gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_Arm64_ConvertToInt64RoundToZero, - simdBaseJitType, simdSize); + return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_LONG, simdBaseJitType, simdSize); } - case NI_VectorT_ConvertToSingle: + case NI_VectorT_ConvertToInt64Native: { - assert((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT)); - return gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_ConvertToSingle, simdBaseJitType, - simdSize); + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_DOUBLE); + return gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_LONG, simdBaseJitType, simdSize); } case NI_VectorT_ConvertToUInt32: { + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_FLOAT); + return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_UINT, simdBaseJitType, simdSize); + } + + case NI_VectorT_ConvertToUInt32Native: + { + assert(sig->numArgs == 1); assert(simdBaseType == TYP_FLOAT); - return gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_ConvertToUInt32RoundToZero, - simdBaseJitType, simdSize); + return gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_UINT, simdBaseJitType, simdSize); } case NI_VectorT_ConvertToUInt64: { + assert(sig->numArgs == 1); assert(simdBaseType == TYP_DOUBLE); - return gtNewSimdHWIntrinsicNode(retType, op1, NI_AdvSimd_Arm64_ConvertToUInt64RoundToZero, - simdBaseJitType, simdSize); + return gtNewSimdCvtNode(retType, op1, CORINFO_TYPE_ULONG, simdBaseJitType, simdSize); + } + + case NI_VectorT_ConvertToUInt64Native: + { + assert(sig->numArgs == 1); + assert(simdBaseType == TYP_DOUBLE); + return gtNewSimdCvtNativeNode(retType, op1, CORINFO_TYPE_ULONG, simdBaseJitType, simdSize); } -#else -#error Unsupported platform -#endif // !TARGET_XARCH && !TARGET_ARM64 default: { diff --git a/src/coreclr/jit/simdashwintrinsiclistarm64.h b/src/coreclr/jit/simdashwintrinsiclistarm64.h index cb8d702be5e71f..911306e712409c 100644 --- a/src/coreclr/jit/simdashwintrinsiclistarm64.h +++ b/src/coreclr/jit/simdashwintrinsiclistarm64.h @@ -224,10 +224,14 @@ SIMD_AS_HWINTRINSIC_ID(VectorT, Ceiling, SIMD_AS_HWINTRINSIC_ID(VectorT, ConditionalSelect, 3, {NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToDouble, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToDouble, NI_VectorT_ConvertToDouble, NI_Illegal, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt32, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt32, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt64}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt64Native}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToSingle, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToSingle, NI_VectorT_ConvertToSingle, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64Native}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_NM(VectorT, CreateBroadcast, ".ctor", 2, {NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1) SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1) SIMD_AS_HWINTRINSIC_ID(VectorT, Divide, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_Divide, NI_VectorT_Divide}, SimdAsHWIntrinsicFlag::None) diff --git a/src/coreclr/jit/simdashwintrinsiclistxarch.h b/src/coreclr/jit/simdashwintrinsiclistxarch.h index 5cf07eff0c84ae..dd1d6374bc248f 100644 --- a/src/coreclr/jit/simdashwintrinsiclistxarch.h +++ b/src/coreclr/jit/simdashwintrinsiclistxarch.h @@ -224,10 +224,14 @@ SIMD_AS_HWINTRINSIC_ID(VectorT, Ceiling, SIMD_AS_HWINTRINSIC_ID(VectorT, ConditionalSelect, 3, {NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect, NI_VectorT_ConditionalSelect}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToDouble, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToDouble, NI_VectorT_ConvertToDouble, NI_Illegal, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt32, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt32, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt64}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToInt64Native}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToSingle, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToSingle, NI_VectorT_ConvertToSingle, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64Native}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_NM(VectorT, CreateBroadcast, ".ctor", 2, {NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast, NI_VectorT_CreateBroadcast}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1) SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1) SIMD_AS_HWINTRINSIC_ID(VectorT, Divide, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_Divide, NI_VectorT_Divide}, SimdAsHWIntrinsicFlag::None) diff --git a/src/coreclr/jit/simdcodegenxarch.cpp b/src/coreclr/jit/simdcodegenxarch.cpp index d0fb1bf0aef4e8..aff087062f58fe 100644 --- a/src/coreclr/jit/simdcodegenxarch.cpp +++ b/src/coreclr/jit/simdcodegenxarch.cpp @@ -96,7 +96,7 @@ void CodeGen::genStoreIndTypeSimd12(GenTreeStoreInd* treeNode) } else { - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); // Extract upper 4 bytes from data emit->emitIns_R_R(INS_movhlps, EA_16BYTE, tmpReg, dataReg); @@ -295,7 +295,7 @@ void CodeGen::genEmitStoreLclTypeSimd12(GenTree* store, unsigned lclNum, unsigne } else { - regNumber tmpReg = store->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(store); // Extract upper 4 bytes from data emit->emitIns_R_R(INS_movhlps, EA_16BYTE, tmpReg, dataReg); @@ -391,7 +391,7 @@ void CodeGen::genPutArgStkSimd12(GenTreePutArgStk* treeNode) regNumber dataReg = genConsumeReg(data); // Need an additional Xmm register to extract upper 4 bytes from data. - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = internalRegisters.GetSingle(treeNode); genStoreSimd12ToStack(dataReg, tmpReg); } diff --git a/src/coreclr/jit/ssabuilder.cpp b/src/coreclr/jit/ssabuilder.cpp index caba13f3536abc..0a5229e32b8b7c 100644 --- a/src/coreclr/jit/ssabuilder.cpp +++ b/src/coreclr/jit/ssabuilder.cpp @@ -965,8 +965,8 @@ void SsaBuilder::AddPhiArgsToSuccessors(BasicBlock* block) // Walk the statements for phi nodes. for (Statement* const stmt : succ->Statements()) { - // A prefix of the statements of the block are phi definition nodes. If we complete processing - // that prefix, exit. + // A prefix of the statements of the block are phi definition nodes. If we complete + // processing that prefix, exit. if (!stmt->IsPhiDefnStmt()) { break; @@ -988,8 +988,9 @@ void SsaBuilder::AddPhiArgsToSuccessors(BasicBlock* block) { if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates) { - // We've already propagated the "out" number to the phi shared with ByrefExposed, - // but still need to update bbMemorySsaPhiFunc to be in sync between GcHeap and ByrefExposed. + // We've already propagated the "out" number to the phi shared with + // ByrefExposed, but still need to update bbMemorySsaPhiFunc to be in sync + // between GcHeap and ByrefExposed. assert(memoryKind > ByrefExposed); assert(block->bbMemorySsaNumOut[memoryKind] == block->bbMemorySsaNumOut[ByrefExposed]); assert((succ->bbMemorySsaPhiFunc[ByrefExposed] == succMemoryPhi) || @@ -1009,8 +1010,9 @@ void SsaBuilder::AddPhiArgsToSuccessors(BasicBlock* block) BasicBlock::MemoryPhiArg* curArg = succMemoryPhi; unsigned ssaNum = block->bbMemorySsaNumOut[memoryKind]; bool found = false; - // This is a quadratic algorithm. We might need to consider some switch over to a hash table - // representation for the arguments of a phi node, to make this linear. + // This is a quadratic algorithm. We might need to consider some switch over + // to a hash table representation for the arguments of a phi node, to make this + // linear. while (curArg != nullptr) { if (curArg->m_ssaNum == ssaNum) diff --git a/src/coreclr/jit/targetarm.cpp b/src/coreclr/jit/targetarm.cpp index 037578fa67b85c..675fd04230d531 100644 --- a/src/coreclr/jit/targetarm.cpp +++ b/src/coreclr/jit/targetarm.cpp @@ -85,11 +85,11 @@ ABIPassingInformation Arm32Classifier::Classify(Compiler* comp, m_nextIntReg = roundUp(m_nextIntReg, 2); } - unsigned size = type == TYP_STRUCT ? structLayout->GetSize() : genTypeSize(type); - unsigned alignedSize = roundUp(size, alignment); + unsigned size = type == TYP_STRUCT ? structLayout->GetSize() : genTypeSize(type); + unsigned numSlots = (size + 3) / 4; - unsigned numInRegs = min(alignedSize / 4, 4 - m_nextIntReg); - bool anyOnStack = numInRegs < (alignedSize / 4); + unsigned numInRegs = min(numSlots, 4 - m_nextIntReg); + bool anyOnStack = numInRegs < numSlots; // If we already passed anything on stack (due to float args) then we // cannot split an arg. @@ -116,7 +116,7 @@ ABIPassingInformation Arm32Classifier::Classify(Compiler* comp, { m_stackArgSize = roundUp(m_stackArgSize, alignment); unsigned stackSize = size - (numInRegs * 4); - info.Segments[numInRegs] = ABIPassingSegment::OnStack(m_stackArgSize, 0, stackSize); + info.Segments[numInRegs] = ABIPassingSegment::OnStack(m_stackArgSize, numInRegs * 4, stackSize); m_stackArgSize += roundUp(stackSize, 4); // As soon as any int arg goes on stack we cannot put anything else in diff --git a/src/coreclr/jit/targetloongarch64.cpp b/src/coreclr/jit/targetloongarch64.cpp index 47f74094fab9dc..9292f0e0e67a8f 100644 --- a/src/coreclr/jit/targetloongarch64.cpp +++ b/src/coreclr/jit/targetloongarch64.cpp @@ -104,7 +104,7 @@ ABIPassingInformation LoongArch64Classifier::Classify(Compiler* comp, } else if ((floatFlags & STRUCT_FLOAT_FIELD_FIRST) != 0) { - slots = 1; + slots = 2; canPassArgInRegisters = (m_floatRegs.Count() > 0) && (m_intRegs.Count() > 0); argRegTypeInStruct1 = (floatFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT; @@ -112,7 +112,7 @@ ABIPassingInformation LoongArch64Classifier::Classify(Compiler* comp, } else if ((floatFlags & STRUCT_FLOAT_FIELD_SECOND) != 0) { - slots = 1; + slots = 2; canPassArgInRegisters = (m_floatRegs.Count() > 0) && (m_intRegs.Count() > 0); argRegTypeInStruct1 = (floatFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? TYP_LONG : TYP_INT; @@ -161,6 +161,7 @@ ABIPassingInformation LoongArch64Classifier::Classify(Compiler* comp, canPassArgInRegisters = m_floatRegs.Count() > 0; if (!canPassArgInRegisters) { + type = TYP_I_IMPL; m_floatRegs.Clear(); canPassArgInRegisters = m_intRegs.Count() > 0; } diff --git a/src/coreclr/jit/targetriscv64.cpp b/src/coreclr/jit/targetriscv64.cpp index 29f71dc76d8fa2..581087b5cc63f8 100644 --- a/src/coreclr/jit/targetriscv64.cpp +++ b/src/coreclr/jit/targetriscv64.cpp @@ -36,6 +36,7 @@ RiscV64Classifier::RiscV64Classifier(const ClassifierInfo& info) , m_intRegs(intArgRegs, ArrLen(intArgRegs)) , m_floatRegs(fltArgRegs, ArrLen(fltArgRegs)) { + assert(!m_info.IsVarArgs); // TODO: varargs currently not supported on RISC-V } //----------------------------------------------------------------------------- @@ -57,8 +58,6 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp, ClassLayout* structLayout, WellKnownArg /*wellKnownParam*/) { - assert(!m_info.IsVarArgs); // TODO: varargs currently not supported on RISC-V - StructFloatFieldInfoFlags flags = STRUCT_NO_FLOAT_FIELD; unsigned intFields = 0, floatFields = 0; unsigned passedSize; @@ -93,36 +92,13 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp, } else { - assert(genTypeSize(type) <= TARGET_POINTER_SIZE); - - if (varTypeIsFloating(type)) - floatFields = 1; - passedSize = genTypeSize(type); + assert(passedSize <= TARGET_POINTER_SIZE); + floatFields = varTypeIsFloating(type) ? 1 : 0; } assert((floatFields > 0) || (intFields == 0)); - auto PassSlot = [this](bool inFloatReg, unsigned offset, unsigned size) -> ABIPassingSegment { - assert(size > 0); - assert(size <= TARGET_POINTER_SIZE); - if (inFloatReg) - { - return ABIPassingSegment::InRegister(m_floatRegs.Dequeue(), offset, size); - } - else if (m_intRegs.Count() > 0) - { - return ABIPassingSegment::InRegister(m_intRegs.Dequeue(), offset, size); - } - else - { - assert((m_stackArgSize % TARGET_POINTER_SIZE) == 0); - ABIPassingSegment seg = ABIPassingSegment::OnStack(m_stackArgSize, offset, size); - m_stackArgSize += TARGET_POINTER_SIZE; - return seg; - } - }; - if ((floatFields > 0) && (m_floatRegs.Count() >= floatFields) && (m_intRegs.Count() >= intFields)) { // Hardware floating-point calling convention @@ -151,27 +127,45 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp, bool isSecondFloat = (flags & (STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_FLOAT_FIELD_SECOND)) != 0; assert(isFirstFloat || isSecondFloat); - return {2, new (comp, CMK_ABI) ABIPassingSegment[]{PassSlot(isFirstFloat, 0, firstSize), - PassSlot(isSecondFloat, offset, secondSize)}}; + regNumber firstReg = (isFirstFloat ? m_floatRegs : m_intRegs).Dequeue(); + regNumber secondReg = (isSecondFloat ? m_floatRegs : m_intRegs).Dequeue(); + + return {2, new (comp, CMK_ABI) + ABIPassingSegment[]{ABIPassingSegment::InRegister(firstReg, 0, firstSize), + ABIPassingSegment::InRegister(secondReg, offset, secondSize)}}; } } else { // Integer calling convention + auto passSlot = [this](unsigned offset, unsigned size) -> ABIPassingSegment { + assert(size > 0); + assert(size <= TARGET_POINTER_SIZE); + if (m_intRegs.Count() > 0) + { + return ABIPassingSegment::InRegister(m_intRegs.Dequeue(), offset, size); + } + else + { + assert((m_stackArgSize % TARGET_POINTER_SIZE) == 0); + ABIPassingSegment seg = ABIPassingSegment::OnStack(m_stackArgSize, offset, size); + m_stackArgSize += TARGET_POINTER_SIZE; + return seg; + } + }; + if (passedSize <= TARGET_POINTER_SIZE) { - return ABIPassingInformation::FromSegment(comp, PassSlot(false, 0, passedSize)); + return ABIPassingInformation::FromSegment(comp, passSlot(0, passedSize)); } else { assert(varTypeIsStruct(type)); return {2, new (comp, CMK_ABI) - ABIPassingSegment[]{PassSlot(false, 0, TARGET_POINTER_SIZE), - PassSlot(false, TARGET_POINTER_SIZE, passedSize - TARGET_POINTER_SIZE)}}; + ABIPassingSegment[]{passSlot(0, TARGET_POINTER_SIZE), + passSlot(TARGET_POINTER_SIZE, passedSize - TARGET_POINTER_SIZE)}}; } } - - unreached(); } #endif // TARGET_RISCV64 diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index e3b99463b466de..07ca1fb6dc09c9 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1746,7 +1746,7 @@ void HelperCallProperties::init() case CORINFO_HELP_CHECKED_ASSIGN_REF: case CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP: case CORINFO_HELP_ASSIGN_BYREF: - case CORINFO_HELP_ASSIGN_STRUCT: + case CORINFO_HELP_BULK_WRITEBARRIER: mutatesHeap = true; break; diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 0808d9d9711178..909e5ab768af44 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -6521,6 +6521,7 @@ bool ValueNumStore::IsVNPositiveInt32Constant(ValueNum vn) // IsVNArrLenUnsignedBound: Checks if the specified vn represents an expression // of one of the following forms: // - "(uint)i < (uint)len" that implies (0 <= i < len) +// - "(ulong)i < (ulong)len" that implies (0 <= i < len) // - "const < (uint)len" that implies "len > const" // - "const <= (uint)len" that implies "len > const - 1" // @@ -6544,49 +6545,57 @@ bool ValueNumStore::IsVNUnsignedCompareCheckedBound(ValueNum vn, UnsignedCompare if ((funcApp.m_func == VNF_LT_UN) || (funcApp.m_func == VNF_GE_UN)) { // We only care about "(uint)i < (uint)len" and its negation "(uint)i >= (uint)len" - if (IsVNCheckedBound(funcApp.m_args[1])) + // Same for (ulong) + ValueNum vnBound = funcApp.m_args[1]; + ValueNum vnIdx = funcApp.m_args[0]; + ValueNum vnCastOp = NoVN; + if (IsVNCheckedBound(vnBound) || (IsVNCastToULong(vnBound, &vnCastOp) && IsVNCheckedBound(vnCastOp))) { - info->vnIdx = funcApp.m_args[0]; + info->vnIdx = vnIdx; info->cmpOper = funcApp.m_func; - info->vnBound = funcApp.m_args[1]; + info->vnBound = (vnCastOp != NoVN) ? vnCastOp : vnBound; return true; } // We care about (uint)len < constant and its negation "(uint)len >= constant" - else if (IsVNPositiveInt32Constant(funcApp.m_args[1]) && IsVNCheckedBound(funcApp.m_args[0])) + else if (IsVNPositiveInt32Constant(vnBound) && IsVNCheckedBound(vnIdx)) { // Change constant < len into (uint)len >= (constant - 1) // to make consuming this simpler (and likewise for it's negation). - INT32 validIndex = ConstantValue(funcApp.m_args[1]) - 1; + INT32 validIndex = ConstantValue(vnBound) - 1; assert(validIndex >= 0); info->vnIdx = VNForIntCon(validIndex); info->cmpOper = (funcApp.m_func == VNF_GE_UN) ? VNF_LT_UN : VNF_GE_UN; - info->vnBound = funcApp.m_args[0]; + info->vnBound = vnIdx; return true; } } else if ((funcApp.m_func == VNF_GT_UN) || (funcApp.m_func == VNF_LE_UN)) { // We only care about "(uint)a.len > (uint)i" and its negation "(uint)a.len <= (uint)i" - if (IsVNCheckedBound(funcApp.m_args[0])) + // Same for (ulong) + ValueNum vnBound = funcApp.m_args[0]; + ValueNum vnIdx = funcApp.m_args[1]; + ValueNum vnCastOp = NoVN; + if (IsVNCheckedBound(vnBound) || (IsVNCastToULong(vnBound, &vnCastOp) && IsVNCheckedBound(vnCastOp))) { - info->vnIdx = funcApp.m_args[1]; + info->vnIdx = vnIdx; // Let's keep a consistent operand order - it's always i < len, never len > i info->cmpOper = (funcApp.m_func == VNF_GT_UN) ? VNF_LT_UN : VNF_GE_UN; - info->vnBound = funcApp.m_args[0]; + info->vnBound = (vnCastOp != NoVN) ? vnCastOp : vnBound; return true; } // Look for constant > (uint)len and its negation "constant <= (uint)len" - else if (IsVNPositiveInt32Constant(funcApp.m_args[0]) && IsVNCheckedBound(funcApp.m_args[1])) + else if (IsVNPositiveInt32Constant(vnBound) && IsVNCheckedBound(vnIdx)) { // Change constant <= (uint)len to (constant - 1) < (uint)len // to make consuming this simpler (and likewise for it's negation). - INT32 validIndex = ConstantValue(funcApp.m_args[0]) - 1; + INT32 validIndex = ConstantValue(vnBound) - 1; assert(validIndex >= 0); info->vnIdx = VNForIntCon(validIndex); info->cmpOper = (funcApp.m_func == VNF_LE_UN) ? VNF_LT_UN : VNF_GE_UN; - info->vnBound = funcApp.m_args[1]; + info->vnBound = vnIdx; return true; } } @@ -6823,6 +6832,33 @@ bool ValueNumStore::IsVNCheckedBound(ValueNum vn) return false; } +//---------------------------------------------------------------------------------- +// IsVNCastToULong: checks whether the given VN represents (ulong)op cast +// +// Arguments: +// vn - VN, presumably, representing (ulong)op cast +// castedOp - [Out] VN of op being cast +// +// Return Value: +// true if the given VN represents (ulong)op cast +// +bool ValueNumStore::IsVNCastToULong(ValueNum vn, ValueNum* castedOp) +{ + VNFuncApp funcApp; + if (GetVNFunc(vn, &funcApp) && (funcApp.m_func == VNF_Cast)) + { + var_types castToType; + bool srcIsUnsigned; + GetCastOperFromVN(funcApp.m_args[1], &castToType, &srcIsUnsigned); + if (srcIsUnsigned && (castToType == TYP_LONG)) + { + *castedOp = funcApp.m_args[0]; + return true; + } + } + return false; +} + void ValueNumStore::SetVNIsCheckedBound(ValueNum vn) { // This is meant to flag VNs for lengths that aren't known at compile time, so we can diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 799d36472b00c9..f88de8f55856d5 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -905,6 +905,9 @@ class ValueNumStore // of the length argument to a GT_BOUNDS_CHECK node. bool IsVNCheckedBound(ValueNum vn); + // Returns true if the VN is known to be a cast to ulong + bool IsVNCastToULong(ValueNum vn, ValueNum* castedOp); + // Record that a VN is known to appear as the conservative value number of the length // argument to a GT_BOUNDS_CHECK node. void SetVNIsCheckedBound(ValueNum vn); diff --git a/src/coreclr/md/runtime/mdinternalro.cpp b/src/coreclr/md/runtime/mdinternalro.cpp index 96d72558485527..7f633c6112e9b8 100644 --- a/src/coreclr/md/runtime/mdinternalro.cpp +++ b/src/coreclr/md/runtime/mdinternalro.cpp @@ -3147,7 +3147,6 @@ mdModule MDInternalRO::GetModuleFromScope(void) //***************************************************************************** // Fill a variant given a MDDefaultValue -// This routine will create a bstr if the ELEMENT_TYPE of default value is STRING //***************************************************************************** __checkReturn HRESULT _FillMDDefaultValue( @@ -3236,19 +3235,7 @@ HRESULT _FillMDDefaultValue( if (cbValue == 0) pValue = NULL; -#if BIGENDIAN - { - // We need to allocate and swap the string if we're on a big endian - // This allocation will be freed by the MDDefaultValue destructor. - pMDDefaultValue->m_wzValue = new WCHAR[(cbValue + 1) / sizeof (WCHAR)]; - IfNullGo(pMDDefaultValue->m_wzValue); - memcpy(const_cast(pMDDefaultValue->m_wzValue), pValue, cbValue); - _ASSERTE(cbValue % sizeof(WCHAR) == 0); - SwapStringLength(const_cast(pMDDefaultValue->m_wzValue), cbValue / sizeof(WCHAR)); - } -#else pMDDefaultValue->m_wzValue = (LPWSTR) pValue; -#endif break; case ELEMENT_TYPE_CLASS: // diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index c9314487b0507d..7441f7da0f6249 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -74,9 +74,8 @@ The .NET Foundation licenses this file to you under the MIT license. - 13.5 - 14.2 - 11.0 + 15.0 + 12.2 <_AppleSdkName Condition="'$(_targetOS)' == 'ios'">iphoneos <_AppleSdkName Condition="'$(_targetOS)' == 'iossimulator'">iphonesimulator @@ -96,7 +95,7 @@ The .NET Foundation licenses this file to you under the MIT license. - 11.0 + 12.0 x86_64-apple-macos$(AppleMinOSVersion) arm64-apple-macos$(AppleMinOSVersion) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index 988a02dd8792d8..0df29b62a37287 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -229,7 +229,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + @@ -281,7 +281,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + @@ -289,7 +289,7 @@ The .NET Foundation licenses this file to you under the MIT license. - + diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index f070214054f7f9..4a10690b15af4f 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -231,15 +231,19 @@ if(FEATURE_EVENT_TRACE) add_definitions(-DFEATURE_EVENT_TRACE) endif() +if (NOT CLR_CMAKE_TARGET_ARCH_WASM) + add_definitions(-DFEATURE_HIJACK) +endif() + add_definitions(-DFEATURE_BASICFREEZE) add_definitions(-DFEATURE_CONSERVATIVE_GC) if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) add_definitions(-DFEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP) add_definitions(-DFEATURE_MANUALLY_MANAGED_CARD_BUNDLES) -endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64) -if(CLR_CMAKE_TARGET_ARCH_ARM) +endif() +if(CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_WASM) add_definitions(-DFEATURE_64BIT_ALIGNMENT) -endif(CLR_CMAKE_TARGET_ARCH_ARM) +endif() add_definitions(-DFEATURE_CUSTOM_IMPORTS) add_definitions(-DFEATURE_DYNAMIC_CODE) @@ -250,7 +254,7 @@ add_definitions(-DNATIVEAOT) add_definitions(-DFEATURE_CACHED_INTERFACE_DISPATCH) if(CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM) add_definitions(-DINTERFACE_DISPATCH_CACHE_HAS_CELL_BACKPOINTER) -endif(CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM) +endif() add_definitions(-D_LIB) # there is a problem with undefined symbols when this is set @@ -267,7 +271,7 @@ if(CLR_CMAKE_TARGET_WIN32) add_compile_options($<$:/safeseh>) endif() else() - if(NOT CLR_CMAKE_TARGET_APPLE) + if(NOT CLR_CMAKE_TARGET_APPLE AND NOT CLR_CMAKE_TARGET_ARCH_WASM) add_definitions(-DFEATURE_READONLY_GS_COOKIE) endif() include(unix/configure.cmake) diff --git a/src/coreclr/nativeaot/Runtime/CommonMacros.h b/src/coreclr/nativeaot/Runtime/CommonMacros.h index a2b4183fb1ecd5..4b74de2360e616 100644 --- a/src/coreclr/nativeaot/Runtime/CommonMacros.h +++ b/src/coreclr/nativeaot/Runtime/CommonMacros.h @@ -125,35 +125,8 @@ inline bool IS_ALIGNED(T* val, uintptr_t alignment); #ifndef __GCENV_BASE_INCLUDED__ -#if defined(HOST_WASM) -#define OS_PAGE_SIZE 0x4 -#else #define OS_PAGE_SIZE PalOsPageSize() -#endif - -#if defined(HOST_AMD64) - -#define DATA_ALIGNMENT 8 - -#elif defined(HOST_X86) - -#define DATA_ALIGNMENT 4 - -#elif defined(HOST_ARM) -#define DATA_ALIGNMENT 4 - -#elif defined(HOST_ARM64) - -#define DATA_ALIGNMENT 8 - -#elif defined(HOST_WASM) - -#define DATA_ALIGNMENT 4 - -#else -#error Unsupported target architecture -#endif #endif // __GCENV_BASE_INCLUDED__ #if defined(TARGET_ARM) diff --git a/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.inl b/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.inl index bb4c64aed3cf48..cb4adbfc6a275f 100644 --- a/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.inl +++ b/src/coreclr/nativeaot/Runtime/GCMemoryHelpers.inl @@ -172,6 +172,8 @@ static const uint32_t INVALIDGCVALUE = 0xcccccccd; FORCEINLINE void InlineWriteBarrier(void * dst, void * ref) { + ASSERT(((uint8_t*)dst >= g_lowest_address) && ((uint8_t*)dst < g_highest_address)) + if (((uint8_t*)ref >= g_ephemeral_low) && ((uint8_t*)ref < g_ephemeral_high)) { // volatile is used here to prevent fetch of g_card_table from being reordered diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h index e44c87a6046e09..9257324bd1589b 100644 --- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h +++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h @@ -688,9 +688,11 @@ REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalStartBackgroundGCThread(_In_ Background REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalStartFinalizerThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext); REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalStartEventPipeHelperThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext); +#ifdef FEATURE_HIJACK typedef void (*PalHijackCallback)(_In_ NATIVE_CONTEXT* pThreadContext, _In_opt_ void* pThreadToHijack); REDHAWK_PALIMPORT void REDHAWK_PALAPI PalHijack(HANDLE hThread, _In_opt_ void* pThreadToHijack); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalRegisterHijackCallback(_In_ PalHijackCallback callback); +#endif REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(_In_ HANDLE hTemplateModule, uint32_t templateRva, size_t templateSize, _Outptr_result_bytebuffer_(templateSize) void** newThunksOut); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress, size_t templateSize); diff --git a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h index 6a3b24a3944870..d4360273d28ac8 100644 --- a/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h +++ b/src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h @@ -12,7 +12,7 @@ struct ReadyToRunHeaderConstants static const uint32_t Signature = 0x00525452; // 'RTR' static const uint32_t CurrentMajorVersion = 9; - static const uint32_t CurrentMinorVersion = 2; + static const uint32_t CurrentMinorVersion = 3; }; struct ReadyToRunHeader diff --git a/src/coreclr/nativeaot/Runtime/portable.cpp b/src/coreclr/nativeaot/Runtime/portable.cpp index bcd99d051198d8..318a10fd20a526 100644 --- a/src/coreclr/nativeaot/Runtime/portable.cpp +++ b/src/coreclr/nativeaot/Runtime/portable.cpp @@ -332,28 +332,6 @@ void * ReturnFromUniversalTransition; EXTERN_C void * ReturnFromUniversalTransition_DebugStepTailCall; void * ReturnFromUniversalTransition_DebugStepTailCall; -#endif // USE_PORTABLE_HELPERS - -#if defined(USE_PORTABLE_HELPERS) -// -// Return address hijacking -// -FCIMPL0(void, RhpGcStressHijack) -{ - ASSERT_UNCONDITIONALLY("NYI"); -} -FCIMPLEND - -FCIMPL0(void, RhpGcProbeHijack) -{ - ASSERT_UNCONDITIONALLY("NYI"); -} -FCIMPLEND - -#endif // defined(USE_PORTABLE_HELPERS) || defined(TARGET_UNIX) - -#if defined(USE_PORTABLE_HELPERS) - #if !defined (HOST_ARM64) FCIMPL2(void, RhpAssignRef, Object ** dst, Object * ref) { diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp index 41fa9e53949459..1ae78d37d56fc4 100644 --- a/src/coreclr/nativeaot/Runtime/thread.cpp +++ b/src/coreclr/nativeaot/Runtime/thread.cpp @@ -578,7 +578,8 @@ void Thread::GcScanRootsWorker(ScanFunc * pfnEnumCallback, ScanContext * pvCallb #ifndef DACCESS_COMPILE -EXTERN_C void FASTCALL RhpSuspendRedirected(); +#ifdef FEATURE_HIJACK + EXTERN_C void FASTCALL RhpGcProbeHijack(); EXTERN_C void FASTCALL RhpGcStressHijack(); @@ -815,6 +816,7 @@ void Thread::HijackReturnAddressWorker(StackFrameIterator* frameIterator, Hijack GetPalThreadIdForLogging(), frameIterator->GetRegisterSet()->GetIP()); } } +#endif // FEATURE_HIJACK NATIVE_CONTEXT* Thread::GetInterruptedContext() { @@ -834,6 +836,16 @@ NATIVE_CONTEXT* Thread::EnsureRedirectionContext() return m_interruptedContext; } +EXTERN_C NOINLINE void FASTCALL RhpSuspendRedirected() +{ + Thread* pThread = ThreadStore::GetCurrentThread(); + pThread->WaitForGC(INTERRUPTED_THREAD_MARKER); + + // restore execution at interrupted location + PalRestoreContext(pThread->GetInterruptedContext()); + UNREACHABLE(); +} + bool Thread::Redirect() { ASSERT(!IsDoNotTriggerGcSet()); @@ -861,6 +873,7 @@ bool Thread::Redirect() } #endif //FEATURE_SUSPEND_REDIRECTION +#ifdef FEATURE_HIJACK bool Thread::InlineSuspend(NATIVE_CONTEXT* interruptedContext) { ASSERT(!IsDoNotTriggerGcSet()); @@ -948,6 +961,7 @@ void* Thread::GetHijackedReturnAddress() ASSERT(ThreadStore::GetCurrentThread() == this); return m_pvHijackedReturnAddress; } +#endif // FEATURE_HIJACK void Thread::SetState(ThreadStateFlags flags) { @@ -1021,20 +1035,6 @@ EXTERN_C NOINLINE void FASTCALL RhpGcPoll2(PInvokeTransitionFrame* pFrame) RhpWaitForGC2(pFrame); } -#ifdef FEATURE_SUSPEND_REDIRECTION - -EXTERN_C NOINLINE void FASTCALL RhpSuspendRedirected() -{ - Thread* pThread = ThreadStore::GetCurrentThread(); - pThread->WaitForGC(INTERRUPTED_THREAD_MARKER); - - // restore execution at interrupted location - PalRestoreContext(pThread->GetInterruptedContext()); - UNREACHABLE(); -} - -#endif //FEATURE_SUSPEND_REDIRECTION - void Thread::PushExInfo(ExInfo * pExInfo) { ValidateExInfoStack(); diff --git a/src/coreclr/nativeaot/Runtime/thread.h b/src/coreclr/nativeaot/Runtime/thread.h index 161fea12281688..3c8073faa2ac70 100644 --- a/src/coreclr/nativeaot/Runtime/thread.h +++ b/src/coreclr/nativeaot/Runtime/thread.h @@ -92,9 +92,11 @@ struct ThreadBuffer PInvokeTransitionFrame* m_pCachedTransitionFrame; PTR_Thread m_pNext; // used by ThreadStore's SList HANDLE m_hPalThread; // WARNING: this may legitimately be INVALID_HANDLE_VALUE +#ifdef FEATURE_HIJACK void ** m_ppvHijackedReturnAddressLocation; void * m_pvHijackedReturnAddress; uintptr_t m_uHijackedReturnValueFlags; +#endif // FEATURE_HIJACK PTR_ExInfo m_pExInfoStackHead; Object* m_threadAbortException; // ThreadAbortException instance -set only during thread abort #ifdef TARGET_X86 @@ -168,7 +170,7 @@ class Thread : private ThreadBuffer void ClearState(ThreadStateFlags flags); bool IsStateSet(ThreadStateFlags flags); - +#ifdef FEATURE_HIJACK static void HijackCallback(NATIVE_CONTEXT* pThreadContext, void* pThreadToHijack); // @@ -181,6 +183,11 @@ class Thread : private ThreadBuffer void HijackReturnAddress(NATIVE_CONTEXT* pSuspendCtx, HijackFunc* pfnHijackFunction); void HijackReturnAddressWorker(StackFrameIterator* frameIterator, HijackFunc* pfnHijackFunction); bool InlineSuspend(NATIVE_CONTEXT* interruptedContext); + void CrossThreadUnhijack(); + void UnhijackWorker(); +#else // FEATURE_HIJACK + void CrossThreadUnhijack() { } +#endif // FEATURE_HIJACK #ifdef FEATURE_SUSPEND_REDIRECTION bool Redirect(); @@ -188,8 +195,6 @@ class Thread : private ThreadBuffer bool CacheTransitionFrameForSuspend(); void ResetCachedTransitionFrame(); - void CrossThreadUnhijack(); - void UnhijackWorker(); void EnsureRuntimeInitialized(); // @@ -222,10 +227,17 @@ class Thread : private ThreadBuffer void GcScanRoots(ScanFunc* pfnEnumCallback, ScanContext * pvCallbackData); +#ifdef FEATURE_HIJACK void Hijack(); void Unhijack(); bool IsHijacked(); void* GetHijackedReturnAddress(); + static bool IsHijackTarget(void * address); +#else // FEATURE_HIJACK + void Unhijack() { } + bool IsHijacked() { return false; } + static bool IsHijackTarget(void * address) { return false; } +#endif // FEATURE_HIJACK #ifdef FEATURE_GC_STRESS static void HijackForGcStress(PAL_LIMITED_CONTEXT * pSuspendCtx); @@ -262,8 +274,6 @@ class Thread : private ThreadBuffer PInvokeTransitionFrame* GetTransitionFrameForStackTrace(); void * GetCurrentThreadPInvokeReturnAddress(); - static bool IsHijackTarget(void * address); - // // The set of operations used to support unmanaged code running in cooperative mode // diff --git a/src/coreclr/nativeaot/Runtime/threadstore.cpp b/src/coreclr/nativeaot/Runtime/threadstore.cpp index d94ef850a1c9bb..63bb947e2baa9b 100644 --- a/src/coreclr/nativeaot/Runtime/threadstore.cpp +++ b/src/coreclr/nativeaot/Runtime/threadstore.cpp @@ -85,8 +85,10 @@ ThreadStore * ThreadStore::Create(RuntimeInstance * pRuntimeInstance) if (NULL == pNewThreadStore) return NULL; +#ifdef FEATURE_HIJACK if (!PalRegisterHijackCallback(Thread::HijackCallback)) return NULL; +#endif pNewThreadStore->m_pRuntimeInstance = pRuntimeInstance; @@ -281,10 +283,12 @@ void ThreadStore::SuspendAllThreads(bool waitForGCEvent) if (!pTargetThread->CacheTransitionFrameForSuspend()) { remaining++; +#ifdef FEATURE_HIJACK if (!observeOnly) { pTargetThread->Hijack(); } +#endif // FEATURE_HIJACK } } END_FOREACH_THREAD diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp index 5cac500ca85a87..79a9476e3b7641 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp @@ -705,12 +705,7 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartBackgroundGCThread(_In_ Background REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartFinalizerThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext) { -#ifdef HOST_WASM - // WASMTODO: No threads so we can't start the finalizer thread - return true; -#else // HOST_WASM return PalStartBackgroundWork(callback, pCallbackContext, UInt32_TRUE); -#endif // HOST_WASM } REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartEventPipeHelperThread(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext) @@ -989,6 +984,7 @@ extern "C" uint16_t RtlCaptureStackBackTrace(uint32_t arg1, uint32_t arg2, void* return 0; } +#ifdef FEATURE_HIJACK static PalHijackCallback g_pHijackCallback; static struct sigaction g_previousActivationHandler; @@ -1076,6 +1072,7 @@ REDHAWK_PALEXPORT void REDHAWK_PALAPI PalHijack(HANDLE hThread, _In_opt_ void* p abort(); } } +#endif // FEATURE_HIJACK extern "C" uint32_t WaitForSingleObjectEx(HANDLE handle, uint32_t milliseconds, UInt32_BOOL alertable) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs index e77a106b252baf..c0bceb7963c8ad 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; -using Internal.Runtime.Augments; +using Debug = System.Diagnostics.Debug; namespace Internal.Runtime.CompilerServices { @@ -56,6 +56,8 @@ public override int GetHashCode() public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunctionPointer, IntPtr instantiationArgument) { + Debug.Assert(canonFunctionPointer != IntPtr.Zero); + if (instantiationArgument == IntPtr.Zero) return canonFunctionPointer; @@ -79,7 +81,7 @@ public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunction // Generate new chunk if existing chunks are insufficient if (s_genericFunctionPointerCollection.Count <= newChunkIndex) { - System.Diagnostics.Debug.Assert(newSubChunkIndex == 0); + Debug.Assert(newSubChunkIndex == 0); // New generic descriptors are allocated on the native heap and not tracked in the GC. IntPtr pNewMem = (IntPtr)NativeMemory.Alloc(c_genericDictionaryChunkSize, (nuint)sizeof(GenericMethodDescriptor)); @@ -100,8 +102,8 @@ public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunction uint subChunkIndex = index % c_genericDictionaryChunkSize; GenericMethodDescriptor* genericFunctionPointer = &((GenericMethodDescriptor*)s_genericFunctionPointerCollection[chunkIndex])[subChunkIndex]; - System.Diagnostics.Debug.Assert(canonFunctionPointer == genericFunctionPointer->MethodFunctionPointer); - System.Diagnostics.Debug.Assert(instantiationArgument == genericFunctionPointer->InstantiationArgument); + Debug.Assert(canonFunctionPointer == genericFunctionPointer->MethodFunctionPointer); + Debug.Assert(instantiationArgument == genericFunctionPointer->InstantiationArgument); return (IntPtr)((byte*)genericFunctionPointer + FatFunctionPointerOffset); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 70928c997a5084..c7bfa7ff2215ed 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -1,8 +1,6 @@ true - - $(NoWarn);AD0001 diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs index ee76c4a5e302dd..5e855eb58565d6 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Reflection.Metadata; namespace System.Reflection { @@ -129,6 +130,11 @@ public AssemblyName ToAssemblyName() return assemblyName; } + internal static RuntimeAssemblyName FromAssemblyNameInfo(AssemblyNameInfo source) + { + return new(source.Name, source.Version, source.CultureName, source._flags, source.PublicKeyOrToken); + } + // // Copies a RuntimeAssemblyName into a freshly allocated AssemblyName with no data aliasing to any other object. // @@ -142,10 +148,10 @@ public void CopyToAssemblyName(AssemblyName blank) // Our "Flags" contain both the classic flags and the ProcessorArchitecture + ContentType bits. The public AssemblyName has separate properties for // these. The setters for these properties quietly mask out any bits intended for the other one, so we needn't do that ourselves.. - blank.Flags = ExtractAssemblyNameFlags(this.Flags); - blank.ContentType = ExtractAssemblyContentType(this.Flags); + blank.Flags = AssemblyNameInfo.ExtractAssemblyNameFlags(this.Flags); + blank.ContentType = AssemblyNameInfo.ExtractAssemblyContentType(this.Flags); #pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete - blank.ProcessorArchitecture = ExtractProcessorArchitecture(this.Flags); + blank.ProcessorArchitecture = AssemblyNameInfo.ExtractProcessorArchitecture(this.Flags); #pragma warning restore SYSLIB0037 if (this.PublicKeyOrToken != null) @@ -168,17 +174,8 @@ public string FullName get { byte[]? pkt = (0 != (Flags & AssemblyNameFlags.PublicKey)) ? AssemblyNameHelpers.ComputePublicKeyToken(PublicKeyOrToken) : PublicKeyOrToken; - return AssemblyNameFormatter.ComputeDisplayName(Name, Version, CultureName, pkt, ExtractAssemblyNameFlags(Flags), ExtractAssemblyContentType(Flags)); + return AssemblyNameFormatter.ComputeDisplayName(Name, Version, CultureName, pkt, AssemblyNameInfo.ExtractAssemblyNameFlags(Flags), AssemblyNameInfo.ExtractAssemblyContentType(Flags)); } } - - private static AssemblyNameFlags ExtractAssemblyNameFlags(AssemblyNameFlags combinedFlags) - => combinedFlags & unchecked((AssemblyNameFlags)0xFFFFF10F); - - private static AssemblyContentType ExtractAssemblyContentType(AssemblyNameFlags flags) - => (AssemblyContentType)((((int)flags) >> 9) & 0x7); - - private static ProcessorArchitecture ExtractProcessorArchitecture(AssemblyNameFlags flags) - => (ProcessorArchitecture)((((int)flags) >> 4) & 0x7); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/TypeNameParser.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/TypeNameParser.NativeAot.cs index e370cb4eed0a83..2149003ddcfb4c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/TypeNameParser.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/TypeNameParser.NativeAot.cs @@ -1,8 +1,6 @@ // 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.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection.Runtime.Assemblies; @@ -53,7 +51,13 @@ internal partial struct TypeNameParser return null; } - return new TypeNameParser(typeName) + Metadata.TypeName? parsed = Metadata.TypeNameParser.Parse(typeName, throwOnError); + if (parsed is null) + { + return null; + } + + return new TypeNameParser() { _assemblyResolver = assemblyResolver, _typeResolver = typeResolver, @@ -61,7 +65,7 @@ internal partial struct TypeNameParser _ignoreCase = ignoreCase, _extensibleParser = extensibleParser, _defaultAssemblyName = defaultAssemblyName - }.Parse(); + }.Resolve(parsed); } internal static Type? GetType( @@ -70,35 +74,35 @@ internal partial struct TypeNameParser bool ignoreCase, Assembly topLevelAssembly) { - return new TypeNameParser(typeName) + Metadata.TypeName? parsed = Metadata.TypeNameParser.Parse(typeName, throwOnError); + + if (parsed is null) + { + return null; + } + else if (topLevelAssembly is not null && parsed.AssemblyName is not null) + { + return throwOnError ? throw new ArgumentException(SR.Argument_AssemblyGetTypeCannotSpecifyAssembly) : null; + } + + return new TypeNameParser() { _throwOnError = throwOnError, _ignoreCase = ignoreCase, _topLevelAssembly = topLevelAssembly, - }.Parse(); + }.Resolve(parsed); } - private bool CheckTopLevelAssemblyQualifiedName() - { - if (_topLevelAssembly is not null) - { - if (_throwOnError) - throw new ArgumentException(SR.Argument_AssemblyGetTypeCannotSpecifyAssembly); - return false; - } - return true; - } - - private Assembly? ResolveAssembly(string assemblyName) + private Assembly? ResolveAssembly(Metadata.AssemblyNameInfo assemblyName) { Assembly? assembly; if (_assemblyResolver is not null) { - assembly = _assemblyResolver(new AssemblyName(assemblyName)); + assembly = _assemblyResolver(assemblyName.ToAssemblyName()); } else { - assembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(RuntimeAssemblyName.Parse(assemblyName)); + assembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(RuntimeAssemblyName.FromAssemblyNameInfo(assemblyName)); } if (assembly is null && _throwOnError) @@ -113,13 +117,13 @@ private bool CheckTopLevelAssemblyQualifiedName() Justification = "GetType APIs are marked as RequiresUnreferencedCode.")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", Justification = "GetType APIs are marked as RequiresUnreferencedCode.")] - private Type? GetType(string typeName, ReadOnlySpan nestedTypeNames, string? assemblyNameIfAny) + private Type? GetType(string escapedTypeName, ReadOnlySpan nestedTypeNames, Metadata.TypeName parsedName) { Assembly? assembly; - if (assemblyNameIfAny is not null) + if (parsedName.AssemblyName is not null) { - assembly = ResolveAssembly(assemblyNameIfAny); + assembly = ResolveAssembly(parsedName.AssemblyName); if (assembly is null) return null; } @@ -133,8 +137,6 @@ private bool CheckTopLevelAssemblyQualifiedName() // Resolve the top level type. if (_typeResolver is not null) { - string escapedTypeName = EscapeTypeName(typeName); - type = _typeResolver(assembly, escapedTypeName, _ignoreCase); if (type is null) @@ -154,14 +156,14 @@ private bool CheckTopLevelAssemblyQualifiedName() { if (assembly is RuntimeAssemblyInfo runtimeAssembly) { - type = runtimeAssembly.GetTypeCore(typeName, throwOnError: _throwOnError, ignoreCase: _ignoreCase); + type = runtimeAssembly.GetTypeCore(UnescapeTypeName(escapedTypeName), throwOnError: _throwOnError, ignoreCase: _ignoreCase); } else { // This is a third-party Assembly object. We can emulate GetTypeCore() by calling the public GetType() // method. This is wasteful because it'll probably reparse a type string that we've already parsed // but it can't be helped. - type = assembly.GetType(EscapeTypeName(typeName), throwOnError: _throwOnError, ignoreCase: _ignoreCase); + type = assembly.GetType(escapedTypeName, throwOnError: _throwOnError, ignoreCase: _ignoreCase); } if (type is null) @@ -169,13 +171,15 @@ private bool CheckTopLevelAssemblyQualifiedName() } else { + string? unescapedTypeName = UnescapeTypeName(escapedTypeName); + RuntimeAssemblyInfo? defaultAssembly = null; if (_defaultAssemblyName != null) { defaultAssembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(RuntimeAssemblyName.Parse(_defaultAssemblyName)); if (defaultAssembly != null) { - type = defaultAssembly.GetTypeCore(typeName, throwOnError: false, ignoreCase: _ignoreCase); + type = defaultAssembly.GetTypeCore(unescapedTypeName, throwOnError: false, ignoreCase: _ignoreCase); } } @@ -185,7 +189,7 @@ private bool CheckTopLevelAssemblyQualifiedName() coreLib = (RuntimeAssemblyInfo)typeof(object).Assembly; if (coreLib != assembly) { - type = coreLib.GetTypeCore(typeName, throwOnError: false, ignoreCase: _ignoreCase); + type = coreLib.GetTypeCore(unescapedTypeName, throwOnError: false, ignoreCase: _ignoreCase); } } @@ -193,7 +197,7 @@ private bool CheckTopLevelAssemblyQualifiedName() { if (_throwOnError) { - throw Helpers.CreateTypeLoadException(typeName, (defaultAssembly ?? coreLib).FullName); + throw Helpers.CreateTypeLoadException(unescapedTypeName, (defaultAssembly ?? coreLib).FullName); } return null; } @@ -214,10 +218,9 @@ private bool CheckTopLevelAssemblyQualifiedName() if (type is null && _ignoreCase && !_extensibleParser) { // Return the first name that matches. Which one gets returned on a multiple match is an implementation detail. - string lowerName = nestedTypeNames[i].ToLowerInvariant(); foreach (Type nt in declaringType.GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Public)) { - if (nt.Name.ToLowerInvariant() == lowerName) + if (nt.Name.Equals(nestedTypeNames[i], StringComparison.InvariantCultureIgnoreCase)) { type = nt; break; @@ -230,7 +233,7 @@ private bool CheckTopLevelAssemblyQualifiedName() if (_throwOnError) { throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveNestedType, - nestedTypeNames[i], (i > 0) ? nestedTypeNames[i - 1] : typeName)); + nestedTypeNames[i], (i > 0) ? nestedTypeNames[i - 1] : escapedTypeName)); } return null; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Condition.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Condition.cs index ba8aba61a0a1b3..2321c5bafe14b7 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Condition.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Condition.cs @@ -32,6 +32,8 @@ private static Waiter GetWaiterForCurrentThread() private Waiter? _waitersHead; private Waiter? _waitersTail; + internal Lock AssociatedLock => _lock; + private unsafe void AssertIsInList(Waiter waiter) { Debug.Assert(_waitersHead != null && _waitersTail != null); @@ -106,6 +108,8 @@ public unsafe bool Wait(int millisecondsTimeout, object? associatedObjectForMoni if (!_lock.IsHeldByCurrentThread) throw new SynchronizationLockException(); + using ThreadBlockingInfo.Scope threadBlockingScope = new(this, millisecondsTimeout); + Waiter waiter = GetWaiterForCurrentThread(); AddWaiter(waiter); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs index 7ac43d2257e786..999d4061543ed5 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Diagnostics.Tracing; +using System.Runtime; using System.Runtime.CompilerServices; namespace System.Threading @@ -17,13 +18,19 @@ public sealed partial class Lock private static int s_staticsInitializationStage; private static bool s_isSingleProcessor; private static short s_maxSpinCount; - private static short s_minSpinCount; + private static short s_minSpinCountForAdaptiveSpin; /// /// Initializes a new instance of the class. /// public Lock() => _spinCount = SpinCountNotInitialized; +#pragma warning disable CA1822 // can be marked as static - varies between runtimes + internal ulong OwningOSThreadId => 0; +#pragma warning restore CA1822 + + internal int OwningManagedThreadId => (int)_owningThreadId; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal bool TryEnterOneShot(int currentManagedThreadId) { @@ -92,18 +99,6 @@ internal void Reenter(uint previousRecursionCount) _recursionCount = previousRecursionCount; } - private static bool IsFullyInitialized - { - get - { - // If NativeRuntimeEventSource is already being class-constructed by this thread earlier in the stack, Log can - // be null. This property is used to avoid going down the wait path in that case to avoid null checks in several - // other places. - Debug.Assert((StaticsInitializationStage)s_staticsInitializationStage == StaticsInitializationStage.Complete); - return NativeRuntimeEventSource.Log != null; - } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private TryLockResult LazyInitializeOrEnter() { @@ -113,10 +108,6 @@ private TryLockResult LazyInitializeOrEnter() case StaticsInitializationStage.Complete: if (_spinCount == SpinCountNotInitialized) { - if (!IsFullyInitialized) - { - goto case StaticsInitializationStage.Started; - } _spinCount = s_maxSpinCount; } return TryLockResult.Spin; @@ -137,7 +128,7 @@ private TryLockResult LazyInitializeOrEnter() } stage = (StaticsInitializationStage)Volatile.Read(ref s_staticsInitializationStage); - if (stage == StaticsInitializationStage.Complete && IsFullyInitialized) + if (stage == StaticsInitializationStage.Complete) { goto case StaticsInitializationStage.Complete; } @@ -155,7 +146,9 @@ private TryLockResult LazyInitializeOrEnter() } default: - Debug.Assert(stage == StaticsInitializationStage.NotStarted); + Debug.Assert( + stage == StaticsInitializationStage.NotStarted || + stage == StaticsInitializationStage.PartiallyComplete); if (TryInitializeStatics()) { goto case StaticsInitializationStage.Complete; @@ -169,29 +162,53 @@ private static bool TryInitializeStatics() { // Since Lock is used to synchronize class construction, and some of the statics initialization may involve class // construction, update the stage first to avoid infinite recursion - switch ( - (StaticsInitializationStage) - Interlocked.CompareExchange( - ref s_staticsInitializationStage, - (int)StaticsInitializationStage.Started, - (int)StaticsInitializationStage.NotStarted)) + var oldStage = (StaticsInitializationStage)s_staticsInitializationStage; + while (true) { - case StaticsInitializationStage.Started: - return false; - case StaticsInitializationStage.Complete: + if (oldStage == StaticsInitializationStage.Complete) + { return true; + } + + var stageBeforeUpdate = + (StaticsInitializationStage)Interlocked.CompareExchange( + ref s_staticsInitializationStage, + (int)StaticsInitializationStage.Started, + (int)oldStage); + if (stageBeforeUpdate == StaticsInitializationStage.Started) + { + return false; + } + if (stageBeforeUpdate == oldStage) + { + Debug.Assert( + oldStage == StaticsInitializationStage.NotStarted || + oldStage == StaticsInitializationStage.PartiallyComplete); + break; + } + + oldStage = stageBeforeUpdate; } bool isFullyInitialized; try { - s_isSingleProcessor = Environment.IsSingleProcessor; - s_maxSpinCount = DetermineMaxSpinCount(); - s_minSpinCount = DetermineMinSpinCount(); + if (oldStage == StaticsInitializationStage.NotStarted) + { + // If the stage is PartiallyComplete, these will have already been initialized. + // + // Not using Environment.ProcessorCount here as it involves class construction, and if that property is + // already being constructed earlier in the stack on the same thread, it would return the default value + // here. Initialize s_isSingleProcessor first, as it may be used by other initialization afterwards. + s_isSingleProcessor = RuntimeImports.RhGetProcessCpuCount() == 1; + s_maxSpinCount = DetermineMaxSpinCount(); + s_minSpinCountForAdaptiveSpin = DetermineMinSpinCountForAdaptiveSpin(); + } // Also initialize some types that are used later to prevent potential class construction cycles. If // NativeRuntimeEventSource is already being class-constructed by this thread earlier in the stack, Log can be - // null. Avoid going down the wait path in that case to avoid null checks in several other places. + // null. Avoid going down the wait path in that case to avoid null checks in several other places. If not fully + // initialized, the stage will also be set to PartiallyComplete to try again. isFullyInitialized = NativeRuntimeEventSource.Log != null; } catch @@ -200,7 +217,11 @@ private static bool TryInitializeStatics() throw; } - Volatile.Write(ref s_staticsInitializationStage, (int)StaticsInitializationStage.Complete); + Volatile.Write( + ref s_staticsInitializationStage, + isFullyInitialized + ? (int)StaticsInitializationStage.Complete + : (int)StaticsInitializationStage.PartiallyComplete); return isFullyInitialized; } @@ -242,6 +263,7 @@ private enum StaticsInitializationStage { NotStarted, Started, + PartiallyComplete, Complete } } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs index 04958f81927abf..90a2c9857c6dc1 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutInfoLoadContext.cs @@ -193,18 +193,16 @@ internal MethodDesc GetMethod(ref NativeParser parser, out RuntimeSignature meth { TypeDesc[] typeArguments = GetTypeSequence(ref parser); Debug.Assert(typeArguments.Length > 0); - retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, containingType, nameAndSignature, new Instantiation(typeArguments), functionPointer, (flags & MethodFlags.FunctionPointerIsUSG) != 0); + retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, containingType, nameAndSignature, new Instantiation(typeArguments)); } else { - retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, containingType, nameAndSignature, functionPointer, (flags & MethodFlags.FunctionPointerIsUSG) != 0); + retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, containingType, nameAndSignature); } - if ((flags & MethodFlags.FunctionPointerIsUSG) != 0) + if ((flags & MethodFlags.HasFunctionPointer) != 0) { - // TODO, consider a change such that if a USG function pointer is passed in, but we have - // a way to get a non-usg pointer, that may be preferable - Debug.Assert(retVal.UsgFunctionPointer != IntPtr.Zero); + retVal.SetFunctionPointer(functionPointer); } return retVal; diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 8ee004b11d42c7..43ea9b81d8bf0e 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -300,7 +300,7 @@ internal void ParseNativeLayoutInfo(InstantiatedMethod method) if (method.UnboxingStub) { // Strip unboxing stub, note the first parameter which is false - nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(false, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation, IntPtr.Zero, false); + nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(false, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation); } uint nativeLayoutInfoToken; @@ -311,9 +311,11 @@ internal void ParseNativeLayoutInfo(InstantiatedMethod method) throw new MissingTemplateException(); } - if (templateMethod.FunctionPointer != IntPtr.Zero) + // We might have a mismatch between unboxing/non-unboxing variants so only remember it for static methods + if (TypeLoaderEnvironment.IsStaticMethodSignature(templateMethod.NameAndSignature) + && templateMethod.FunctionPointer != IntPtr.Zero) { - nonTemplateMethod.SetFunctionPointer(templateMethod.FunctionPointer, isFunctionPointerUSG: false); + nonTemplateMethod.SetFunctionPointer(templateMethod.FunctionPointer); } // Ensure that if this method is non-shareable from a normal canonical perspective, then diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs index c5f5308226148d..c8437c4a4e437c 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.ConstructedGenericMethodsLookup.cs @@ -153,7 +153,7 @@ internal override bool MatchParsedEntry(ref NativeParser entryParser, ref Extern DefType parsedDeclaringType = context.ResolveRuntimeTypeHandle(parsedDeclaringTypeHandle) as DefType; Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(parsedArgsHandles); - InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, nameAndSignature, parsedArgs, IntPtr.Zero, false); + InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, nameAndSignature, parsedArgs); return parsedGenericMethod == _methodToLookup; } @@ -164,7 +164,7 @@ internal override bool MatchGenericMethodEntry(GenericMethodEntry entry) DefType parsedDeclaringType = context.ResolveRuntimeTypeHandle(entry._declaringTypeHandle) as DefType; Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(entry._genericMethodArgumentHandles); - InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, entry._methodNameAndSignature, parsedArgs, IntPtr.Zero, false); + InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, entry._methodNameAndSignature, parsedArgs); return parsedGenericMethod == _methodToLookup; } @@ -267,9 +267,7 @@ public bool TryGetGenericVirtualMethodPointer(InstantiatedMethod method, out Int return false; } - methodPointer = templateMethod.IsCanonicalMethod(CanonicalFormKind.Universal) ? - templateMethod.UsgFunctionPointer : - templateMethod.FunctionPointer; + methodPointer = templateMethod.FunctionPointer; if (!TryLookupGenericMethodDictionary(new MethodDescBasedGenericMethodLookup(method), out dictionaryPointer)) { diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs index d9416b32863869..c73df4af62b5d7 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.GVMResolution.cs @@ -309,7 +309,7 @@ private static InstantiatedMethod FindMatchingInterfaceSlot(NativeFormatModuleIn Debug.Assert(interfaceImplType != null); } - return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, interfaceImplType, targetMethodNameAndSignature, slotMethod.Instantiation, IntPtr.Zero, false); + return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, interfaceImplType, targetMethodNameAndSignature, slotMethod.Instantiation); } } } @@ -500,7 +500,7 @@ private static InstantiatedMethod ResolveGenericVirtualMethodTarget(DefType targ Debug.Assert(targetMethodNameAndSignature != null); TypeSystemContext context = slotMethod.Context; - return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, targetType, targetMethodNameAndSignature, slotMethod.Instantiation, IntPtr.Zero, false); + return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, targetType, targetMethodNameAndSignature, slotMethod.Instantiation); } } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs index 9ddec8a39d7aa3..dd2bc75e3d61d4 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs @@ -388,10 +388,10 @@ public MethodDesc GetMethodDescForDynamicRuntimeMethodHandle(TypeSystemContext c if (genericMethodArgs != null) { Instantiation methodInst = context.ResolveRuntimeTypeHandles(genericMethodArgs); - return context.ResolveGenericMethodInstantiation(unboxingStub: false, type, nameAndSignature, methodInst, default, default); + return context.ResolveGenericMethodInstantiation(unboxingStub: false, type, nameAndSignature, methodInst); } - return context.ResolveRuntimeMethod(unboxingStub: false, type, nameAndSignature, default, default); + return context.ResolveRuntimeMethod(unboxingStub: false, type, nameAndSignature); } private unsafe bool TryGetStaticRuntimeMethodHandleComponents(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgs) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs index 42864c10f2ebc7..22c07b2e837bc6 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs @@ -485,7 +485,7 @@ public bool TryGetGenericMethodDictionaryForComponents(RuntimeTypeHandle declari TypeSystemContext context = TypeSystemContextFactory.Create(); DefType declaringType = (DefType)context.ResolveRuntimeTypeHandle(declaringTypeHandle); - InstantiatedMethod methodBeingLoaded = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, declaringType, nameAndSignature, context.ResolveRuntimeTypeHandles(genericMethodArgHandles), IntPtr.Zero, false); + InstantiatedMethod methodBeingLoaded = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, declaringType, nameAndSignature, context.ResolveRuntimeTypeHandles(genericMethodArgHandles)); if (TryLookupGenericMethodDictionary(new MethodDescBasedGenericMethodLookup(methodBeingLoaded), out methodDictionary)) { diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/MethodDesc.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/MethodDesc.Runtime.cs index 89161ce5309d72..24dceff6d0f05f 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/MethodDesc.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/MethodDesc.Runtime.cs @@ -6,19 +6,18 @@ using Internal.Runtime.CompilerServices; +using Debug = System.Diagnostics.Debug; + namespace Internal.TypeSystem { public partial class MethodDesc { private IntPtr _functionPointer; - private IntPtr _usgFunctionPointer; - public void SetFunctionPointer(IntPtr functionPointer, bool isFunctionPointerUSG) + public void SetFunctionPointer(IntPtr functionPointer) { - if (isFunctionPointerUSG) - _usgFunctionPointer = functionPointer; - else - _functionPointer = functionPointer; + Debug.Assert(_functionPointer == IntPtr.Zero || _functionPointer == functionPointer); + _functionPointer = functionPointer; } /// @@ -32,17 +31,6 @@ public IntPtr FunctionPointer } } - /// - /// Pointer to function's universal shared generics code. May be IntPtr.Zero - /// - public IntPtr UsgFunctionPointer - { - get - { - return _usgFunctionPointer; - } - } - public abstract MethodNameAndSignature NameAndSignature { get; } private bool? _isNonSharableCache; diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.Canon.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.Canon.cs index 956dcdcafb9761..ad12ea96f00817 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.Canon.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.Canon.cs @@ -23,7 +23,7 @@ public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind) if (canonicalizedTypeOfTargetMethod == OwningType) return this; - return Context.ResolveRuntimeMethod(this.UnboxingStub, canonicalizedTypeOfTargetMethod, this.NameAndSignature, IntPtr.Zero, false); + return Context.ResolveRuntimeMethod(this.UnboxingStub, canonicalizedTypeOfTargetMethod, this.NameAndSignature); } } } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.cs index f95b8561e3a9dc..042b1957e22b65 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/RuntimeMethodDesc.cs @@ -117,7 +117,7 @@ public override MethodDesc GetTypicalMethodDefinition() } // Otherwise, find its equivalent on the type definition of the owning type - return Context.ResolveRuntimeMethod(UnboxingStub, (DefType)owningTypeDefinition, _nameAndSignature, IntPtr.Zero, false); + return Context.ResolveRuntimeMethod(UnboxingStub, (DefType)owningTypeDefinition, _nameAndSignature); } public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation) @@ -127,7 +127,7 @@ public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, TypeDesc owningType = method.OwningType; TypeDesc instantiatedOwningType = owningType.InstantiateSignature(typeInstantiation, methodInstantiation); if (owningType != instantiatedOwningType) - method = instantiatedOwningType.Context.ResolveRuntimeMethod(UnboxingStub, (DefType)instantiatedOwningType, _nameAndSignature, IntPtr.Zero, false); + method = instantiatedOwningType.Context.ResolveRuntimeMethod(UnboxingStub, (DefType)instantiatedOwningType, _nameAndSignature); Instantiation instantiation = method.Instantiation; TypeDesc[] clone = null; diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs index 464a370a5f7be3..1e4b888552220a 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs @@ -417,7 +417,7 @@ protected override MethodDesc CreateValueFromKey(RuntimeMethodKey key) // Instantiated Types always get their methods through GetMethodForInstantiatedType if (key._owningType is InstantiatedType) { - MethodDesc typicalMethod = key._owningType.Context.ResolveRuntimeMethod(key._unboxingStub, (DefType)key._owningType.GetTypeDefinition(), key._methodNameAndSignature, IntPtr.Zero, false); + MethodDesc typicalMethod = key._owningType.Context.ResolveRuntimeMethod(key._unboxingStub, (DefType)key._owningType.GetTypeDefinition(), key._methodNameAndSignature); return typicalMethod.Context.GetMethodForInstantiatedType(typicalMethod, (InstantiatedType)key._owningType); } } @@ -434,18 +434,10 @@ protected override MethodDesc CreateValueFromKey(RuntimeMethodKey key) private RuntimeMethodKey.RuntimeMethodKeyHashtable _runtimeMethods; - internal MethodDesc ResolveRuntimeMethod(bool unboxingStub, DefType owningType, MethodNameAndSignature nameAndSignature, IntPtr functionPointer, bool usgFunctionPointer) + internal MethodDesc ResolveRuntimeMethod(bool unboxingStub, DefType owningType, MethodNameAndSignature nameAndSignature) { _runtimeMethods ??= new RuntimeMethodKey.RuntimeMethodKeyHashtable(); - - MethodDesc retVal = _runtimeMethods.GetOrCreateValue(new RuntimeMethodKey(unboxingStub, owningType, nameAndSignature)); - - if (functionPointer != IntPtr.Zero) - { - retVal.SetFunctionPointer(functionPointer, usgFunctionPointer); - } - - return retVal; + return _runtimeMethods.GetOrCreateValue(new RuntimeMethodKey(unboxingStub, owningType, nameAndSignature)); } private LowLevelDictionary _genericTypeInstances; @@ -479,9 +471,9 @@ public DefType ResolveGenericInstantiation(DefType typeDef, Instantiation argume /// /// Find a method based on owner type and nativelayout name, method instantiation, and signature. /// - public MethodDesc ResolveGenericMethodInstantiation(bool unboxingStub, DefType owningType, MethodNameAndSignature nameAndSignature, Instantiation methodInstantiation, IntPtr functionPointer, bool usgFunctionPointer) + public MethodDesc ResolveGenericMethodInstantiation(bool unboxingStub, DefType owningType, MethodNameAndSignature nameAndSignature, Instantiation methodInstantiation) { - var uninstantiatedMethod = ResolveRuntimeMethod(unboxingStub, owningType, nameAndSignature, IntPtr.Zero, false); + var uninstantiatedMethod = ResolveRuntimeMethod(unboxingStub, owningType, nameAndSignature); MethodDesc returnedMethod; if (methodInstantiation.IsNull || (methodInstantiation.Length == 0)) @@ -492,12 +484,6 @@ public MethodDesc ResolveGenericMethodInstantiation(bool unboxingStub, DefType o { returnedMethod = GetInstantiatedMethod(uninstantiatedMethod, methodInstantiation); } - - if (functionPointer != IntPtr.Zero) - { - returnedMethod.SetFunctionPointer(functionPointer, usgFunctionPointer); - } - return returnedMethod; } diff --git a/src/coreclr/pal/prebuilt/idl/cordebug_i.cpp b/src/coreclr/pal/prebuilt/idl/cordebug_i.cpp index 6bfe487fd5ff0b..811cd6512fa047 100644 --- a/src/coreclr/pal/prebuilt/idl/cordebug_i.cpp +++ b/src/coreclr/pal/prebuilt/idl/cordebug_i.cpp @@ -474,6 +474,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionObjectCallStackEnum,0xED775530,0x4DC MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionObjectValue,0xAE4CA65D,0x59DD,0x42A2,0x83,0xA5,0x57,0xE8,0xA0,0x8D,0x87,0x19); +MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionObjectValue2,0xe3b2f332,0xcc46,0x4f1e,0xab,0x4e,0x54,0x00,0xe3,0x32,0x19,0x5e); + + MIDL_DEFINE_GUID(IID, LIBID_CORDBLib,0x53D13620,0xF417,0x11d1,0x97,0x62,0xA6,0x38,0x26,0xA4,0xF2,0x55); diff --git a/src/coreclr/pal/prebuilt/inc/cordebug.h b/src/coreclr/pal/prebuilt/inc/cordebug.h index 6d74b1a412f8c4..78b86c69ee96b9 100644 --- a/src/coreclr/pal/prebuilt/inc/cordebug.h +++ b/src/coreclr/pal/prebuilt/inc/cordebug.h @@ -5,10 +5,10 @@ /* File created by MIDL compiler version 8.01.0628 */ /* Compiler settings for cordebug.idl: - Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0628 + Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0628 protocol : dce , ms_ext, c_ext, robust - error checks: allocation ref bounds_check enum stub_data - VC __declspec() decoration level: + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: __declspec(uuid()), __declspec(selectany), __declspec(novtable) DECLSPEC_UUID(), MIDL_INTERFACE() */ @@ -49,7 +49,7 @@ #endif #endif -/* Forward Declarations */ +/* Forward Declarations */ #ifndef __ICorDebugDataTarget_FWD_DEFINED__ #define __ICorDebugDataTarget_FWD_DEFINED__ @@ -1003,6 +1003,13 @@ typedef interface ICorDebugExceptionObjectValue ICorDebugExceptionObjectValue; #endif /* __ICorDebugExceptionObjectValue_FWD_DEFINED__ */ +#ifndef __ICorDebugExceptionObjectValue2_FWD_DEFINED__ +#define __ICorDebugExceptionObjectValue2_FWD_DEFINED__ +typedef interface ICorDebugExceptionObjectValue2 ICorDebugExceptionObjectValue2; + +#endif /* __ICorDebugExceptionObjectValue2_FWD_DEFINED__ */ + + #ifndef __CorDebug_FWD_DEFINED__ #define __CorDebug_FWD_DEFINED__ @@ -1264,11 +1271,11 @@ typedef interface ICorDebugModule3 ICorDebugModule3; #ifdef __cplusplus extern "C"{ -#endif +#endif /* interface __MIDL_itf_cordebug_0000_0000 */ -/* [local] */ +/* [local] */ #if 0 typedef UINT32 mdToken; @@ -1322,7 +1329,7 @@ typedef struct _COR_IL_MAP #endif //_COR_IL_MAP #ifndef _COR_DEBUG_IL_TO_NATIVE_MAP_ #define _COR_DEBUG_IL_TO_NATIVE_MAP_ -typedef +typedef enum CorDebugIlToNativeMappingTypes { NO_MAPPING = -1, @@ -1339,7 +1346,7 @@ typedef struct COR_DEBUG_IL_TO_NATIVE_MAP #endif // _COR_DEBUG_IL_TO_NATIVE_MAP_ #define REMOTE_DEBUGGING_DLL_ENTRY L"Software\\Microsoft\\.NETFramework\\Debugger\\ActivateRemoteDebugging" -typedef +typedef enum CorDebugJITCompilerFlags { CORDEBUG_JIT_DEFAULT = 0x1, @@ -1347,20 +1354,20 @@ enum CorDebugJITCompilerFlags CORDEBUG_JIT_ENABLE_ENC = 0x7 } CorDebugJITCompilerFlags; -typedef +typedef enum CorDebugJITCompilerFlagsDecprecated { CORDEBUG_JIT_TRACK_DEBUG_INFO = 0x1 } CorDebugJITCompilerFlagsDeprecated; -typedef +typedef enum CorDebugNGENPolicy { DISABLE_LOCAL_NIC = 1 } CorDebugNGENPolicy; #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) @@ -1435,7 +1442,7 @@ typedef ULONG64 CORDB_REGISTER; typedef DWORD CORDB_CONTINUE_STATUS; -typedef +typedef enum CorDebugBlockingReason { BLOCKING_NONE = 0, @@ -1473,9 +1480,9 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0000_v0_0_s_ifspec; #define __ICorDebugDataTarget_INTERFACE_DEFINED__ /* interface ICorDebugDataTarget */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugPlatform { CORDB_PLATFORM_WINDOWS_X86 = 0, @@ -1491,78 +1498,78 @@ enum CorDebugPlatform CORDB_PLATFORM_POSIX_ARM = ( CORDB_PLATFORM_POSIX_X86 + 1 ) , CORDB_PLATFORM_POSIX_ARM64 = ( CORDB_PLATFORM_POSIX_ARM + 1 ) , CORDB_PLATFORM_POSIX_LOONGARCH64 = ( CORDB_PLATFORM_POSIX_ARM64 + 1 ) , - CORDB_PLATFORM_POSIX_RISCV64 = ( CORDB_PLATFORM_POSIX_LOONGARCH64 + 1 ) + CORDB_PLATFORM_POSIX_RISCV64 = ( CORDB_PLATFORM_POSIX_LOONGARCH64 + 1 ) } CorDebugPlatform; EXTERN_C const IID IID_ICorDebugDataTarget; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("FE06DC28-49FB-4636-A4A3-E80DB4AE116C") ICorDebugDataTarget : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetPlatform( + virtual HRESULT STDMETHODCALLTYPE GetPlatform( /* [out] */ CorDebugPlatform *pTargetPlatform) = 0; - - virtual HRESULT STDMETHODCALLTYPE ReadVirtual( + + virtual HRESULT STDMETHODCALLTYPE ReadVirtual( /* [in] */ CORDB_ADDRESS address, /* [length_is][size_is][out] */ BYTE *pBuffer, /* [in] */ ULONG32 bytesRequested, /* [out] */ ULONG32 *pBytesRead) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadContext( + + virtual HRESULT STDMETHODCALLTYPE GetThreadContext( /* [in] */ DWORD dwThreadID, /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 contextSize, /* [size_is][out] */ BYTE *pContext) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugDataTargetVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugDataTarget * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugDataTarget * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugDataTarget * This); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget, GetPlatform) - HRESULT ( STDMETHODCALLTYPE *GetPlatform )( + HRESULT ( STDMETHODCALLTYPE *GetPlatform )( ICorDebugDataTarget * This, /* [out] */ CorDebugPlatform *pTargetPlatform); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget, ReadVirtual) - HRESULT ( STDMETHODCALLTYPE *ReadVirtual )( + HRESULT ( STDMETHODCALLTYPE *ReadVirtual )( ICorDebugDataTarget * This, /* [in] */ CORDB_ADDRESS address, /* [length_is][size_is][out] */ BYTE *pBuffer, /* [in] */ ULONG32 bytesRequested, /* [out] */ ULONG32 *pBytesRead); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget, GetThreadContext) - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorDebugDataTarget * This, /* [in] */ DWORD dwThreadID, /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 contextSize, /* [size_is][out] */ BYTE *pContext); - + END_INTERFACE } ICorDebugDataTargetVtbl; @@ -1571,29 +1578,29 @@ EXTERN_C const IID IID_ICorDebugDataTarget; CONST_VTBL struct ICorDebugDataTargetVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugDataTarget_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugDataTarget_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugDataTarget_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugDataTarget_GetPlatform(This,pTargetPlatform) \ - ( (This)->lpVtbl -> GetPlatform(This,pTargetPlatform) ) + ( (This)->lpVtbl -> GetPlatform(This,pTargetPlatform) ) #define ICorDebugDataTarget_ReadVirtual(This,address,pBuffer,bytesRequested,pBytesRead) \ - ( (This)->lpVtbl -> ReadVirtual(This,address,pBuffer,bytesRequested,pBytesRead) ) + ( (This)->lpVtbl -> ReadVirtual(This,address,pBuffer,bytesRequested,pBytesRead) ) #define ICorDebugDataTarget_GetThreadContext(This,dwThreadID,contextFlags,contextSize,pContext) \ - ( (This)->lpVtbl -> GetThreadContext(This,dwThreadID,contextFlags,contextSize,pContext) ) + ( (This)->lpVtbl -> GetThreadContext(This,dwThreadID,contextFlags,contextSize,pContext) ) #endif /* COBJMACROS */ @@ -1610,69 +1617,69 @@ EXTERN_C const IID IID_ICorDebugDataTarget; #define __ICorDebugStaticFieldSymbol_INTERFACE_DEFINED__ /* interface ICorDebugStaticFieldSymbol */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugStaticFieldSymbol; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CBF9DA63-F68D-4BBB-A21C-15A45EAADF5B") ICorDebugStaticFieldSymbol : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetName( + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pcbSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAddress( + + virtual HRESULT STDMETHODCALLTYPE GetAddress( /* [out] */ CORDB_ADDRESS *pRVA) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugStaticFieldSymbolVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugStaticFieldSymbol * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugStaticFieldSymbol * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugStaticFieldSymbol * This); - + DECLSPEC_XFGVIRT(ICorDebugStaticFieldSymbol, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugStaticFieldSymbol * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugStaticFieldSymbol, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugStaticFieldSymbol * This, /* [out] */ ULONG32 *pcbSize); - + DECLSPEC_XFGVIRT(ICorDebugStaticFieldSymbol, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugStaticFieldSymbol * This, /* [out] */ CORDB_ADDRESS *pRVA); - + END_INTERFACE } ICorDebugStaticFieldSymbolVtbl; @@ -1681,29 +1688,29 @@ EXTERN_C const IID IID_ICorDebugStaticFieldSymbol; CONST_VTBL struct ICorDebugStaticFieldSymbolVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugStaticFieldSymbol_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugStaticFieldSymbol_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugStaticFieldSymbol_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugStaticFieldSymbol_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #define ICorDebugStaticFieldSymbol_GetSize(This,pcbSize) \ - ( (This)->lpVtbl -> GetSize(This,pcbSize) ) + ( (This)->lpVtbl -> GetSize(This,pcbSize) ) #define ICorDebugStaticFieldSymbol_GetAddress(This,pRVA) \ - ( (This)->lpVtbl -> GetAddress(This,pRVA) ) + ( (This)->lpVtbl -> GetAddress(This,pRVA) ) #endif /* COBJMACROS */ @@ -1720,69 +1727,69 @@ EXTERN_C const IID IID_ICorDebugStaticFieldSymbol; #define __ICorDebugInstanceFieldSymbol_INTERFACE_DEFINED__ /* interface ICorDebugInstanceFieldSymbol */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugInstanceFieldSymbol; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("A074096B-3ADC-4485-81DA-68C7A4EA52DB") ICorDebugInstanceFieldSymbol : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetName( + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pcbSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetOffset( + + virtual HRESULT STDMETHODCALLTYPE GetOffset( /* [out] */ ULONG32 *pcbOffset) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugInstanceFieldSymbolVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugInstanceFieldSymbol * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugInstanceFieldSymbol * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugInstanceFieldSymbol * This); - + DECLSPEC_XFGVIRT(ICorDebugInstanceFieldSymbol, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugInstanceFieldSymbol * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugInstanceFieldSymbol, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugInstanceFieldSymbol * This, /* [out] */ ULONG32 *pcbSize); - + DECLSPEC_XFGVIRT(ICorDebugInstanceFieldSymbol, GetOffset) - HRESULT ( STDMETHODCALLTYPE *GetOffset )( + HRESULT ( STDMETHODCALLTYPE *GetOffset )( ICorDebugInstanceFieldSymbol * This, /* [out] */ ULONG32 *pcbOffset); - + END_INTERFACE } ICorDebugInstanceFieldSymbolVtbl; @@ -1791,29 +1798,29 @@ EXTERN_C const IID IID_ICorDebugInstanceFieldSymbol; CONST_VTBL struct ICorDebugInstanceFieldSymbolVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugInstanceFieldSymbol_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugInstanceFieldSymbol_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugInstanceFieldSymbol_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugInstanceFieldSymbol_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #define ICorDebugInstanceFieldSymbol_GetSize(This,pcbSize) \ - ( (This)->lpVtbl -> GetSize(This,pcbSize) ) + ( (This)->lpVtbl -> GetSize(This,pcbSize) ) #define ICorDebugInstanceFieldSymbol_GetOffset(This,pcbOffset) \ - ( (This)->lpVtbl -> GetOffset(This,pcbOffset) ) + ( (This)->lpVtbl -> GetOffset(This,pcbOffset) ) #endif /* COBJMACROS */ @@ -1830,82 +1837,82 @@ EXTERN_C const IID IID_ICorDebugInstanceFieldSymbol; #define __ICorDebugVariableSymbol_INTERFACE_DEFINED__ /* interface ICorDebugVariableSymbol */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugVariableSymbol; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("707E8932-1163-48D9-8A93-F5B1F480FBB7") ICorDebugVariableSymbol : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetName( + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pcbValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetValue( + + virtual HRESULT STDMETHODCALLTYPE GetValue( /* [in] */ ULONG32 offset, /* [in] */ ULONG32 cbContext, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 cbValue, /* [out] */ ULONG32 *pcbValue, /* [length_is][size_is][out] */ BYTE pValue[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetValue( + + virtual HRESULT STDMETHODCALLTYPE SetValue( /* [in] */ ULONG32 offset, /* [in] */ DWORD threadID, /* [in] */ ULONG32 cbContext, /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 cbValue, /* [size_is][in] */ BYTE pValue[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSlotIndex( + + virtual HRESULT STDMETHODCALLTYPE GetSlotIndex( /* [out] */ ULONG32 *pSlotIndex) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugVariableSymbolVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugVariableSymbol * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugVariableSymbol * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugVariableSymbol * This); - + DECLSPEC_XFGVIRT(ICorDebugVariableSymbol, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugVariableSymbol * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugVariableSymbol, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugVariableSymbol * This, /* [out] */ ULONG32 *pcbValue); - + DECLSPEC_XFGVIRT(ICorDebugVariableSymbol, GetValue) - HRESULT ( STDMETHODCALLTYPE *GetValue )( + HRESULT ( STDMETHODCALLTYPE *GetValue )( ICorDebugVariableSymbol * This, /* [in] */ ULONG32 offset, /* [in] */ ULONG32 cbContext, @@ -1913,9 +1920,9 @@ EXTERN_C const IID IID_ICorDebugVariableSymbol; /* [in] */ ULONG32 cbValue, /* [out] */ ULONG32 *pcbValue, /* [length_is][size_is][out] */ BYTE pValue[ ]); - + DECLSPEC_XFGVIRT(ICorDebugVariableSymbol, SetValue) - HRESULT ( STDMETHODCALLTYPE *SetValue )( + HRESULT ( STDMETHODCALLTYPE *SetValue )( ICorDebugVariableSymbol * This, /* [in] */ ULONG32 offset, /* [in] */ DWORD threadID, @@ -1923,12 +1930,12 @@ EXTERN_C const IID IID_ICorDebugVariableSymbol; /* [size_is][in] */ BYTE context[ ], /* [in] */ ULONG32 cbValue, /* [size_is][in] */ BYTE pValue[ ]); - + DECLSPEC_XFGVIRT(ICorDebugVariableSymbol, GetSlotIndex) - HRESULT ( STDMETHODCALLTYPE *GetSlotIndex )( + HRESULT ( STDMETHODCALLTYPE *GetSlotIndex )( ICorDebugVariableSymbol * This, /* [out] */ ULONG32 *pSlotIndex); - + END_INTERFACE } ICorDebugVariableSymbolVtbl; @@ -1937,35 +1944,35 @@ EXTERN_C const IID IID_ICorDebugVariableSymbol; CONST_VTBL struct ICorDebugVariableSymbolVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugVariableSymbol_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugVariableSymbol_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugVariableSymbol_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugVariableSymbol_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #define ICorDebugVariableSymbol_GetSize(This,pcbValue) \ - ( (This)->lpVtbl -> GetSize(This,pcbValue) ) + ( (This)->lpVtbl -> GetSize(This,pcbValue) ) #define ICorDebugVariableSymbol_GetValue(This,offset,cbContext,context,cbValue,pcbValue,pValue) \ - ( (This)->lpVtbl -> GetValue(This,offset,cbContext,context,cbValue,pcbValue,pValue) ) + ( (This)->lpVtbl -> GetValue(This,offset,cbContext,context,cbValue,pcbValue,pValue) ) #define ICorDebugVariableSymbol_SetValue(This,offset,threadID,cbContext,context,cbValue,pValue) \ - ( (This)->lpVtbl -> SetValue(This,offset,threadID,cbContext,context,cbValue,pValue) ) + ( (This)->lpVtbl -> SetValue(This,offset,threadID,cbContext,context,cbValue,pValue) ) #define ICorDebugVariableSymbol_GetSlotIndex(This,pSlotIndex) \ - ( (This)->lpVtbl -> GetSlotIndex(This,pSlotIndex) ) + ( (This)->lpVtbl -> GetSlotIndex(This,pSlotIndex) ) #endif /* COBJMACROS */ @@ -1982,57 +1989,57 @@ EXTERN_C const IID IID_ICorDebugVariableSymbol; #define __ICorDebugMemoryBuffer_INTERFACE_DEFINED__ /* interface ICorDebugMemoryBuffer */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugMemoryBuffer; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("677888B3-D160-4B8C-A73B-D79E6AAA1D13") ICorDebugMemoryBuffer : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetStartAddress( + virtual HRESULT STDMETHODCALLTYPE GetStartAddress( /* [out] */ LPCVOID *address) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pcbBufferLength) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugMemoryBufferVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugMemoryBuffer * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugMemoryBuffer * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugMemoryBuffer * This); - + DECLSPEC_XFGVIRT(ICorDebugMemoryBuffer, GetStartAddress) - HRESULT ( STDMETHODCALLTYPE *GetStartAddress )( + HRESULT ( STDMETHODCALLTYPE *GetStartAddress )( ICorDebugMemoryBuffer * This, /* [out] */ LPCVOID *address); - + DECLSPEC_XFGVIRT(ICorDebugMemoryBuffer, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugMemoryBuffer * This, /* [out] */ ULONG32 *pcbBufferLength); - + END_INTERFACE } ICorDebugMemoryBufferVtbl; @@ -2041,26 +2048,26 @@ EXTERN_C const IID IID_ICorDebugMemoryBuffer; CONST_VTBL struct ICorDebugMemoryBufferVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugMemoryBuffer_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugMemoryBuffer_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugMemoryBuffer_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugMemoryBuffer_GetStartAddress(This,address) \ - ( (This)->lpVtbl -> GetStartAddress(This,address) ) + ( (This)->lpVtbl -> GetStartAddress(This,address) ) #define ICorDebugMemoryBuffer_GetSize(This,pcbBufferLength) \ - ( (This)->lpVtbl -> GetSize(This,pcbBufferLength) ) + ( (This)->lpVtbl -> GetSize(This,pcbBufferLength) ) #endif /* COBJMACROS */ @@ -2077,111 +2084,111 @@ EXTERN_C const IID IID_ICorDebugMemoryBuffer; #define __ICorDebugMergedAssemblyRecord_INTERFACE_DEFINED__ /* interface ICorDebugMergedAssemblyRecord */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugMergedAssemblyRecord; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("FAA8637B-3BBE-4671-8E26-3B59875B922A") ICorDebugMergedAssemblyRecord : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetSimpleName( + virtual HRESULT STDMETHODCALLTYPE GetSimpleName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetVersion( + + virtual HRESULT STDMETHODCALLTYPE GetVersion( /* [out] */ USHORT *pMajor, /* [out] */ USHORT *pMinor, /* [out] */ USHORT *pBuild, /* [out] */ USHORT *pRevision) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCulture( + + virtual HRESULT STDMETHODCALLTYPE GetCulture( /* [in] */ ULONG32 cchCulture, /* [out] */ ULONG32 *pcchCulture, /* [length_is][size_is][out] */ WCHAR szCulture[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetPublicKey( + + virtual HRESULT STDMETHODCALLTYPE GetPublicKey( /* [in] */ ULONG32 cbPublicKey, /* [out] */ ULONG32 *pcbPublicKey, /* [length_is][size_is][out] */ BYTE pbPublicKey[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetPublicKeyToken( + + virtual HRESULT STDMETHODCALLTYPE GetPublicKeyToken( /* [in] */ ULONG32 cbPublicKeyToken, /* [out] */ ULONG32 *pcbPublicKeyToken, /* [length_is][size_is][out] */ BYTE pbPublicKeyToken[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetIndex( + + virtual HRESULT STDMETHODCALLTYPE GetIndex( /* [out] */ ULONG32 *pIndex) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugMergedAssemblyRecordVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugMergedAssemblyRecord * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugMergedAssemblyRecord * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugMergedAssemblyRecord * This); - + DECLSPEC_XFGVIRT(ICorDebugMergedAssemblyRecord, GetSimpleName) - HRESULT ( STDMETHODCALLTYPE *GetSimpleName )( + HRESULT ( STDMETHODCALLTYPE *GetSimpleName )( ICorDebugMergedAssemblyRecord * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugMergedAssemblyRecord, GetVersion) - HRESULT ( STDMETHODCALLTYPE *GetVersion )( + HRESULT ( STDMETHODCALLTYPE *GetVersion )( ICorDebugMergedAssemblyRecord * This, /* [out] */ USHORT *pMajor, /* [out] */ USHORT *pMinor, /* [out] */ USHORT *pBuild, /* [out] */ USHORT *pRevision); - + DECLSPEC_XFGVIRT(ICorDebugMergedAssemblyRecord, GetCulture) - HRESULT ( STDMETHODCALLTYPE *GetCulture )( + HRESULT ( STDMETHODCALLTYPE *GetCulture )( ICorDebugMergedAssemblyRecord * This, /* [in] */ ULONG32 cchCulture, /* [out] */ ULONG32 *pcchCulture, /* [length_is][size_is][out] */ WCHAR szCulture[ ]); - + DECLSPEC_XFGVIRT(ICorDebugMergedAssemblyRecord, GetPublicKey) - HRESULT ( STDMETHODCALLTYPE *GetPublicKey )( + HRESULT ( STDMETHODCALLTYPE *GetPublicKey )( ICorDebugMergedAssemblyRecord * This, /* [in] */ ULONG32 cbPublicKey, /* [out] */ ULONG32 *pcbPublicKey, /* [length_is][size_is][out] */ BYTE pbPublicKey[ ]); - + DECLSPEC_XFGVIRT(ICorDebugMergedAssemblyRecord, GetPublicKeyToken) - HRESULT ( STDMETHODCALLTYPE *GetPublicKeyToken )( + HRESULT ( STDMETHODCALLTYPE *GetPublicKeyToken )( ICorDebugMergedAssemblyRecord * This, /* [in] */ ULONG32 cbPublicKeyToken, /* [out] */ ULONG32 *pcbPublicKeyToken, /* [length_is][size_is][out] */ BYTE pbPublicKeyToken[ ]); - + DECLSPEC_XFGVIRT(ICorDebugMergedAssemblyRecord, GetIndex) - HRESULT ( STDMETHODCALLTYPE *GetIndex )( + HRESULT ( STDMETHODCALLTYPE *GetIndex )( ICorDebugMergedAssemblyRecord * This, /* [out] */ ULONG32 *pIndex); - + END_INTERFACE } ICorDebugMergedAssemblyRecordVtbl; @@ -2190,38 +2197,38 @@ EXTERN_C const IID IID_ICorDebugMergedAssemblyRecord; CONST_VTBL struct ICorDebugMergedAssemblyRecordVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugMergedAssemblyRecord_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugMergedAssemblyRecord_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugMergedAssemblyRecord_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugMergedAssemblyRecord_GetSimpleName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetSimpleName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetSimpleName(This,cchName,pcchName,szName) ) #define ICorDebugMergedAssemblyRecord_GetVersion(This,pMajor,pMinor,pBuild,pRevision) \ - ( (This)->lpVtbl -> GetVersion(This,pMajor,pMinor,pBuild,pRevision) ) + ( (This)->lpVtbl -> GetVersion(This,pMajor,pMinor,pBuild,pRevision) ) #define ICorDebugMergedAssemblyRecord_GetCulture(This,cchCulture,pcchCulture,szCulture) \ - ( (This)->lpVtbl -> GetCulture(This,cchCulture,pcchCulture,szCulture) ) + ( (This)->lpVtbl -> GetCulture(This,cchCulture,pcchCulture,szCulture) ) #define ICorDebugMergedAssemblyRecord_GetPublicKey(This,cbPublicKey,pcbPublicKey,pbPublicKey) \ - ( (This)->lpVtbl -> GetPublicKey(This,cbPublicKey,pcbPublicKey,pbPublicKey) ) + ( (This)->lpVtbl -> GetPublicKey(This,cbPublicKey,pcbPublicKey,pbPublicKey) ) #define ICorDebugMergedAssemblyRecord_GetPublicKeyToken(This,cbPublicKeyToken,pcbPublicKeyToken,pbPublicKeyToken) \ - ( (This)->lpVtbl -> GetPublicKeyToken(This,cbPublicKeyToken,pcbPublicKeyToken,pbPublicKeyToken) ) + ( (This)->lpVtbl -> GetPublicKeyToken(This,cbPublicKeyToken,pcbPublicKeyToken,pbPublicKeyToken) ) #define ICorDebugMergedAssemblyRecord_GetIndex(This,pIndex) \ - ( (This)->lpVtbl -> GetIndex(This,pIndex) ) + ( (This)->lpVtbl -> GetIndex(This,pIndex) ) #endif /* COBJMACROS */ @@ -2238,147 +2245,147 @@ EXTERN_C const IID IID_ICorDebugMergedAssemblyRecord; #define __ICorDebugSymbolProvider_INTERFACE_DEFINED__ /* interface ICorDebugSymbolProvider */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugSymbolProvider; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("3948A999-FD8A-4C38-A708-8A71E9B04DBB") ICorDebugSymbolProvider : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetStaticFieldSymbols( + virtual HRESULT STDMETHODCALLTYPE GetStaticFieldSymbols( /* [in] */ ULONG32 cbSignature, /* [size_is][in] */ BYTE typeSig[ ], /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugStaticFieldSymbol *pSymbols[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetInstanceFieldSymbols( + + virtual HRESULT STDMETHODCALLTYPE GetInstanceFieldSymbols( /* [in] */ ULONG32 cbSignature, /* [size_is][in] */ BYTE typeSig[ ], /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugInstanceFieldSymbol *pSymbols[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetMethodLocalSymbols( + + virtual HRESULT STDMETHODCALLTYPE GetMethodLocalSymbols( /* [in] */ ULONG32 nativeRVA, /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugVariableSymbol *pSymbols[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetMethodParameterSymbols( + + virtual HRESULT STDMETHODCALLTYPE GetMethodParameterSymbols( /* [in] */ ULONG32 nativeRVA, /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugVariableSymbol *pSymbols[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetMergedAssemblyRecords( + + virtual HRESULT STDMETHODCALLTYPE GetMergedAssemblyRecords( /* [in] */ ULONG32 cRequestedRecords, /* [out] */ ULONG32 *pcFetchedRecords, /* [length_is][size_is][out] */ ICorDebugMergedAssemblyRecord *pRecords[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetMethodProps( + + virtual HRESULT STDMETHODCALLTYPE GetMethodProps( /* [in] */ ULONG32 codeRva, /* [out] */ mdToken *pMethodToken, /* [out] */ ULONG32 *pcGenericParams, /* [in] */ ULONG32 cbSignature, /* [out] */ ULONG32 *pcbSignature, /* [length_is][size_is][out] */ BYTE signature[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTypeProps( + + virtual HRESULT STDMETHODCALLTYPE GetTypeProps( /* [in] */ ULONG32 vtableRva, /* [in] */ ULONG32 cbSignature, /* [out] */ ULONG32 *pcbSignature, /* [length_is][size_is][out] */ BYTE signature[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCodeRange( + + virtual HRESULT STDMETHODCALLTYPE GetCodeRange( /* [in] */ ULONG32 codeRva, /* [out] */ ULONG32 *pCodeStartAddress, ULONG32 *pCodeSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAssemblyImageBytes( + + virtual HRESULT STDMETHODCALLTYPE GetAssemblyImageBytes( /* [in] */ CORDB_ADDRESS rva, /* [in] */ ULONG32 length, /* [out] */ ICorDebugMemoryBuffer **ppMemoryBuffer) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObjectSize( + + virtual HRESULT STDMETHODCALLTYPE GetObjectSize( /* [in] */ ULONG32 cbSignature, /* [size_is][in] */ BYTE typeSig[ ], /* [out] */ ULONG32 *pObjectSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAssemblyImageMetadata( + + virtual HRESULT STDMETHODCALLTYPE GetAssemblyImageMetadata( /* [out] */ ICorDebugMemoryBuffer **ppMemoryBuffer) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugSymbolProviderVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugSymbolProvider * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugSymbolProvider * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugSymbolProvider * This); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetStaticFieldSymbols) - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldSymbols )( + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldSymbols )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 cbSignature, /* [size_is][in] */ BYTE typeSig[ ], /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugStaticFieldSymbol *pSymbols[ ]); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetInstanceFieldSymbols) - HRESULT ( STDMETHODCALLTYPE *GetInstanceFieldSymbols )( + HRESULT ( STDMETHODCALLTYPE *GetInstanceFieldSymbols )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 cbSignature, /* [size_is][in] */ BYTE typeSig[ ], /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugInstanceFieldSymbol *pSymbols[ ]); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetMethodLocalSymbols) - HRESULT ( STDMETHODCALLTYPE *GetMethodLocalSymbols )( + HRESULT ( STDMETHODCALLTYPE *GetMethodLocalSymbols )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 nativeRVA, /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugVariableSymbol *pSymbols[ ]); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetMethodParameterSymbols) - HRESULT ( STDMETHODCALLTYPE *GetMethodParameterSymbols )( + HRESULT ( STDMETHODCALLTYPE *GetMethodParameterSymbols )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 nativeRVA, /* [in] */ ULONG32 cRequestedSymbols, /* [out] */ ULONG32 *pcFetchedSymbols, /* [length_is][size_is][out] */ ICorDebugVariableSymbol *pSymbols[ ]); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetMergedAssemblyRecords) - HRESULT ( STDMETHODCALLTYPE *GetMergedAssemblyRecords )( + HRESULT ( STDMETHODCALLTYPE *GetMergedAssemblyRecords )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 cRequestedRecords, /* [out] */ ULONG32 *pcFetchedRecords, /* [length_is][size_is][out] */ ICorDebugMergedAssemblyRecord *pRecords[ ]); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetMethodProps) - HRESULT ( STDMETHODCALLTYPE *GetMethodProps )( + HRESULT ( STDMETHODCALLTYPE *GetMethodProps )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 codeRva, /* [out] */ mdToken *pMethodToken, @@ -2386,41 +2393,41 @@ EXTERN_C const IID IID_ICorDebugSymbolProvider; /* [in] */ ULONG32 cbSignature, /* [out] */ ULONG32 *pcbSignature, /* [length_is][size_is][out] */ BYTE signature[ ]); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetTypeProps) - HRESULT ( STDMETHODCALLTYPE *GetTypeProps )( + HRESULT ( STDMETHODCALLTYPE *GetTypeProps )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 vtableRva, /* [in] */ ULONG32 cbSignature, /* [out] */ ULONG32 *pcbSignature, /* [length_is][size_is][out] */ BYTE signature[ ]); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetCodeRange) - HRESULT ( STDMETHODCALLTYPE *GetCodeRange )( + HRESULT ( STDMETHODCALLTYPE *GetCodeRange )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 codeRva, /* [out] */ ULONG32 *pCodeStartAddress, ULONG32 *pCodeSize); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetAssemblyImageBytes) - HRESULT ( STDMETHODCALLTYPE *GetAssemblyImageBytes )( + HRESULT ( STDMETHODCALLTYPE *GetAssemblyImageBytes )( ICorDebugSymbolProvider * This, /* [in] */ CORDB_ADDRESS rva, /* [in] */ ULONG32 length, /* [out] */ ICorDebugMemoryBuffer **ppMemoryBuffer); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetObjectSize) - HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( + HRESULT ( STDMETHODCALLTYPE *GetObjectSize )( ICorDebugSymbolProvider * This, /* [in] */ ULONG32 cbSignature, /* [size_is][in] */ BYTE typeSig[ ], /* [out] */ ULONG32 *pObjectSize); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider, GetAssemblyImageMetadata) - HRESULT ( STDMETHODCALLTYPE *GetAssemblyImageMetadata )( + HRESULT ( STDMETHODCALLTYPE *GetAssemblyImageMetadata )( ICorDebugSymbolProvider * This, /* [out] */ ICorDebugMemoryBuffer **ppMemoryBuffer); - + END_INTERFACE } ICorDebugSymbolProviderVtbl; @@ -2429,53 +2436,53 @@ EXTERN_C const IID IID_ICorDebugSymbolProvider; CONST_VTBL struct ICorDebugSymbolProviderVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugSymbolProvider_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugSymbolProvider_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugSymbolProvider_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugSymbolProvider_GetStaticFieldSymbols(This,cbSignature,typeSig,cRequestedSymbols,pcFetchedSymbols,pSymbols) \ - ( (This)->lpVtbl -> GetStaticFieldSymbols(This,cbSignature,typeSig,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) + ( (This)->lpVtbl -> GetStaticFieldSymbols(This,cbSignature,typeSig,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) #define ICorDebugSymbolProvider_GetInstanceFieldSymbols(This,cbSignature,typeSig,cRequestedSymbols,pcFetchedSymbols,pSymbols) \ - ( (This)->lpVtbl -> GetInstanceFieldSymbols(This,cbSignature,typeSig,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) + ( (This)->lpVtbl -> GetInstanceFieldSymbols(This,cbSignature,typeSig,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) #define ICorDebugSymbolProvider_GetMethodLocalSymbols(This,nativeRVA,cRequestedSymbols,pcFetchedSymbols,pSymbols) \ - ( (This)->lpVtbl -> GetMethodLocalSymbols(This,nativeRVA,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) + ( (This)->lpVtbl -> GetMethodLocalSymbols(This,nativeRVA,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) #define ICorDebugSymbolProvider_GetMethodParameterSymbols(This,nativeRVA,cRequestedSymbols,pcFetchedSymbols,pSymbols) \ - ( (This)->lpVtbl -> GetMethodParameterSymbols(This,nativeRVA,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) + ( (This)->lpVtbl -> GetMethodParameterSymbols(This,nativeRVA,cRequestedSymbols,pcFetchedSymbols,pSymbols) ) #define ICorDebugSymbolProvider_GetMergedAssemblyRecords(This,cRequestedRecords,pcFetchedRecords,pRecords) \ - ( (This)->lpVtbl -> GetMergedAssemblyRecords(This,cRequestedRecords,pcFetchedRecords,pRecords) ) + ( (This)->lpVtbl -> GetMergedAssemblyRecords(This,cRequestedRecords,pcFetchedRecords,pRecords) ) #define ICorDebugSymbolProvider_GetMethodProps(This,codeRva,pMethodToken,pcGenericParams,cbSignature,pcbSignature,signature) \ - ( (This)->lpVtbl -> GetMethodProps(This,codeRva,pMethodToken,pcGenericParams,cbSignature,pcbSignature,signature) ) + ( (This)->lpVtbl -> GetMethodProps(This,codeRva,pMethodToken,pcGenericParams,cbSignature,pcbSignature,signature) ) #define ICorDebugSymbolProvider_GetTypeProps(This,vtableRva,cbSignature,pcbSignature,signature) \ - ( (This)->lpVtbl -> GetTypeProps(This,vtableRva,cbSignature,pcbSignature,signature) ) + ( (This)->lpVtbl -> GetTypeProps(This,vtableRva,cbSignature,pcbSignature,signature) ) #define ICorDebugSymbolProvider_GetCodeRange(This,codeRva,pCodeStartAddress,pCodeSize) \ - ( (This)->lpVtbl -> GetCodeRange(This,codeRva,pCodeStartAddress,pCodeSize) ) + ( (This)->lpVtbl -> GetCodeRange(This,codeRva,pCodeStartAddress,pCodeSize) ) #define ICorDebugSymbolProvider_GetAssemblyImageBytes(This,rva,length,ppMemoryBuffer) \ - ( (This)->lpVtbl -> GetAssemblyImageBytes(This,rva,length,ppMemoryBuffer) ) + ( (This)->lpVtbl -> GetAssemblyImageBytes(This,rva,length,ppMemoryBuffer) ) #define ICorDebugSymbolProvider_GetObjectSize(This,cbSignature,typeSig,pObjectSize) \ - ( (This)->lpVtbl -> GetObjectSize(This,cbSignature,typeSig,pObjectSize) ) + ( (This)->lpVtbl -> GetObjectSize(This,cbSignature,typeSig,pObjectSize) ) #define ICorDebugSymbolProvider_GetAssemblyImageMetadata(This,ppMemoryBuffer) \ - ( (This)->lpVtbl -> GetAssemblyImageMetadata(This,ppMemoryBuffer) ) + ( (This)->lpVtbl -> GetAssemblyImageMetadata(This,ppMemoryBuffer) ) #endif /* COBJMACROS */ @@ -2492,61 +2499,61 @@ EXTERN_C const IID IID_ICorDebugSymbolProvider; #define __ICorDebugSymbolProvider2_INTERFACE_DEFINED__ /* interface ICorDebugSymbolProvider2 */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugSymbolProvider2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F9801807-4764-4330-9E67-4F685094165E") ICorDebugSymbolProvider2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetGenericDictionaryInfo( + virtual HRESULT STDMETHODCALLTYPE GetGenericDictionaryInfo( /* [out] */ ICorDebugMemoryBuffer **ppMemoryBuffer) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFrameProps( + + virtual HRESULT STDMETHODCALLTYPE GetFrameProps( /* [in] */ ULONG32 codeRva, /* [out] */ ULONG32 *pCodeStartRva, /* [out] */ ULONG32 *pParentFrameStartRva) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugSymbolProvider2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugSymbolProvider2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugSymbolProvider2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugSymbolProvider2 * This); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider2, GetGenericDictionaryInfo) - HRESULT ( STDMETHODCALLTYPE *GetGenericDictionaryInfo )( + HRESULT ( STDMETHODCALLTYPE *GetGenericDictionaryInfo )( ICorDebugSymbolProvider2 * This, /* [out] */ ICorDebugMemoryBuffer **ppMemoryBuffer); - + DECLSPEC_XFGVIRT(ICorDebugSymbolProvider2, GetFrameProps) - HRESULT ( STDMETHODCALLTYPE *GetFrameProps )( + HRESULT ( STDMETHODCALLTYPE *GetFrameProps )( ICorDebugSymbolProvider2 * This, /* [in] */ ULONG32 codeRva, /* [out] */ ULONG32 *pCodeStartRva, /* [out] */ ULONG32 *pParentFrameStartRva); - + END_INTERFACE } ICorDebugSymbolProvider2Vtbl; @@ -2555,26 +2562,26 @@ EXTERN_C const IID IID_ICorDebugSymbolProvider2; CONST_VTBL struct ICorDebugSymbolProvider2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugSymbolProvider2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugSymbolProvider2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugSymbolProvider2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugSymbolProvider2_GetGenericDictionaryInfo(This,ppMemoryBuffer) \ - ( (This)->lpVtbl -> GetGenericDictionaryInfo(This,ppMemoryBuffer) ) + ( (This)->lpVtbl -> GetGenericDictionaryInfo(This,ppMemoryBuffer) ) #define ICorDebugSymbolProvider2_GetFrameProps(This,codeRva,pCodeStartRva,pParentFrameStartRva) \ - ( (This)->lpVtbl -> GetFrameProps(This,codeRva,pCodeStartRva,pParentFrameStartRva) ) + ( (This)->lpVtbl -> GetFrameProps(This,codeRva,pCodeStartRva,pParentFrameStartRva) ) #endif /* COBJMACROS */ @@ -2591,61 +2598,61 @@ EXTERN_C const IID IID_ICorDebugSymbolProvider2; #define __ICorDebugVirtualUnwinder_INTERFACE_DEFINED__ /* interface ICorDebugVirtualUnwinder */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugVirtualUnwinder; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F69126B7-C787-4F6B-AE96-A569786FC670") ICorDebugVirtualUnwinder : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetContext( + virtual HRESULT STDMETHODCALLTYPE GetContext( /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 cbContextBuf, /* [out] */ ULONG32 *contextSize, /* [size_is][out] */ BYTE contextBuf[ ]) = 0; - + virtual HRESULT STDMETHODCALLTYPE Next( void) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugVirtualUnwinderVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugVirtualUnwinder * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugVirtualUnwinder * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugVirtualUnwinder * This); - + DECLSPEC_XFGVIRT(ICorDebugVirtualUnwinder, GetContext) - HRESULT ( STDMETHODCALLTYPE *GetContext )( + HRESULT ( STDMETHODCALLTYPE *GetContext )( ICorDebugVirtualUnwinder * This, /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 cbContextBuf, /* [out] */ ULONG32 *contextSize, /* [size_is][out] */ BYTE contextBuf[ ]); - + DECLSPEC_XFGVIRT(ICorDebugVirtualUnwinder, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugVirtualUnwinder * This); - + END_INTERFACE } ICorDebugVirtualUnwinderVtbl; @@ -2654,26 +2661,26 @@ EXTERN_C const IID IID_ICorDebugVirtualUnwinder; CONST_VTBL struct ICorDebugVirtualUnwinderVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugVirtualUnwinder_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugVirtualUnwinder_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugVirtualUnwinder_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugVirtualUnwinder_GetContext(This,contextFlags,cbContextBuf,contextSize,contextBuf) \ - ( (This)->lpVtbl -> GetContext(This,contextFlags,cbContextBuf,contextSize,contextBuf) ) + ( (This)->lpVtbl -> GetContext(This,contextFlags,cbContextBuf,contextSize,contextBuf) ) #define ICorDebugVirtualUnwinder_Next(This) \ - ( (This)->lpVtbl -> Next(This) ) + ( (This)->lpVtbl -> Next(This) ) #endif /* COBJMACROS */ @@ -2690,105 +2697,105 @@ EXTERN_C const IID IID_ICorDebugVirtualUnwinder; #define __ICorDebugDataTarget2_INTERFACE_DEFINED__ /* interface ICorDebugDataTarget2 */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugDataTarget2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("2eb364da-605b-4e8d-b333-3394c4828d41") ICorDebugDataTarget2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetImageFromPointer( + virtual HRESULT STDMETHODCALLTYPE GetImageFromPointer( /* [in] */ CORDB_ADDRESS addr, /* [out] */ CORDB_ADDRESS *pImageBase, /* [out] */ ULONG32 *pSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetImageLocation( + + virtual HRESULT STDMETHODCALLTYPE GetImageLocation( /* [in] */ CORDB_ADDRESS baseAddress, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSymbolProviderForImage( + + virtual HRESULT STDMETHODCALLTYPE GetSymbolProviderForImage( /* [in] */ CORDB_ADDRESS imageBaseAddress, /* [out] */ ICorDebugSymbolProvider **ppSymProvider) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateThreadIDs( + + virtual HRESULT STDMETHODCALLTYPE EnumerateThreadIDs( /* [in] */ ULONG32 cThreadIds, /* [out] */ ULONG32 *pcThreadIds, /* [length_is][size_is][out] */ ULONG32 pThreadIds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateVirtualUnwinder( + + virtual HRESULT STDMETHODCALLTYPE CreateVirtualUnwinder( /* [in] */ DWORD nativeThreadID, /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 cbContext, /* [size_is][in] */ BYTE initialContext[ ], /* [out] */ ICorDebugVirtualUnwinder **ppUnwinder) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugDataTarget2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugDataTarget2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugDataTarget2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugDataTarget2 * This); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget2, GetImageFromPointer) - HRESULT ( STDMETHODCALLTYPE *GetImageFromPointer )( + HRESULT ( STDMETHODCALLTYPE *GetImageFromPointer )( ICorDebugDataTarget2 * This, /* [in] */ CORDB_ADDRESS addr, /* [out] */ CORDB_ADDRESS *pImageBase, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget2, GetImageLocation) - HRESULT ( STDMETHODCALLTYPE *GetImageLocation )( + HRESULT ( STDMETHODCALLTYPE *GetImageLocation )( ICorDebugDataTarget2 * This, /* [in] */ CORDB_ADDRESS baseAddress, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget2, GetSymbolProviderForImage) - HRESULT ( STDMETHODCALLTYPE *GetSymbolProviderForImage )( + HRESULT ( STDMETHODCALLTYPE *GetSymbolProviderForImage )( ICorDebugDataTarget2 * This, /* [in] */ CORDB_ADDRESS imageBaseAddress, /* [out] */ ICorDebugSymbolProvider **ppSymProvider); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget2, EnumerateThreadIDs) - HRESULT ( STDMETHODCALLTYPE *EnumerateThreadIDs )( + HRESULT ( STDMETHODCALLTYPE *EnumerateThreadIDs )( ICorDebugDataTarget2 * This, /* [in] */ ULONG32 cThreadIds, /* [out] */ ULONG32 *pcThreadIds, /* [length_is][size_is][out] */ ULONG32 pThreadIds[ ]); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget2, CreateVirtualUnwinder) - HRESULT ( STDMETHODCALLTYPE *CreateVirtualUnwinder )( + HRESULT ( STDMETHODCALLTYPE *CreateVirtualUnwinder )( ICorDebugDataTarget2 * This, /* [in] */ DWORD nativeThreadID, /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 cbContext, /* [size_is][in] */ BYTE initialContext[ ], /* [out] */ ICorDebugVirtualUnwinder **ppUnwinder); - + END_INTERFACE } ICorDebugDataTarget2Vtbl; @@ -2797,35 +2804,35 @@ EXTERN_C const IID IID_ICorDebugDataTarget2; CONST_VTBL struct ICorDebugDataTarget2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugDataTarget2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugDataTarget2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugDataTarget2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugDataTarget2_GetImageFromPointer(This,addr,pImageBase,pSize) \ - ( (This)->lpVtbl -> GetImageFromPointer(This,addr,pImageBase,pSize) ) + ( (This)->lpVtbl -> GetImageFromPointer(This,addr,pImageBase,pSize) ) #define ICorDebugDataTarget2_GetImageLocation(This,baseAddress,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetImageLocation(This,baseAddress,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetImageLocation(This,baseAddress,cchName,pcchName,szName) ) #define ICorDebugDataTarget2_GetSymbolProviderForImage(This,imageBaseAddress,ppSymProvider) \ - ( (This)->lpVtbl -> GetSymbolProviderForImage(This,imageBaseAddress,ppSymProvider) ) + ( (This)->lpVtbl -> GetSymbolProviderForImage(This,imageBaseAddress,ppSymProvider) ) #define ICorDebugDataTarget2_EnumerateThreadIDs(This,cThreadIds,pcThreadIds,pThreadIds) \ - ( (This)->lpVtbl -> EnumerateThreadIDs(This,cThreadIds,pcThreadIds,pThreadIds) ) + ( (This)->lpVtbl -> EnumerateThreadIDs(This,cThreadIds,pcThreadIds,pThreadIds) ) #define ICorDebugDataTarget2_CreateVirtualUnwinder(This,nativeThreadID,contextFlags,cbContext,initialContext,ppUnwinder) \ - ( (This)->lpVtbl -> CreateVirtualUnwinder(This,nativeThreadID,contextFlags,cbContext,initialContext,ppUnwinder) ) + ( (This)->lpVtbl -> CreateVirtualUnwinder(This,nativeThreadID,contextFlags,cbContext,initialContext,ppUnwinder) ) #endif /* COBJMACROS */ @@ -2842,69 +2849,69 @@ EXTERN_C const IID IID_ICorDebugDataTarget2; #define __ICorDebugLoadedModule_INTERFACE_DEFINED__ /* interface ICorDebugLoadedModule */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugLoadedModule; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("817F343A-6630-4578-96C5-D11BC0EC5EE2") ICorDebugLoadedModule : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetBaseAddress( + virtual HRESULT STDMETHODCALLTYPE GetBaseAddress( /* [out] */ CORDB_ADDRESS *pAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetName( + + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pcBytes) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugLoadedModuleVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugLoadedModule * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugLoadedModule * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugLoadedModule * This); - + DECLSPEC_XFGVIRT(ICorDebugLoadedModule, GetBaseAddress) - HRESULT ( STDMETHODCALLTYPE *GetBaseAddress )( + HRESULT ( STDMETHODCALLTYPE *GetBaseAddress )( ICorDebugLoadedModule * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugLoadedModule, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugLoadedModule * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugLoadedModule, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugLoadedModule * This, /* [out] */ ULONG32 *pcBytes); - + END_INTERFACE } ICorDebugLoadedModuleVtbl; @@ -2913,29 +2920,29 @@ EXTERN_C const IID IID_ICorDebugLoadedModule; CONST_VTBL struct ICorDebugLoadedModuleVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugLoadedModule_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugLoadedModule_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugLoadedModule_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugLoadedModule_GetBaseAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetBaseAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetBaseAddress(This,pAddress) ) #define ICorDebugLoadedModule_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #define ICorDebugLoadedModule_GetSize(This,pcBytes) \ - ( (This)->lpVtbl -> GetSize(This,pcBytes) ) + ( (This)->lpVtbl -> GetSize(This,pcBytes) ) #endif /* COBJMACROS */ @@ -2952,53 +2959,53 @@ EXTERN_C const IID IID_ICorDebugLoadedModule; #define __ICorDebugDataTarget3_INTERFACE_DEFINED__ /* interface ICorDebugDataTarget3 */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugDataTarget3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("D05E60C3-848C-4E7D-894E-623320FF6AFA") ICorDebugDataTarget3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetLoadedModules( + virtual HRESULT STDMETHODCALLTYPE GetLoadedModules( /* [in] */ ULONG32 cRequestedModules, /* [out] */ ULONG32 *pcFetchedModules, /* [length_is][size_is][out] */ ICorDebugLoadedModule *pLoadedModules[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugDataTarget3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugDataTarget3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugDataTarget3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugDataTarget3 * This); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget3, GetLoadedModules) - HRESULT ( STDMETHODCALLTYPE *GetLoadedModules )( + HRESULT ( STDMETHODCALLTYPE *GetLoadedModules )( ICorDebugDataTarget3 * This, /* [in] */ ULONG32 cRequestedModules, /* [out] */ ULONG32 *pcFetchedModules, /* [length_is][size_is][out] */ ICorDebugLoadedModule *pLoadedModules[ ]); - + END_INTERFACE } ICorDebugDataTarget3Vtbl; @@ -3007,23 +3014,23 @@ EXTERN_C const IID IID_ICorDebugDataTarget3; CONST_VTBL struct ICorDebugDataTarget3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugDataTarget3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugDataTarget3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugDataTarget3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugDataTarget3_GetLoadedModules(This,cRequestedModules,pcFetchedModules,pLoadedModules) \ - ( (This)->lpVtbl -> GetLoadedModules(This,cRequestedModules,pcFetchedModules,pLoadedModules) ) + ( (This)->lpVtbl -> GetLoadedModules(This,cRequestedModules,pcFetchedModules,pLoadedModules) ) #endif /* COBJMACROS */ @@ -3040,53 +3047,53 @@ EXTERN_C const IID IID_ICorDebugDataTarget3; #define __ICorDebugDataTarget4_INTERFACE_DEFINED__ /* interface ICorDebugDataTarget4 */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugDataTarget4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("E799DC06-E099-4713-BDD9-906D3CC02CF2") ICorDebugDataTarget4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE VirtualUnwind( + virtual HRESULT STDMETHODCALLTYPE VirtualUnwind( /* [in] */ DWORD threadId, /* [in] */ ULONG32 contextSize, /* [size_is][out][in] */ BYTE *context) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugDataTarget4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugDataTarget4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugDataTarget4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugDataTarget4 * This); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget4, VirtualUnwind) - HRESULT ( STDMETHODCALLTYPE *VirtualUnwind )( + HRESULT ( STDMETHODCALLTYPE *VirtualUnwind )( ICorDebugDataTarget4 * This, /* [in] */ DWORD threadId, /* [in] */ ULONG32 contextSize, /* [size_is][out][in] */ BYTE *context); - + END_INTERFACE } ICorDebugDataTarget4Vtbl; @@ -3095,23 +3102,23 @@ EXTERN_C const IID IID_ICorDebugDataTarget4; CONST_VTBL struct ICorDebugDataTarget4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugDataTarget4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugDataTarget4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugDataTarget4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugDataTarget4_VirtualUnwind(This,threadId,contextSize,context) \ - ( (This)->lpVtbl -> VirtualUnwind(This,threadId,contextSize,context) ) + ( (This)->lpVtbl -> VirtualUnwind(This,threadId,contextSize,context) ) #endif /* COBJMACROS */ @@ -3128,96 +3135,96 @@ EXTERN_C const IID IID_ICorDebugDataTarget4; #define __ICorDebugMutableDataTarget_INTERFACE_DEFINED__ /* interface ICorDebugMutableDataTarget */ -/* [unique][local][uuid][object] */ +/* [unique][local][uuid][object] */ EXTERN_C const IID IID_ICorDebugMutableDataTarget; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("A1B8A756-3CB6-4CCB-979F-3DF999673A59") ICorDebugMutableDataTarget : public ICorDebugDataTarget { public: - virtual HRESULT STDMETHODCALLTYPE WriteVirtual( + virtual HRESULT STDMETHODCALLTYPE WriteVirtual( /* [in] */ CORDB_ADDRESS address, /* [size_is][in] */ const BYTE *pBuffer, /* [in] */ ULONG32 bytesRequested) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetThreadContext( + + virtual HRESULT STDMETHODCALLTYPE SetThreadContext( /* [in] */ DWORD dwThreadID, /* [in] */ ULONG32 contextSize, /* [size_is][in] */ const BYTE *pContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE ContinueStatusChanged( + + virtual HRESULT STDMETHODCALLTYPE ContinueStatusChanged( /* [in] */ DWORD dwThreadId, /* [in] */ CORDB_CONTINUE_STATUS continueStatus) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugMutableDataTargetVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugMutableDataTarget * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugMutableDataTarget * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugMutableDataTarget * This); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget, GetPlatform) - HRESULT ( STDMETHODCALLTYPE *GetPlatform )( + HRESULT ( STDMETHODCALLTYPE *GetPlatform )( ICorDebugMutableDataTarget * This, /* [out] */ CorDebugPlatform *pTargetPlatform); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget, ReadVirtual) - HRESULT ( STDMETHODCALLTYPE *ReadVirtual )( + HRESULT ( STDMETHODCALLTYPE *ReadVirtual )( ICorDebugMutableDataTarget * This, /* [in] */ CORDB_ADDRESS address, /* [length_is][size_is][out] */ BYTE *pBuffer, /* [in] */ ULONG32 bytesRequested, /* [out] */ ULONG32 *pBytesRead); - + DECLSPEC_XFGVIRT(ICorDebugDataTarget, GetThreadContext) - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorDebugMutableDataTarget * This, /* [in] */ DWORD dwThreadID, /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 contextSize, /* [size_is][out] */ BYTE *pContext); - + DECLSPEC_XFGVIRT(ICorDebugMutableDataTarget, WriteVirtual) - HRESULT ( STDMETHODCALLTYPE *WriteVirtual )( + HRESULT ( STDMETHODCALLTYPE *WriteVirtual )( ICorDebugMutableDataTarget * This, /* [in] */ CORDB_ADDRESS address, /* [size_is][in] */ const BYTE *pBuffer, /* [in] */ ULONG32 bytesRequested); - + DECLSPEC_XFGVIRT(ICorDebugMutableDataTarget, SetThreadContext) - HRESULT ( STDMETHODCALLTYPE *SetThreadContext )( + HRESULT ( STDMETHODCALLTYPE *SetThreadContext )( ICorDebugMutableDataTarget * This, /* [in] */ DWORD dwThreadID, /* [in] */ ULONG32 contextSize, /* [size_is][in] */ const BYTE *pContext); - + DECLSPEC_XFGVIRT(ICorDebugMutableDataTarget, ContinueStatusChanged) - HRESULT ( STDMETHODCALLTYPE *ContinueStatusChanged )( + HRESULT ( STDMETHODCALLTYPE *ContinueStatusChanged )( ICorDebugMutableDataTarget * This, /* [in] */ DWORD dwThreadId, /* [in] */ CORDB_CONTINUE_STATUS continueStatus); - + END_INTERFACE } ICorDebugMutableDataTargetVtbl; @@ -3226,39 +3233,39 @@ EXTERN_C const IID IID_ICorDebugMutableDataTarget; CONST_VTBL struct ICorDebugMutableDataTargetVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugMutableDataTarget_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugMutableDataTarget_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugMutableDataTarget_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugMutableDataTarget_GetPlatform(This,pTargetPlatform) \ - ( (This)->lpVtbl -> GetPlatform(This,pTargetPlatform) ) + ( (This)->lpVtbl -> GetPlatform(This,pTargetPlatform) ) #define ICorDebugMutableDataTarget_ReadVirtual(This,address,pBuffer,bytesRequested,pBytesRead) \ - ( (This)->lpVtbl -> ReadVirtual(This,address,pBuffer,bytesRequested,pBytesRead) ) + ( (This)->lpVtbl -> ReadVirtual(This,address,pBuffer,bytesRequested,pBytesRead) ) #define ICorDebugMutableDataTarget_GetThreadContext(This,dwThreadID,contextFlags,contextSize,pContext) \ - ( (This)->lpVtbl -> GetThreadContext(This,dwThreadID,contextFlags,contextSize,pContext) ) + ( (This)->lpVtbl -> GetThreadContext(This,dwThreadID,contextFlags,contextSize,pContext) ) #define ICorDebugMutableDataTarget_WriteVirtual(This,address,pBuffer,bytesRequested) \ - ( (This)->lpVtbl -> WriteVirtual(This,address,pBuffer,bytesRequested) ) + ( (This)->lpVtbl -> WriteVirtual(This,address,pBuffer,bytesRequested) ) #define ICorDebugMutableDataTarget_SetThreadContext(This,dwThreadID,contextSize,pContext) \ - ( (This)->lpVtbl -> SetThreadContext(This,dwThreadID,contextSize,pContext) ) + ( (This)->lpVtbl -> SetThreadContext(This,dwThreadID,contextSize,pContext) ) #define ICorDebugMutableDataTarget_ContinueStatusChanged(This,dwThreadId,continueStatus) \ - ( (This)->lpVtbl -> ContinueStatusChanged(This,dwThreadId,continueStatus) ) + ( (This)->lpVtbl -> ContinueStatusChanged(This,dwThreadId,continueStatus) ) #endif /* COBJMACROS */ @@ -3275,63 +3282,63 @@ EXTERN_C const IID IID_ICorDebugMutableDataTarget; #define __ICorDebugMetaDataLocator_INTERFACE_DEFINED__ /* interface ICorDebugMetaDataLocator */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugMetaDataLocator; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("7cef8ba9-2ef7-42bf-973f-4171474f87d9") ICorDebugMetaDataLocator : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetMetaData( + virtual HRESULT STDMETHODCALLTYPE GetMetaData( /* [in] */ LPCWSTR wszImagePath, /* [in] */ DWORD dwImageTimeStamp, /* [in] */ DWORD dwImageSize, /* [in] */ ULONG32 cchPathBuffer, - /* [annotation][out] */ + /* [annotation][out] */ _Out_ ULONG32 *pcchPathBuffer, - /* [annotation][length_is][size_is][out] */ + /* [annotation][length_is][size_is][out] */ _Out_writes_to_(cchPathBuffer, *pcchPathBuffer) WCHAR wszPathBuffer[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugMetaDataLocatorVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugMetaDataLocator * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugMetaDataLocator * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugMetaDataLocator * This); - + DECLSPEC_XFGVIRT(ICorDebugMetaDataLocator, GetMetaData) - HRESULT ( STDMETHODCALLTYPE *GetMetaData )( + HRESULT ( STDMETHODCALLTYPE *GetMetaData )( ICorDebugMetaDataLocator * This, /* [in] */ LPCWSTR wszImagePath, /* [in] */ DWORD dwImageTimeStamp, /* [in] */ DWORD dwImageSize, /* [in] */ ULONG32 cchPathBuffer, - /* [annotation][out] */ + /* [annotation][out] */ _Out_ ULONG32 *pcchPathBuffer, - /* [annotation][length_is][size_is][out] */ + /* [annotation][length_is][size_is][out] */ _Out_writes_to_(cchPathBuffer, *pcchPathBuffer) WCHAR wszPathBuffer[ ]); - + END_INTERFACE } ICorDebugMetaDataLocatorVtbl; @@ -3340,23 +3347,23 @@ EXTERN_C const IID IID_ICorDebugMetaDataLocator; CONST_VTBL struct ICorDebugMetaDataLocatorVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugMetaDataLocator_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugMetaDataLocator_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugMetaDataLocator_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugMetaDataLocator_GetMetaData(This,wszImagePath,dwImageTimeStamp,dwImageSize,cchPathBuffer,pcchPathBuffer,wszPathBuffer) \ - ( (This)->lpVtbl -> GetMetaData(This,wszImagePath,dwImageTimeStamp,dwImageSize,cchPathBuffer,pcchPathBuffer,wszPathBuffer) ) + ( (This)->lpVtbl -> GetMetaData(This,wszImagePath,dwImageTimeStamp,dwImageSize,cchPathBuffer,pcchPathBuffer,wszPathBuffer) ) #endif /* COBJMACROS */ @@ -3370,10 +3377,10 @@ EXTERN_C const IID IID_ICorDebugMetaDataLocator; /* interface __MIDL_itf_cordebug_0000_0015 */ -/* [local] */ +/* [local] */ #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0015_v0_0_c_ifspec; @@ -3383,9 +3390,9 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0015_v0_0_s_ifspec; #define __ICorDebugManagedCallback_INTERFACE_DEFINED__ /* interface ICorDebugManagedCallback */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugStepReason { STEP_NORMAL = 0, @@ -3394,10 +3401,10 @@ enum CorDebugStepReason STEP_EXCEPTION_FILTER = ( STEP_CALL + 1 ) , STEP_EXCEPTION_HANDLER = ( STEP_EXCEPTION_FILTER + 1 ) , STEP_INTERCEPT = ( STEP_EXCEPTION_HANDLER + 1 ) , - STEP_EXIT = ( STEP_INTERCEPT + 1 ) + STEP_EXIT = ( STEP_INTERCEPT + 1 ) } CorDebugStepReason; -typedef +typedef enum LoggingLevelEnum { LTraceLevel0 = 0, @@ -3415,273 +3422,273 @@ enum LoggingLevelEnum LPanicLevel = 100 } LoggingLevelEnum; -typedef +typedef enum LogSwitchCallReason { SWITCH_CREATE = 0, SWITCH_MODIFY = ( SWITCH_CREATE + 1 ) , - SWITCH_DELETE = ( SWITCH_MODIFY + 1 ) + SWITCH_DELETE = ( SWITCH_MODIFY + 1 ) } LogSwitchCallReason; EXTERN_C const IID IID_ICorDebugManagedCallback; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("3d6f5f60-7538-11d3-8d5b-00104b35e7ef") ICorDebugManagedCallback : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Breakpoint( + virtual HRESULT STDMETHODCALLTYPE Breakpoint( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugBreakpoint *pBreakpoint) = 0; - - virtual HRESULT STDMETHODCALLTYPE StepComplete( + + virtual HRESULT STDMETHODCALLTYPE StepComplete( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugStepper *pStepper, /* [in] */ CorDebugStepReason reason) = 0; - - virtual HRESULT STDMETHODCALLTYPE Break( + + virtual HRESULT STDMETHODCALLTYPE Break( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *thread) = 0; - - virtual HRESULT STDMETHODCALLTYPE Exception( + + virtual HRESULT STDMETHODCALLTYPE Exception( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ BOOL unhandled) = 0; - - virtual HRESULT STDMETHODCALLTYPE EvalComplete( + + virtual HRESULT STDMETHODCALLTYPE EvalComplete( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugEval *pEval) = 0; - - virtual HRESULT STDMETHODCALLTYPE EvalException( + + virtual HRESULT STDMETHODCALLTYPE EvalException( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugEval *pEval) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateProcess( + + virtual HRESULT STDMETHODCALLTYPE CreateProcess( /* [in] */ ICorDebugProcess *pProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExitProcess( + + virtual HRESULT STDMETHODCALLTYPE ExitProcess( /* [in] */ ICorDebugProcess *pProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateThread( + + virtual HRESULT STDMETHODCALLTYPE CreateThread( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *thread) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExitThread( + + virtual HRESULT STDMETHODCALLTYPE ExitThread( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *thread) = 0; - - virtual HRESULT STDMETHODCALLTYPE LoadModule( + + virtual HRESULT STDMETHODCALLTYPE LoadModule( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugModule *pModule) = 0; - - virtual HRESULT STDMETHODCALLTYPE UnloadModule( + + virtual HRESULT STDMETHODCALLTYPE UnloadModule( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugModule *pModule) = 0; - - virtual HRESULT STDMETHODCALLTYPE LoadClass( + + virtual HRESULT STDMETHODCALLTYPE LoadClass( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugClass *c) = 0; - - virtual HRESULT STDMETHODCALLTYPE UnloadClass( + + virtual HRESULT STDMETHODCALLTYPE UnloadClass( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugClass *c) = 0; - - virtual HRESULT STDMETHODCALLTYPE DebuggerError( + + virtual HRESULT STDMETHODCALLTYPE DebuggerError( /* [in] */ ICorDebugProcess *pProcess, /* [in] */ HRESULT errorHR, /* [in] */ DWORD errorCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE LogMessage( + + virtual HRESULT STDMETHODCALLTYPE LogMessage( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ LONG lLevel, /* [in] */ WCHAR *pLogSwitchName, /* [in] */ WCHAR *pMessage) = 0; - - virtual HRESULT STDMETHODCALLTYPE LogSwitch( + + virtual HRESULT STDMETHODCALLTYPE LogSwitch( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ LONG lLevel, /* [in] */ ULONG ulReason, /* [in] */ WCHAR *pLogSwitchName, /* [in] */ WCHAR *pParentName) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateAppDomain( + + virtual HRESULT STDMETHODCALLTYPE CreateAppDomain( /* [in] */ ICorDebugProcess *pProcess, /* [in] */ ICorDebugAppDomain *pAppDomain) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExitAppDomain( + + virtual HRESULT STDMETHODCALLTYPE ExitAppDomain( /* [in] */ ICorDebugProcess *pProcess, /* [in] */ ICorDebugAppDomain *pAppDomain) = 0; - - virtual HRESULT STDMETHODCALLTYPE LoadAssembly( + + virtual HRESULT STDMETHODCALLTYPE LoadAssembly( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugAssembly *pAssembly) = 0; - - virtual HRESULT STDMETHODCALLTYPE UnloadAssembly( + + virtual HRESULT STDMETHODCALLTYPE UnloadAssembly( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugAssembly *pAssembly) = 0; - - virtual HRESULT STDMETHODCALLTYPE ControlCTrap( + + virtual HRESULT STDMETHODCALLTYPE ControlCTrap( /* [in] */ ICorDebugProcess *pProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE NameChange( + + virtual HRESULT STDMETHODCALLTYPE NameChange( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread) = 0; - - virtual HRESULT STDMETHODCALLTYPE UpdateModuleSymbols( + + virtual HRESULT STDMETHODCALLTYPE UpdateModuleSymbols( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugModule *pModule, /* [in] */ IStream *pSymbolStream) = 0; - - virtual HRESULT STDMETHODCALLTYPE EditAndContinueRemap( + + virtual HRESULT STDMETHODCALLTYPE EditAndContinueRemap( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugFunction *pFunction, /* [in] */ BOOL fAccurate) = 0; - - virtual HRESULT STDMETHODCALLTYPE BreakpointSetError( + + virtual HRESULT STDMETHODCALLTYPE BreakpointSetError( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugBreakpoint *pBreakpoint, /* [in] */ DWORD dwError) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugManagedCallbackVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugManagedCallback * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugManagedCallback * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugManagedCallback * This); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, Breakpoint) - HRESULT ( STDMETHODCALLTYPE *Breakpoint )( + HRESULT ( STDMETHODCALLTYPE *Breakpoint )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugBreakpoint *pBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, StepComplete) - HRESULT ( STDMETHODCALLTYPE *StepComplete )( + HRESULT ( STDMETHODCALLTYPE *StepComplete )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugStepper *pStepper, /* [in] */ CorDebugStepReason reason); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, Break) - HRESULT ( STDMETHODCALLTYPE *Break )( + HRESULT ( STDMETHODCALLTYPE *Break )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *thread); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, Exception) - HRESULT ( STDMETHODCALLTYPE *Exception )( + HRESULT ( STDMETHODCALLTYPE *Exception )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ BOOL unhandled); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, EvalComplete) - HRESULT ( STDMETHODCALLTYPE *EvalComplete )( + HRESULT ( STDMETHODCALLTYPE *EvalComplete )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugEval *pEval); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, EvalException) - HRESULT ( STDMETHODCALLTYPE *EvalException )( + HRESULT ( STDMETHODCALLTYPE *EvalException )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugEval *pEval); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, CreateProcess) - HRESULT ( STDMETHODCALLTYPE *CreateProcess )( + HRESULT ( STDMETHODCALLTYPE *CreateProcess )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugProcess *pProcess); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, ExitProcess) - HRESULT ( STDMETHODCALLTYPE *ExitProcess )( + HRESULT ( STDMETHODCALLTYPE *ExitProcess )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugProcess *pProcess); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, CreateThread) - HRESULT ( STDMETHODCALLTYPE *CreateThread )( + HRESULT ( STDMETHODCALLTYPE *CreateThread )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *thread); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, ExitThread) - HRESULT ( STDMETHODCALLTYPE *ExitThread )( + HRESULT ( STDMETHODCALLTYPE *ExitThread )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *thread); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, LoadModule) - HRESULT ( STDMETHODCALLTYPE *LoadModule )( + HRESULT ( STDMETHODCALLTYPE *LoadModule )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugModule *pModule); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, UnloadModule) - HRESULT ( STDMETHODCALLTYPE *UnloadModule )( + HRESULT ( STDMETHODCALLTYPE *UnloadModule )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugModule *pModule); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, LoadClass) - HRESULT ( STDMETHODCALLTYPE *LoadClass )( + HRESULT ( STDMETHODCALLTYPE *LoadClass )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugClass *c); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, UnloadClass) - HRESULT ( STDMETHODCALLTYPE *UnloadClass )( + HRESULT ( STDMETHODCALLTYPE *UnloadClass )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugClass *c); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, DebuggerError) - HRESULT ( STDMETHODCALLTYPE *DebuggerError )( + HRESULT ( STDMETHODCALLTYPE *DebuggerError )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugProcess *pProcess, /* [in] */ HRESULT errorHR, /* [in] */ DWORD errorCode); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, LogMessage) - HRESULT ( STDMETHODCALLTYPE *LogMessage )( + HRESULT ( STDMETHODCALLTYPE *LogMessage )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ LONG lLevel, /* [in] */ WCHAR *pLogSwitchName, /* [in] */ WCHAR *pMessage); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, LogSwitch) - HRESULT ( STDMETHODCALLTYPE *LogSwitch )( + HRESULT ( STDMETHODCALLTYPE *LogSwitch )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, @@ -3689,65 +3696,65 @@ EXTERN_C const IID IID_ICorDebugManagedCallback; /* [in] */ ULONG ulReason, /* [in] */ WCHAR *pLogSwitchName, /* [in] */ WCHAR *pParentName); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, CreateAppDomain) - HRESULT ( STDMETHODCALLTYPE *CreateAppDomain )( + HRESULT ( STDMETHODCALLTYPE *CreateAppDomain )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugProcess *pProcess, /* [in] */ ICorDebugAppDomain *pAppDomain); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, ExitAppDomain) - HRESULT ( STDMETHODCALLTYPE *ExitAppDomain )( + HRESULT ( STDMETHODCALLTYPE *ExitAppDomain )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugProcess *pProcess, /* [in] */ ICorDebugAppDomain *pAppDomain); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, LoadAssembly) - HRESULT ( STDMETHODCALLTYPE *LoadAssembly )( + HRESULT ( STDMETHODCALLTYPE *LoadAssembly )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugAssembly *pAssembly); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, UnloadAssembly) - HRESULT ( STDMETHODCALLTYPE *UnloadAssembly )( + HRESULT ( STDMETHODCALLTYPE *UnloadAssembly )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugAssembly *pAssembly); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, ControlCTrap) - HRESULT ( STDMETHODCALLTYPE *ControlCTrap )( + HRESULT ( STDMETHODCALLTYPE *ControlCTrap )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugProcess *pProcess); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, NameChange) - HRESULT ( STDMETHODCALLTYPE *NameChange )( + HRESULT ( STDMETHODCALLTYPE *NameChange )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, UpdateModuleSymbols) - HRESULT ( STDMETHODCALLTYPE *UpdateModuleSymbols )( + HRESULT ( STDMETHODCALLTYPE *UpdateModuleSymbols )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugModule *pModule, /* [in] */ IStream *pSymbolStream); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, EditAndContinueRemap) - HRESULT ( STDMETHODCALLTYPE *EditAndContinueRemap )( + HRESULT ( STDMETHODCALLTYPE *EditAndContinueRemap )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugFunction *pFunction, /* [in] */ BOOL fAccurate); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback, BreakpointSetError) - HRESULT ( STDMETHODCALLTYPE *BreakpointSetError )( + HRESULT ( STDMETHODCALLTYPE *BreakpointSetError )( ICorDebugManagedCallback * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugBreakpoint *pBreakpoint, /* [in] */ DWORD dwError); - + END_INTERFACE } ICorDebugManagedCallbackVtbl; @@ -3756,98 +3763,98 @@ EXTERN_C const IID IID_ICorDebugManagedCallback; CONST_VTBL struct ICorDebugManagedCallbackVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugManagedCallback_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugManagedCallback_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugManagedCallback_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugManagedCallback_Breakpoint(This,pAppDomain,pThread,pBreakpoint) \ - ( (This)->lpVtbl -> Breakpoint(This,pAppDomain,pThread,pBreakpoint) ) + ( (This)->lpVtbl -> Breakpoint(This,pAppDomain,pThread,pBreakpoint) ) #define ICorDebugManagedCallback_StepComplete(This,pAppDomain,pThread,pStepper,reason) \ - ( (This)->lpVtbl -> StepComplete(This,pAppDomain,pThread,pStepper,reason) ) + ( (This)->lpVtbl -> StepComplete(This,pAppDomain,pThread,pStepper,reason) ) #define ICorDebugManagedCallback_Break(This,pAppDomain,thread) \ - ( (This)->lpVtbl -> Break(This,pAppDomain,thread) ) + ( (This)->lpVtbl -> Break(This,pAppDomain,thread) ) #define ICorDebugManagedCallback_Exception(This,pAppDomain,pThread,unhandled) \ - ( (This)->lpVtbl -> Exception(This,pAppDomain,pThread,unhandled) ) + ( (This)->lpVtbl -> Exception(This,pAppDomain,pThread,unhandled) ) #define ICorDebugManagedCallback_EvalComplete(This,pAppDomain,pThread,pEval) \ - ( (This)->lpVtbl -> EvalComplete(This,pAppDomain,pThread,pEval) ) + ( (This)->lpVtbl -> EvalComplete(This,pAppDomain,pThread,pEval) ) #define ICorDebugManagedCallback_EvalException(This,pAppDomain,pThread,pEval) \ - ( (This)->lpVtbl -> EvalException(This,pAppDomain,pThread,pEval) ) + ( (This)->lpVtbl -> EvalException(This,pAppDomain,pThread,pEval) ) #define ICorDebugManagedCallback_CreateProcess(This,pProcess) \ - ( (This)->lpVtbl -> CreateProcess(This,pProcess) ) + ( (This)->lpVtbl -> CreateProcess(This,pProcess) ) #define ICorDebugManagedCallback_ExitProcess(This,pProcess) \ - ( (This)->lpVtbl -> ExitProcess(This,pProcess) ) + ( (This)->lpVtbl -> ExitProcess(This,pProcess) ) #define ICorDebugManagedCallback_CreateThread(This,pAppDomain,thread) \ - ( (This)->lpVtbl -> CreateThread(This,pAppDomain,thread) ) + ( (This)->lpVtbl -> CreateThread(This,pAppDomain,thread) ) #define ICorDebugManagedCallback_ExitThread(This,pAppDomain,thread) \ - ( (This)->lpVtbl -> ExitThread(This,pAppDomain,thread) ) + ( (This)->lpVtbl -> ExitThread(This,pAppDomain,thread) ) #define ICorDebugManagedCallback_LoadModule(This,pAppDomain,pModule) \ - ( (This)->lpVtbl -> LoadModule(This,pAppDomain,pModule) ) + ( (This)->lpVtbl -> LoadModule(This,pAppDomain,pModule) ) #define ICorDebugManagedCallback_UnloadModule(This,pAppDomain,pModule) \ - ( (This)->lpVtbl -> UnloadModule(This,pAppDomain,pModule) ) + ( (This)->lpVtbl -> UnloadModule(This,pAppDomain,pModule) ) #define ICorDebugManagedCallback_LoadClass(This,pAppDomain,c) \ - ( (This)->lpVtbl -> LoadClass(This,pAppDomain,c) ) + ( (This)->lpVtbl -> LoadClass(This,pAppDomain,c) ) #define ICorDebugManagedCallback_UnloadClass(This,pAppDomain,c) \ - ( (This)->lpVtbl -> UnloadClass(This,pAppDomain,c) ) + ( (This)->lpVtbl -> UnloadClass(This,pAppDomain,c) ) #define ICorDebugManagedCallback_DebuggerError(This,pProcess,errorHR,errorCode) \ - ( (This)->lpVtbl -> DebuggerError(This,pProcess,errorHR,errorCode) ) + ( (This)->lpVtbl -> DebuggerError(This,pProcess,errorHR,errorCode) ) #define ICorDebugManagedCallback_LogMessage(This,pAppDomain,pThread,lLevel,pLogSwitchName,pMessage) \ - ( (This)->lpVtbl -> LogMessage(This,pAppDomain,pThread,lLevel,pLogSwitchName,pMessage) ) + ( (This)->lpVtbl -> LogMessage(This,pAppDomain,pThread,lLevel,pLogSwitchName,pMessage) ) #define ICorDebugManagedCallback_LogSwitch(This,pAppDomain,pThread,lLevel,ulReason,pLogSwitchName,pParentName) \ - ( (This)->lpVtbl -> LogSwitch(This,pAppDomain,pThread,lLevel,ulReason,pLogSwitchName,pParentName) ) + ( (This)->lpVtbl -> LogSwitch(This,pAppDomain,pThread,lLevel,ulReason,pLogSwitchName,pParentName) ) #define ICorDebugManagedCallback_CreateAppDomain(This,pProcess,pAppDomain) \ - ( (This)->lpVtbl -> CreateAppDomain(This,pProcess,pAppDomain) ) + ( (This)->lpVtbl -> CreateAppDomain(This,pProcess,pAppDomain) ) #define ICorDebugManagedCallback_ExitAppDomain(This,pProcess,pAppDomain) \ - ( (This)->lpVtbl -> ExitAppDomain(This,pProcess,pAppDomain) ) + ( (This)->lpVtbl -> ExitAppDomain(This,pProcess,pAppDomain) ) #define ICorDebugManagedCallback_LoadAssembly(This,pAppDomain,pAssembly) \ - ( (This)->lpVtbl -> LoadAssembly(This,pAppDomain,pAssembly) ) + ( (This)->lpVtbl -> LoadAssembly(This,pAppDomain,pAssembly) ) #define ICorDebugManagedCallback_UnloadAssembly(This,pAppDomain,pAssembly) \ - ( (This)->lpVtbl -> UnloadAssembly(This,pAppDomain,pAssembly) ) + ( (This)->lpVtbl -> UnloadAssembly(This,pAppDomain,pAssembly) ) #define ICorDebugManagedCallback_ControlCTrap(This,pProcess) \ - ( (This)->lpVtbl -> ControlCTrap(This,pProcess) ) + ( (This)->lpVtbl -> ControlCTrap(This,pProcess) ) #define ICorDebugManagedCallback_NameChange(This,pAppDomain,pThread) \ - ( (This)->lpVtbl -> NameChange(This,pAppDomain,pThread) ) + ( (This)->lpVtbl -> NameChange(This,pAppDomain,pThread) ) #define ICorDebugManagedCallback_UpdateModuleSymbols(This,pAppDomain,pModule,pSymbolStream) \ - ( (This)->lpVtbl -> UpdateModuleSymbols(This,pAppDomain,pModule,pSymbolStream) ) + ( (This)->lpVtbl -> UpdateModuleSymbols(This,pAppDomain,pModule,pSymbolStream) ) #define ICorDebugManagedCallback_EditAndContinueRemap(This,pAppDomain,pThread,pFunction,fAccurate) \ - ( (This)->lpVtbl -> EditAndContinueRemap(This,pAppDomain,pThread,pFunction,fAccurate) ) + ( (This)->lpVtbl -> EditAndContinueRemap(This,pAppDomain,pThread,pFunction,fAccurate) ) #define ICorDebugManagedCallback_BreakpointSetError(This,pAppDomain,pThread,pBreakpoint,dwError) \ - ( (This)->lpVtbl -> BreakpointSetError(This,pAppDomain,pThread,pBreakpoint,dwError) ) + ( (This)->lpVtbl -> BreakpointSetError(This,pAppDomain,pThread,pBreakpoint,dwError) ) #endif /* COBJMACROS */ @@ -3861,7 +3868,7 @@ EXTERN_C const IID IID_ICorDebugManagedCallback; /* interface __MIDL_itf_cordebug_0000_0016 */ -/* [local] */ +/* [local] */ #pragma warning(pop) #pragma warning(push) @@ -3874,51 +3881,51 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0016_v0_0_s_ifspec; #define __ICorDebugManagedCallback3_INTERFACE_DEFINED__ /* interface ICorDebugManagedCallback3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugManagedCallback3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("264EA0FC-2591-49AA-868E-835E6515323F") ICorDebugManagedCallback3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CustomNotification( + virtual HRESULT STDMETHODCALLTYPE CustomNotification( /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugAppDomain *pAppDomain) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugManagedCallback3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugManagedCallback3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugManagedCallback3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugManagedCallback3 * This); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback3, CustomNotification) - HRESULT ( STDMETHODCALLTYPE *CustomNotification )( + HRESULT ( STDMETHODCALLTYPE *CustomNotification )( ICorDebugManagedCallback3 * This, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugAppDomain *pAppDomain); - + END_INTERFACE } ICorDebugManagedCallback3Vtbl; @@ -3927,23 +3934,23 @@ EXTERN_C const IID IID_ICorDebugManagedCallback3; CONST_VTBL struct ICorDebugManagedCallback3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugManagedCallback3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugManagedCallback3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugManagedCallback3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugManagedCallback3_CustomNotification(This,pThread,pAppDomain) \ - ( (This)->lpVtbl -> CustomNotification(This,pThread,pAppDomain) ) + ( (This)->lpVtbl -> CustomNotification(This,pThread,pAppDomain) ) #endif /* COBJMACROS */ @@ -3960,71 +3967,71 @@ EXTERN_C const IID IID_ICorDebugManagedCallback3; #define __ICorDebugManagedCallback4_INTERFACE_DEFINED__ /* interface ICorDebugManagedCallback4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugManagedCallback4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("322911AE-16A5-49BA-84A3-ED69678138A3") ICorDebugManagedCallback4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE BeforeGarbageCollection( + virtual HRESULT STDMETHODCALLTYPE BeforeGarbageCollection( /* [in] */ ICorDebugProcess *pProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE AfterGarbageCollection( + + virtual HRESULT STDMETHODCALLTYPE AfterGarbageCollection( /* [in] */ ICorDebugProcess *pProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE DataBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE DataBreakpoint( /* [in] */ ICorDebugProcess *pProcess, /* [in] */ ICorDebugThread *pThread, /* [in] */ BYTE *pContext, /* [in] */ ULONG32 contextSize) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugManagedCallback4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugManagedCallback4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugManagedCallback4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugManagedCallback4 * This); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback4, BeforeGarbageCollection) - HRESULT ( STDMETHODCALLTYPE *BeforeGarbageCollection )( + HRESULT ( STDMETHODCALLTYPE *BeforeGarbageCollection )( ICorDebugManagedCallback4 * This, /* [in] */ ICorDebugProcess *pProcess); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback4, AfterGarbageCollection) - HRESULT ( STDMETHODCALLTYPE *AfterGarbageCollection )( + HRESULT ( STDMETHODCALLTYPE *AfterGarbageCollection )( ICorDebugManagedCallback4 * This, /* [in] */ ICorDebugProcess *pProcess); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback4, DataBreakpoint) - HRESULT ( STDMETHODCALLTYPE *DataBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *DataBreakpoint )( ICorDebugManagedCallback4 * This, /* [in] */ ICorDebugProcess *pProcess, /* [in] */ ICorDebugThread *pThread, /* [in] */ BYTE *pContext, /* [in] */ ULONG32 contextSize); - + END_INTERFACE } ICorDebugManagedCallback4Vtbl; @@ -4033,29 +4040,29 @@ EXTERN_C const IID IID_ICorDebugManagedCallback4; CONST_VTBL struct ICorDebugManagedCallback4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugManagedCallback4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugManagedCallback4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugManagedCallback4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugManagedCallback4_BeforeGarbageCollection(This,pProcess) \ - ( (This)->lpVtbl -> BeforeGarbageCollection(This,pProcess) ) + ( (This)->lpVtbl -> BeforeGarbageCollection(This,pProcess) ) #define ICorDebugManagedCallback4_AfterGarbageCollection(This,pProcess) \ - ( (This)->lpVtbl -> AfterGarbageCollection(This,pProcess) ) + ( (This)->lpVtbl -> AfterGarbageCollection(This,pProcess) ) #define ICorDebugManagedCallback4_DataBreakpoint(This,pProcess,pThread,pContext,contextSize) \ - ( (This)->lpVtbl -> DataBreakpoint(This,pProcess,pThread,pContext,contextSize) ) + ( (This)->lpVtbl -> DataBreakpoint(This,pProcess,pThread,pContext,contextSize) ) #endif /* COBJMACROS */ @@ -4069,9 +4076,9 @@ EXTERN_C const IID IID_ICorDebugManagedCallback4; /* interface __MIDL_itf_cordebug_0000_0018 */ -/* [local] */ +/* [local] */ -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0018_v0_0_c_ifspec; @@ -4081,9 +4088,9 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0018_v0_0_s_ifspec; #define __ICorDebugManagedCallback2_INTERFACE_DEFINED__ /* interface ICorDebugManagedCallback2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugExceptionCallbackType { DEBUG_EXCEPTION_FIRST_CHANCE = 1, @@ -4092,14 +4099,14 @@ enum CorDebugExceptionCallbackType DEBUG_EXCEPTION_UNHANDLED = 4 } CorDebugExceptionCallbackType; -typedef +typedef enum CorDebugExceptionFlags { DEBUG_EXCEPTION_NONE = 0, DEBUG_EXCEPTION_CAN_BE_INTERCEPTED = 0x1 } CorDebugExceptionFlags; -typedef +typedef enum CorDebugExceptionUnwindCallbackType { DEBUG_EXCEPTION_UNWIND_BEGIN = 1, @@ -4110,109 +4117,109 @@ enum CorDebugExceptionUnwindCallbackType EXTERN_C const IID IID_ICorDebugManagedCallback2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("250E5EEA-DB5C-4C76-B6F3-8C46F12E3203") ICorDebugManagedCallback2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE FunctionRemapOpportunity( + virtual HRESULT STDMETHODCALLTYPE FunctionRemapOpportunity( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugFunction *pOldFunction, /* [in] */ ICorDebugFunction *pNewFunction, /* [in] */ ULONG32 oldILOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateConnection( + + virtual HRESULT STDMETHODCALLTYPE CreateConnection( /* [in] */ ICorDebugProcess *pProcess, /* [in] */ CONNID dwConnectionId, /* [in] */ WCHAR *pConnName) = 0; - - virtual HRESULT STDMETHODCALLTYPE ChangeConnection( + + virtual HRESULT STDMETHODCALLTYPE ChangeConnection( /* [in] */ ICorDebugProcess *pProcess, /* [in] */ CONNID dwConnectionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE DestroyConnection( + + virtual HRESULT STDMETHODCALLTYPE DestroyConnection( /* [in] */ ICorDebugProcess *pProcess, /* [in] */ CONNID dwConnectionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE Exception( + + virtual HRESULT STDMETHODCALLTYPE Exception( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugFrame *pFrame, /* [in] */ ULONG32 nOffset, /* [in] */ CorDebugExceptionCallbackType dwEventType, /* [in] */ DWORD dwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE ExceptionUnwind( + + virtual HRESULT STDMETHODCALLTYPE ExceptionUnwind( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ CorDebugExceptionUnwindCallbackType dwEventType, /* [in] */ DWORD dwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE FunctionRemapComplete( + + virtual HRESULT STDMETHODCALLTYPE FunctionRemapComplete( /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugFunction *pFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE MDANotification( + + virtual HRESULT STDMETHODCALLTYPE MDANotification( /* [in] */ ICorDebugController *pController, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugMDA *pMDA) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugManagedCallback2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugManagedCallback2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugManagedCallback2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugManagedCallback2 * This); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, FunctionRemapOpportunity) - HRESULT ( STDMETHODCALLTYPE *FunctionRemapOpportunity )( + HRESULT ( STDMETHODCALLTYPE *FunctionRemapOpportunity )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugFunction *pOldFunction, /* [in] */ ICorDebugFunction *pNewFunction, /* [in] */ ULONG32 oldILOffset); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, CreateConnection) - HRESULT ( STDMETHODCALLTYPE *CreateConnection )( + HRESULT ( STDMETHODCALLTYPE *CreateConnection )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugProcess *pProcess, /* [in] */ CONNID dwConnectionId, /* [in] */ WCHAR *pConnName); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, ChangeConnection) - HRESULT ( STDMETHODCALLTYPE *ChangeConnection )( + HRESULT ( STDMETHODCALLTYPE *ChangeConnection )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugProcess *pProcess, /* [in] */ CONNID dwConnectionId); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, DestroyConnection) - HRESULT ( STDMETHODCALLTYPE *DestroyConnection )( + HRESULT ( STDMETHODCALLTYPE *DestroyConnection )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugProcess *pProcess, /* [in] */ CONNID dwConnectionId); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, Exception) - HRESULT ( STDMETHODCALLTYPE *Exception )( + HRESULT ( STDMETHODCALLTYPE *Exception )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, @@ -4220,29 +4227,29 @@ EXTERN_C const IID IID_ICorDebugManagedCallback2; /* [in] */ ULONG32 nOffset, /* [in] */ CorDebugExceptionCallbackType dwEventType, /* [in] */ DWORD dwFlags); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, ExceptionUnwind) - HRESULT ( STDMETHODCALLTYPE *ExceptionUnwind )( + HRESULT ( STDMETHODCALLTYPE *ExceptionUnwind )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ CorDebugExceptionUnwindCallbackType dwEventType, /* [in] */ DWORD dwFlags); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, FunctionRemapComplete) - HRESULT ( STDMETHODCALLTYPE *FunctionRemapComplete )( + HRESULT ( STDMETHODCALLTYPE *FunctionRemapComplete )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugAppDomain *pAppDomain, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugFunction *pFunction); - + DECLSPEC_XFGVIRT(ICorDebugManagedCallback2, MDANotification) - HRESULT ( STDMETHODCALLTYPE *MDANotification )( + HRESULT ( STDMETHODCALLTYPE *MDANotification )( ICorDebugManagedCallback2 * This, /* [in] */ ICorDebugController *pController, /* [in] */ ICorDebugThread *pThread, /* [in] */ ICorDebugMDA *pMDA); - + END_INTERFACE } ICorDebugManagedCallback2Vtbl; @@ -4251,44 +4258,44 @@ EXTERN_C const IID IID_ICorDebugManagedCallback2; CONST_VTBL struct ICorDebugManagedCallback2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugManagedCallback2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugManagedCallback2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugManagedCallback2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugManagedCallback2_FunctionRemapOpportunity(This,pAppDomain,pThread,pOldFunction,pNewFunction,oldILOffset) \ - ( (This)->lpVtbl -> FunctionRemapOpportunity(This,pAppDomain,pThread,pOldFunction,pNewFunction,oldILOffset) ) + ( (This)->lpVtbl -> FunctionRemapOpportunity(This,pAppDomain,pThread,pOldFunction,pNewFunction,oldILOffset) ) #define ICorDebugManagedCallback2_CreateConnection(This,pProcess,dwConnectionId,pConnName) \ - ( (This)->lpVtbl -> CreateConnection(This,pProcess,dwConnectionId,pConnName) ) + ( (This)->lpVtbl -> CreateConnection(This,pProcess,dwConnectionId,pConnName) ) #define ICorDebugManagedCallback2_ChangeConnection(This,pProcess,dwConnectionId) \ - ( (This)->lpVtbl -> ChangeConnection(This,pProcess,dwConnectionId) ) + ( (This)->lpVtbl -> ChangeConnection(This,pProcess,dwConnectionId) ) #define ICorDebugManagedCallback2_DestroyConnection(This,pProcess,dwConnectionId) \ - ( (This)->lpVtbl -> DestroyConnection(This,pProcess,dwConnectionId) ) + ( (This)->lpVtbl -> DestroyConnection(This,pProcess,dwConnectionId) ) #define ICorDebugManagedCallback2_Exception(This,pAppDomain,pThread,pFrame,nOffset,dwEventType,dwFlags) \ - ( (This)->lpVtbl -> Exception(This,pAppDomain,pThread,pFrame,nOffset,dwEventType,dwFlags) ) + ( (This)->lpVtbl -> Exception(This,pAppDomain,pThread,pFrame,nOffset,dwEventType,dwFlags) ) #define ICorDebugManagedCallback2_ExceptionUnwind(This,pAppDomain,pThread,dwEventType,dwFlags) \ - ( (This)->lpVtbl -> ExceptionUnwind(This,pAppDomain,pThread,dwEventType,dwFlags) ) + ( (This)->lpVtbl -> ExceptionUnwind(This,pAppDomain,pThread,dwEventType,dwFlags) ) #define ICorDebugManagedCallback2_FunctionRemapComplete(This,pAppDomain,pThread,pFunction) \ - ( (This)->lpVtbl -> FunctionRemapComplete(This,pAppDomain,pThread,pFunction) ) + ( (This)->lpVtbl -> FunctionRemapComplete(This,pAppDomain,pThread,pFunction) ) #define ICorDebugManagedCallback2_MDANotification(This,pController,pThread,pMDA) \ - ( (This)->lpVtbl -> MDANotification(This,pController,pThread,pMDA) ) + ( (This)->lpVtbl -> MDANotification(This,pController,pThread,pMDA) ) #endif /* COBJMACROS */ @@ -4302,7 +4309,7 @@ EXTERN_C const IID IID_ICorDebugManagedCallback2; /* interface __MIDL_itf_cordebug_0000_0019 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -4314,51 +4321,51 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0019_v0_0_s_ifspec; #define __ICorDebugUnmanagedCallback_INTERFACE_DEFINED__ /* interface ICorDebugUnmanagedCallback */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugUnmanagedCallback; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("5263E909-8CB5-11d3-BD2F-0000F80849BD") ICorDebugUnmanagedCallback : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE DebugEvent( + virtual HRESULT STDMETHODCALLTYPE DebugEvent( /* [in] */ LPDEBUG_EVENT pDebugEvent, /* [in] */ BOOL fOutOfBand) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugUnmanagedCallbackVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugUnmanagedCallback * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugUnmanagedCallback * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugUnmanagedCallback * This); - + DECLSPEC_XFGVIRT(ICorDebugUnmanagedCallback, DebugEvent) - HRESULT ( STDMETHODCALLTYPE *DebugEvent )( + HRESULT ( STDMETHODCALLTYPE *DebugEvent )( ICorDebugUnmanagedCallback * This, /* [in] */ LPDEBUG_EVENT pDebugEvent, /* [in] */ BOOL fOutOfBand); - + END_INTERFACE } ICorDebugUnmanagedCallbackVtbl; @@ -4367,23 +4374,23 @@ EXTERN_C const IID IID_ICorDebugUnmanagedCallback; CONST_VTBL struct ICorDebugUnmanagedCallbackVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugUnmanagedCallback_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugUnmanagedCallback_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugUnmanagedCallback_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugUnmanagedCallback_DebugEvent(This,pDebugEvent,fOutOfBand) \ - ( (This)->lpVtbl -> DebugEvent(This,pDebugEvent,fOutOfBand) ) + ( (This)->lpVtbl -> DebugEvent(This,pDebugEvent,fOutOfBand) ) #endif /* COBJMACROS */ @@ -4397,15 +4404,15 @@ EXTERN_C const IID IID_ICorDebugUnmanagedCallback; /* interface __MIDL_itf_cordebug_0000_0020 */ -/* [local] */ +/* [local] */ -typedef +typedef enum CorDebugCreateProcessFlags { DEBUG_NO_SPECIAL_OPTIONS = 0 } CorDebugCreateProcessFlags; -typedef +typedef enum CorDebugHandleType { HANDLE_STRONG = 1, @@ -4414,7 +4421,7 @@ enum CorDebugHandleType } CorDebugHandleType; #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0020_v0_0_c_ifspec; @@ -4424,28 +4431,28 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0020_v0_0_s_ifspec; #define __ICorDebug_INTERFACE_DEFINED__ /* interface ICorDebug */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebug; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("3d6f5f61-7538-11d3-8d5b-00104b35e7ef") ICorDebug : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE Initialize( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE Terminate( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetManagedHandler( + + virtual HRESULT STDMETHODCALLTYPE SetManagedHandler( /* [in] */ ICorDebugManagedCallback *pCallback) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetUnmanagedHandler( + + virtual HRESULT STDMETHODCALLTYPE SetUnmanagedHandler( /* [in] */ ICorDebugUnmanagedCallback *pCallback) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateProcess( + + virtual HRESULT STDMETHODCALLTYPE CreateProcess( /* [in] */ LPCWSTR lpApplicationName, /* [in] */ LPWSTR lpCommandLine, /* [in] */ LPSECURITY_ATTRIBUTES lpProcessAttributes, @@ -4458,67 +4465,67 @@ EXTERN_C const IID IID_ICorDebug; /* [in] */ LPPROCESS_INFORMATION lpProcessInformation, /* [in] */ CorDebugCreateProcessFlags debuggingFlags, /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE DebugActiveProcess( + + virtual HRESULT STDMETHODCALLTYPE DebugActiveProcess( /* [in] */ DWORD id, /* [in] */ BOOL win32Attach, /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateProcesses( + + virtual HRESULT STDMETHODCALLTYPE EnumerateProcesses( /* [out] */ ICorDebugProcessEnum **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetProcess( + + virtual HRESULT STDMETHODCALLTYPE GetProcess( /* [in] */ DWORD dwProcessId, /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE CanLaunchOrAttach( + + virtual HRESULT STDMETHODCALLTYPE CanLaunchOrAttach( /* [in] */ DWORD dwProcessId, /* [in] */ BOOL win32DebuggingEnabled) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebug * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebug * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebug * This); - + DECLSPEC_XFGVIRT(ICorDebug, Initialize) - HRESULT ( STDMETHODCALLTYPE *Initialize )( + HRESULT ( STDMETHODCALLTYPE *Initialize )( ICorDebug * This); - + DECLSPEC_XFGVIRT(ICorDebug, Terminate) - HRESULT ( STDMETHODCALLTYPE *Terminate )( + HRESULT ( STDMETHODCALLTYPE *Terminate )( ICorDebug * This); - + DECLSPEC_XFGVIRT(ICorDebug, SetManagedHandler) - HRESULT ( STDMETHODCALLTYPE *SetManagedHandler )( + HRESULT ( STDMETHODCALLTYPE *SetManagedHandler )( ICorDebug * This, /* [in] */ ICorDebugManagedCallback *pCallback); - + DECLSPEC_XFGVIRT(ICorDebug, SetUnmanagedHandler) - HRESULT ( STDMETHODCALLTYPE *SetUnmanagedHandler )( + HRESULT ( STDMETHODCALLTYPE *SetUnmanagedHandler )( ICorDebug * This, /* [in] */ ICorDebugUnmanagedCallback *pCallback); - + DECLSPEC_XFGVIRT(ICorDebug, CreateProcess) - HRESULT ( STDMETHODCALLTYPE *CreateProcess )( + HRESULT ( STDMETHODCALLTYPE *CreateProcess )( ICorDebug * This, /* [in] */ LPCWSTR lpApplicationName, /* [in] */ LPWSTR lpCommandLine, @@ -4532,31 +4539,31 @@ EXTERN_C const IID IID_ICorDebug; /* [in] */ LPPROCESS_INFORMATION lpProcessInformation, /* [in] */ CorDebugCreateProcessFlags debuggingFlags, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebug, DebugActiveProcess) - HRESULT ( STDMETHODCALLTYPE *DebugActiveProcess )( + HRESULT ( STDMETHODCALLTYPE *DebugActiveProcess )( ICorDebug * This, /* [in] */ DWORD id, /* [in] */ BOOL win32Attach, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebug, EnumerateProcesses) - HRESULT ( STDMETHODCALLTYPE *EnumerateProcesses )( + HRESULT ( STDMETHODCALLTYPE *EnumerateProcesses )( ICorDebug * This, /* [out] */ ICorDebugProcessEnum **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebug, GetProcess) - HRESULT ( STDMETHODCALLTYPE *GetProcess )( + HRESULT ( STDMETHODCALLTYPE *GetProcess )( ICorDebug * This, /* [in] */ DWORD dwProcessId, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebug, CanLaunchOrAttach) - HRESULT ( STDMETHODCALLTYPE *CanLaunchOrAttach )( + HRESULT ( STDMETHODCALLTYPE *CanLaunchOrAttach )( ICorDebug * This, /* [in] */ DWORD dwProcessId, /* [in] */ BOOL win32DebuggingEnabled); - + END_INTERFACE } ICorDebugVtbl; @@ -4565,47 +4572,47 @@ EXTERN_C const IID IID_ICorDebug; CONST_VTBL struct ICorDebugVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebug_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebug_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebug_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebug_Initialize(This) \ - ( (This)->lpVtbl -> Initialize(This) ) + ( (This)->lpVtbl -> Initialize(This) ) #define ICorDebug_Terminate(This) \ - ( (This)->lpVtbl -> Terminate(This) ) + ( (This)->lpVtbl -> Terminate(This) ) #define ICorDebug_SetManagedHandler(This,pCallback) \ - ( (This)->lpVtbl -> SetManagedHandler(This,pCallback) ) + ( (This)->lpVtbl -> SetManagedHandler(This,pCallback) ) #define ICorDebug_SetUnmanagedHandler(This,pCallback) \ - ( (This)->lpVtbl -> SetUnmanagedHandler(This,pCallback) ) + ( (This)->lpVtbl -> SetUnmanagedHandler(This,pCallback) ) #define ICorDebug_CreateProcess(This,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation,debuggingFlags,ppProcess) \ - ( (This)->lpVtbl -> CreateProcess(This,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation,debuggingFlags,ppProcess) ) + ( (This)->lpVtbl -> CreateProcess(This,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation,debuggingFlags,ppProcess) ) #define ICorDebug_DebugActiveProcess(This,id,win32Attach,ppProcess) \ - ( (This)->lpVtbl -> DebugActiveProcess(This,id,win32Attach,ppProcess) ) + ( (This)->lpVtbl -> DebugActiveProcess(This,id,win32Attach,ppProcess) ) #define ICorDebug_EnumerateProcesses(This,ppProcess) \ - ( (This)->lpVtbl -> EnumerateProcesses(This,ppProcess) ) + ( (This)->lpVtbl -> EnumerateProcesses(This,ppProcess) ) #define ICorDebug_GetProcess(This,dwProcessId,ppProcess) \ - ( (This)->lpVtbl -> GetProcess(This,dwProcessId,ppProcess) ) + ( (This)->lpVtbl -> GetProcess(This,dwProcessId,ppProcess) ) #define ICorDebug_CanLaunchOrAttach(This,dwProcessId,win32DebuggingEnabled) \ - ( (This)->lpVtbl -> CanLaunchOrAttach(This,dwProcessId,win32DebuggingEnabled) ) + ( (This)->lpVtbl -> CanLaunchOrAttach(This,dwProcessId,win32DebuggingEnabled) ) #endif /* COBJMACROS */ @@ -4619,7 +4626,7 @@ EXTERN_C const IID IID_ICorDebug; /* interface __MIDL_itf_cordebug_0000_0021 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -4631,57 +4638,57 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0021_v0_0_s_ifspec; #define __ICorDebugRemoteTarget_INTERFACE_DEFINED__ /* interface ICorDebugRemoteTarget */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugRemoteTarget; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("C3ED8383-5A49-4cf5-B4B7-01864D9E582D") ICorDebugRemoteTarget : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetHostName( + virtual HRESULT STDMETHODCALLTYPE GetHostName( /* [in] */ ULONG32 cchHostName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_ ULONG32 *pcchHostName, - /* [annotation][length_is][size_is][out] */ + /* [annotation][length_is][size_is][out] */ _Out_writes_to_opt_(cchHostName, *pcchHostName) WCHAR szHostName[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugRemoteTargetVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugRemoteTarget * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugRemoteTarget * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugRemoteTarget * This); - + DECLSPEC_XFGVIRT(ICorDebugRemoteTarget, GetHostName) - HRESULT ( STDMETHODCALLTYPE *GetHostName )( + HRESULT ( STDMETHODCALLTYPE *GetHostName )( ICorDebugRemoteTarget * This, /* [in] */ ULONG32 cchHostName, - /* [annotation][out] */ + /* [annotation][out] */ _Out_ ULONG32 *pcchHostName, - /* [annotation][length_is][size_is][out] */ + /* [annotation][length_is][size_is][out] */ _Out_writes_to_opt_(cchHostName, *pcchHostName) WCHAR szHostName[ ]); - + END_INTERFACE } ICorDebugRemoteTargetVtbl; @@ -4690,23 +4697,23 @@ EXTERN_C const IID IID_ICorDebugRemoteTarget; CONST_VTBL struct ICorDebugRemoteTargetVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugRemoteTarget_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugRemoteTarget_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugRemoteTarget_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugRemoteTarget_GetHostName(This,cchHostName,pcchHostName,szHostName) \ - ( (This)->lpVtbl -> GetHostName(This,cchHostName,pcchHostName,szHostName) ) + ( (This)->lpVtbl -> GetHostName(This,cchHostName,pcchHostName,szHostName) ) #endif /* COBJMACROS */ @@ -4723,21 +4730,21 @@ EXTERN_C const IID IID_ICorDebugRemoteTarget; #define __ICorDebugRemote_INTERFACE_DEFINED__ /* interface ICorDebugRemote */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugRemote; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("D5EBB8E2-7BBE-4c1d-98A6-A3C04CBDEF64") ICorDebugRemote : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CreateProcessEx( + virtual HRESULT STDMETHODCALLTYPE CreateProcessEx( /* [in] */ ICorDebugRemoteTarget *pRemoteTarget, /* [in] */ LPCWSTR lpApplicationName, - /* [annotation][in] */ + /* [annotation][in] */ _In_ LPWSTR lpCommandLine, /* [in] */ LPSECURITY_ATTRIBUTES lpProcessAttributes, /* [in] */ LPSECURITY_ATTRIBUTES lpThreadAttributes, @@ -4749,43 +4756,43 @@ EXTERN_C const IID IID_ICorDebugRemote; /* [in] */ LPPROCESS_INFORMATION lpProcessInformation, /* [in] */ CorDebugCreateProcessFlags debuggingFlags, /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE DebugActiveProcessEx( + + virtual HRESULT STDMETHODCALLTYPE DebugActiveProcessEx( /* [in] */ ICorDebugRemoteTarget *pRemoteTarget, /* [in] */ DWORD dwProcessId, /* [in] */ BOOL fWin32Attach, /* [out] */ ICorDebugProcess **ppProcess) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugRemoteVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugRemote * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugRemote * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugRemote * This); - + DECLSPEC_XFGVIRT(ICorDebugRemote, CreateProcessEx) - HRESULT ( STDMETHODCALLTYPE *CreateProcessEx )( + HRESULT ( STDMETHODCALLTYPE *CreateProcessEx )( ICorDebugRemote * This, /* [in] */ ICorDebugRemoteTarget *pRemoteTarget, /* [in] */ LPCWSTR lpApplicationName, - /* [annotation][in] */ + /* [annotation][in] */ _In_ LPWSTR lpCommandLine, /* [in] */ LPSECURITY_ATTRIBUTES lpProcessAttributes, /* [in] */ LPSECURITY_ATTRIBUTES lpThreadAttributes, @@ -4797,15 +4804,15 @@ EXTERN_C const IID IID_ICorDebugRemote; /* [in] */ LPPROCESS_INFORMATION lpProcessInformation, /* [in] */ CorDebugCreateProcessFlags debuggingFlags, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebugRemote, DebugActiveProcessEx) - HRESULT ( STDMETHODCALLTYPE *DebugActiveProcessEx )( + HRESULT ( STDMETHODCALLTYPE *DebugActiveProcessEx )( ICorDebugRemote * This, /* [in] */ ICorDebugRemoteTarget *pRemoteTarget, /* [in] */ DWORD dwProcessId, /* [in] */ BOOL fWin32Attach, /* [out] */ ICorDebugProcess **ppProcess); - + END_INTERFACE } ICorDebugRemoteVtbl; @@ -4814,26 +4821,26 @@ EXTERN_C const IID IID_ICorDebugRemote; CONST_VTBL struct ICorDebugRemoteVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugRemote_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugRemote_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugRemote_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugRemote_CreateProcessEx(This,pRemoteTarget,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation,debuggingFlags,ppProcess) \ - ( (This)->lpVtbl -> CreateProcessEx(This,pRemoteTarget,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation,debuggingFlags,ppProcess) ) + ( (This)->lpVtbl -> CreateProcessEx(This,pRemoteTarget,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation,debuggingFlags,ppProcess) ) #define ICorDebugRemote_DebugActiveProcessEx(This,pRemoteTarget,dwProcessId,fWin32Attach,ppProcess) \ - ( (This)->lpVtbl -> DebugActiveProcessEx(This,pRemoteTarget,dwProcessId,fWin32Attach,ppProcess) ) + ( (This)->lpVtbl -> DebugActiveProcessEx(This,pRemoteTarget,dwProcessId,fWin32Attach,ppProcess) ) #endif /* COBJMACROS */ @@ -4847,7 +4854,7 @@ EXTERN_C const IID IID_ICorDebugRemote; /* interface __MIDL_itf_cordebug_0000_0023 */ -/* [local] */ +/* [local] */ typedef struct _COR_VERSION { @@ -4866,9 +4873,9 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0023_v0_0_s_ifspec; #define __ICorDebug2_INTERFACE_DEFINED__ /* interface ICorDebug2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugInterfaceVersion { CorDebugInvalidVersion = 0, @@ -4962,35 +4969,35 @@ enum CorDebugInterfaceVersion EXTERN_C const IID IID_ICorDebug2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("ECCCCF2E-B286-4b3e-A983-860A8793D105") ICorDebug2 : public IUnknown { public: }; - - + + #else /* C style interface */ typedef struct ICorDebug2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebug2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebug2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebug2 * This); - + END_INTERFACE } ICorDebug2Vtbl; @@ -4999,19 +5006,19 @@ EXTERN_C const IID IID_ICorDebug2; CONST_VTBL struct ICorDebug2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebug2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebug2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebug2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #endif /* COBJMACROS */ @@ -5026,13 +5033,13 @@ EXTERN_C const IID IID_ICorDebug2; /* interface __MIDL_itf_cordebug_0000_0024 */ -/* [local] */ +/* [local] */ -typedef +typedef enum CorDebugThreadState { THREAD_RUN = 0, - THREAD_SUSPEND = ( THREAD_RUN + 1 ) + THREAD_SUSPEND = ( THREAD_RUN + 1 ) } CorDebugThreadState; @@ -5044,131 +5051,131 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0024_v0_0_s_ifspec; #define __ICorDebugController_INTERFACE_DEFINED__ /* interface ICorDebugController */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugController; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("3d6f5f62-7538-11d3-8d5b-00104b35e7ef") ICorDebugController : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Stop( + virtual HRESULT STDMETHODCALLTYPE Stop( /* [in] */ DWORD dwTimeoutIgnored) = 0; - - virtual HRESULT STDMETHODCALLTYPE Continue( + + virtual HRESULT STDMETHODCALLTYPE Continue( /* [in] */ BOOL fIsOutOfBand) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsRunning( + + virtual HRESULT STDMETHODCALLTYPE IsRunning( /* [out] */ BOOL *pbRunning) = 0; - - virtual HRESULT STDMETHODCALLTYPE HasQueuedCallbacks( + + virtual HRESULT STDMETHODCALLTYPE HasQueuedCallbacks( /* [in] */ ICorDebugThread *pThread, /* [out] */ BOOL *pbQueued) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateThreads( + + virtual HRESULT STDMETHODCALLTYPE EnumerateThreads( /* [out] */ ICorDebugThreadEnum **ppThreads) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetAllThreadsDebugState( + + virtual HRESULT STDMETHODCALLTYPE SetAllThreadsDebugState( /* [in] */ CorDebugThreadState state, /* [in] */ ICorDebugThread *pExceptThisThread) = 0; - + virtual HRESULT STDMETHODCALLTYPE Detach( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Terminate( + + virtual HRESULT STDMETHODCALLTYPE Terminate( /* [in] */ UINT exitCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE CanCommitChanges( + + virtual HRESULT STDMETHODCALLTYPE CanCommitChanges( /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError) = 0; - - virtual HRESULT STDMETHODCALLTYPE CommitChanges( + + virtual HRESULT STDMETHODCALLTYPE CommitChanges( /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugControllerVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugController * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugController * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugController * This); - + DECLSPEC_XFGVIRT(ICorDebugController, Stop) - HRESULT ( STDMETHODCALLTYPE *Stop )( + HRESULT ( STDMETHODCALLTYPE *Stop )( ICorDebugController * This, /* [in] */ DWORD dwTimeoutIgnored); - + DECLSPEC_XFGVIRT(ICorDebugController, Continue) - HRESULT ( STDMETHODCALLTYPE *Continue )( + HRESULT ( STDMETHODCALLTYPE *Continue )( ICorDebugController * This, /* [in] */ BOOL fIsOutOfBand); - + DECLSPEC_XFGVIRT(ICorDebugController, IsRunning) - HRESULT ( STDMETHODCALLTYPE *IsRunning )( + HRESULT ( STDMETHODCALLTYPE *IsRunning )( ICorDebugController * This, /* [out] */ BOOL *pbRunning); - + DECLSPEC_XFGVIRT(ICorDebugController, HasQueuedCallbacks) - HRESULT ( STDMETHODCALLTYPE *HasQueuedCallbacks )( + HRESULT ( STDMETHODCALLTYPE *HasQueuedCallbacks )( ICorDebugController * This, /* [in] */ ICorDebugThread *pThread, /* [out] */ BOOL *pbQueued); - + DECLSPEC_XFGVIRT(ICorDebugController, EnumerateThreads) - HRESULT ( STDMETHODCALLTYPE *EnumerateThreads )( + HRESULT ( STDMETHODCALLTYPE *EnumerateThreads )( ICorDebugController * This, /* [out] */ ICorDebugThreadEnum **ppThreads); - + DECLSPEC_XFGVIRT(ICorDebugController, SetAllThreadsDebugState) - HRESULT ( STDMETHODCALLTYPE *SetAllThreadsDebugState )( + HRESULT ( STDMETHODCALLTYPE *SetAllThreadsDebugState )( ICorDebugController * This, /* [in] */ CorDebugThreadState state, /* [in] */ ICorDebugThread *pExceptThisThread); - + DECLSPEC_XFGVIRT(ICorDebugController, Detach) - HRESULT ( STDMETHODCALLTYPE *Detach )( + HRESULT ( STDMETHODCALLTYPE *Detach )( ICorDebugController * This); - + DECLSPEC_XFGVIRT(ICorDebugController, Terminate) - HRESULT ( STDMETHODCALLTYPE *Terminate )( + HRESULT ( STDMETHODCALLTYPE *Terminate )( ICorDebugController * This, /* [in] */ UINT exitCode); - + DECLSPEC_XFGVIRT(ICorDebugController, CanCommitChanges) - HRESULT ( STDMETHODCALLTYPE *CanCommitChanges )( + HRESULT ( STDMETHODCALLTYPE *CanCommitChanges )( ICorDebugController * This, /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError); - + DECLSPEC_XFGVIRT(ICorDebugController, CommitChanges) - HRESULT ( STDMETHODCALLTYPE *CommitChanges )( + HRESULT ( STDMETHODCALLTYPE *CommitChanges )( ICorDebugController * This, /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError); - + END_INTERFACE } ICorDebugControllerVtbl; @@ -5177,50 +5184,50 @@ EXTERN_C const IID IID_ICorDebugController; CONST_VTBL struct ICorDebugControllerVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugController_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugController_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugController_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugController_Stop(This,dwTimeoutIgnored) \ - ( (This)->lpVtbl -> Stop(This,dwTimeoutIgnored) ) + ( (This)->lpVtbl -> Stop(This,dwTimeoutIgnored) ) #define ICorDebugController_Continue(This,fIsOutOfBand) \ - ( (This)->lpVtbl -> Continue(This,fIsOutOfBand) ) + ( (This)->lpVtbl -> Continue(This,fIsOutOfBand) ) #define ICorDebugController_IsRunning(This,pbRunning) \ - ( (This)->lpVtbl -> IsRunning(This,pbRunning) ) + ( (This)->lpVtbl -> IsRunning(This,pbRunning) ) #define ICorDebugController_HasQueuedCallbacks(This,pThread,pbQueued) \ - ( (This)->lpVtbl -> HasQueuedCallbacks(This,pThread,pbQueued) ) + ( (This)->lpVtbl -> HasQueuedCallbacks(This,pThread,pbQueued) ) #define ICorDebugController_EnumerateThreads(This,ppThreads) \ - ( (This)->lpVtbl -> EnumerateThreads(This,ppThreads) ) + ( (This)->lpVtbl -> EnumerateThreads(This,ppThreads) ) #define ICorDebugController_SetAllThreadsDebugState(This,state,pExceptThisThread) \ - ( (This)->lpVtbl -> SetAllThreadsDebugState(This,state,pExceptThisThread) ) + ( (This)->lpVtbl -> SetAllThreadsDebugState(This,state,pExceptThisThread) ) #define ICorDebugController_Detach(This) \ - ( (This)->lpVtbl -> Detach(This) ) + ( (This)->lpVtbl -> Detach(This) ) #define ICorDebugController_Terminate(This,exitCode) \ - ( (This)->lpVtbl -> Terminate(This,exitCode) ) + ( (This)->lpVtbl -> Terminate(This,exitCode) ) #define ICorDebugController_CanCommitChanges(This,cSnapshots,pSnapshots,pError) \ - ( (This)->lpVtbl -> CanCommitChanges(This,cSnapshots,pSnapshots,pError) ) + ( (This)->lpVtbl -> CanCommitChanges(This,cSnapshots,pSnapshots,pError) ) #define ICorDebugController_CommitChanges(This,cSnapshots,pSnapshots,pError) \ - ( (This)->lpVtbl -> CommitChanges(This,cSnapshots,pSnapshots,pError) ) + ( (This)->lpVtbl -> CommitChanges(This,cSnapshots,pSnapshots,pError) ) #endif /* COBJMACROS */ @@ -5234,10 +5241,10 @@ EXTERN_C const IID IID_ICorDebugController; /* interface __MIDL_itf_cordebug_0000_0025 */ -/* [local] */ +/* [local] */ #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0025_v0_0_c_ifspec; @@ -5247,180 +5254,180 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0025_v0_0_s_ifspec; #define __ICorDebugAppDomain_INTERFACE_DEFINED__ /* interface ICorDebugAppDomain */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAppDomain; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("3d6f5f63-7538-11d3-8d5b-00104b35e7ef") ICorDebugAppDomain : public ICorDebugController { public: - virtual HRESULT STDMETHODCALLTYPE GetProcess( + virtual HRESULT STDMETHODCALLTYPE GetProcess( /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateAssemblies( + + virtual HRESULT STDMETHODCALLTYPE EnumerateAssemblies( /* [out] */ ICorDebugAssemblyEnum **ppAssemblies) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetModuleFromMetaDataInterface( + + virtual HRESULT STDMETHODCALLTYPE GetModuleFromMetaDataInterface( /* [in] */ IUnknown *pIMetaData, /* [out] */ ICorDebugModule **ppModule) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateBreakpoints( + + virtual HRESULT STDMETHODCALLTYPE EnumerateBreakpoints( /* [out] */ ICorDebugBreakpointEnum **ppBreakpoints) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateSteppers( + + virtual HRESULT STDMETHODCALLTYPE EnumerateSteppers( /* [out] */ ICorDebugStepperEnum **ppSteppers) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsAttached( + + virtual HRESULT STDMETHODCALLTYPE IsAttached( /* [out] */ BOOL *pbAttached) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetName( + + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObject( + + virtual HRESULT STDMETHODCALLTYPE GetObject( /* [out] */ ICorDebugValue **ppObject) = 0; - + virtual HRESULT STDMETHODCALLTYPE Attach( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetID( + + virtual HRESULT STDMETHODCALLTYPE GetID( /* [out] */ ULONG32 *pId) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAppDomainVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAppDomain * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAppDomain * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAppDomain * This); - + DECLSPEC_XFGVIRT(ICorDebugController, Stop) - HRESULT ( STDMETHODCALLTYPE *Stop )( + HRESULT ( STDMETHODCALLTYPE *Stop )( ICorDebugAppDomain * This, /* [in] */ DWORD dwTimeoutIgnored); - + DECLSPEC_XFGVIRT(ICorDebugController, Continue) - HRESULT ( STDMETHODCALLTYPE *Continue )( + HRESULT ( STDMETHODCALLTYPE *Continue )( ICorDebugAppDomain * This, /* [in] */ BOOL fIsOutOfBand); - + DECLSPEC_XFGVIRT(ICorDebugController, IsRunning) - HRESULT ( STDMETHODCALLTYPE *IsRunning )( + HRESULT ( STDMETHODCALLTYPE *IsRunning )( ICorDebugAppDomain * This, /* [out] */ BOOL *pbRunning); - + DECLSPEC_XFGVIRT(ICorDebugController, HasQueuedCallbacks) - HRESULT ( STDMETHODCALLTYPE *HasQueuedCallbacks )( + HRESULT ( STDMETHODCALLTYPE *HasQueuedCallbacks )( ICorDebugAppDomain * This, /* [in] */ ICorDebugThread *pThread, /* [out] */ BOOL *pbQueued); - + DECLSPEC_XFGVIRT(ICorDebugController, EnumerateThreads) - HRESULT ( STDMETHODCALLTYPE *EnumerateThreads )( + HRESULT ( STDMETHODCALLTYPE *EnumerateThreads )( ICorDebugAppDomain * This, /* [out] */ ICorDebugThreadEnum **ppThreads); - + DECLSPEC_XFGVIRT(ICorDebugController, SetAllThreadsDebugState) - HRESULT ( STDMETHODCALLTYPE *SetAllThreadsDebugState )( + HRESULT ( STDMETHODCALLTYPE *SetAllThreadsDebugState )( ICorDebugAppDomain * This, /* [in] */ CorDebugThreadState state, /* [in] */ ICorDebugThread *pExceptThisThread); - + DECLSPEC_XFGVIRT(ICorDebugController, Detach) - HRESULT ( STDMETHODCALLTYPE *Detach )( + HRESULT ( STDMETHODCALLTYPE *Detach )( ICorDebugAppDomain * This); - + DECLSPEC_XFGVIRT(ICorDebugController, Terminate) - HRESULT ( STDMETHODCALLTYPE *Terminate )( + HRESULT ( STDMETHODCALLTYPE *Terminate )( ICorDebugAppDomain * This, /* [in] */ UINT exitCode); - + DECLSPEC_XFGVIRT(ICorDebugController, CanCommitChanges) - HRESULT ( STDMETHODCALLTYPE *CanCommitChanges )( + HRESULT ( STDMETHODCALLTYPE *CanCommitChanges )( ICorDebugAppDomain * This, /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError); - + DECLSPEC_XFGVIRT(ICorDebugController, CommitChanges) - HRESULT ( STDMETHODCALLTYPE *CommitChanges )( + HRESULT ( STDMETHODCALLTYPE *CommitChanges )( ICorDebugAppDomain * This, /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, GetProcess) - HRESULT ( STDMETHODCALLTYPE *GetProcess )( + HRESULT ( STDMETHODCALLTYPE *GetProcess )( ICorDebugAppDomain * This, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, EnumerateAssemblies) - HRESULT ( STDMETHODCALLTYPE *EnumerateAssemblies )( + HRESULT ( STDMETHODCALLTYPE *EnumerateAssemblies )( ICorDebugAppDomain * This, /* [out] */ ICorDebugAssemblyEnum **ppAssemblies); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, GetModuleFromMetaDataInterface) - HRESULT ( STDMETHODCALLTYPE *GetModuleFromMetaDataInterface )( + HRESULT ( STDMETHODCALLTYPE *GetModuleFromMetaDataInterface )( ICorDebugAppDomain * This, /* [in] */ IUnknown *pIMetaData, /* [out] */ ICorDebugModule **ppModule); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, EnumerateBreakpoints) - HRESULT ( STDMETHODCALLTYPE *EnumerateBreakpoints )( + HRESULT ( STDMETHODCALLTYPE *EnumerateBreakpoints )( ICorDebugAppDomain * This, /* [out] */ ICorDebugBreakpointEnum **ppBreakpoints); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, EnumerateSteppers) - HRESULT ( STDMETHODCALLTYPE *EnumerateSteppers )( + HRESULT ( STDMETHODCALLTYPE *EnumerateSteppers )( ICorDebugAppDomain * This, /* [out] */ ICorDebugStepperEnum **ppSteppers); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, IsAttached) - HRESULT ( STDMETHODCALLTYPE *IsAttached )( + HRESULT ( STDMETHODCALLTYPE *IsAttached )( ICorDebugAppDomain * This, /* [out] */ BOOL *pbAttached); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugAppDomain * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, GetObject) - HRESULT ( STDMETHODCALLTYPE *GetObject )( + HRESULT ( STDMETHODCALLTYPE *GetObject )( ICorDebugAppDomain * This, /* [out] */ ICorDebugValue **ppObject); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, Attach) - HRESULT ( STDMETHODCALLTYPE *Attach )( + HRESULT ( STDMETHODCALLTYPE *Attach )( ICorDebugAppDomain * This); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain, GetID) - HRESULT ( STDMETHODCALLTYPE *GetID )( + HRESULT ( STDMETHODCALLTYPE *GetID )( ICorDebugAppDomain * This, /* [out] */ ULONG32 *pId); - + END_INTERFACE } ICorDebugAppDomainVtbl; @@ -5429,81 +5436,81 @@ EXTERN_C const IID IID_ICorDebugAppDomain; CONST_VTBL struct ICorDebugAppDomainVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAppDomain_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAppDomain_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAppDomain_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAppDomain_Stop(This,dwTimeoutIgnored) \ - ( (This)->lpVtbl -> Stop(This,dwTimeoutIgnored) ) + ( (This)->lpVtbl -> Stop(This,dwTimeoutIgnored) ) #define ICorDebugAppDomain_Continue(This,fIsOutOfBand) \ - ( (This)->lpVtbl -> Continue(This,fIsOutOfBand) ) + ( (This)->lpVtbl -> Continue(This,fIsOutOfBand) ) #define ICorDebugAppDomain_IsRunning(This,pbRunning) \ - ( (This)->lpVtbl -> IsRunning(This,pbRunning) ) + ( (This)->lpVtbl -> IsRunning(This,pbRunning) ) #define ICorDebugAppDomain_HasQueuedCallbacks(This,pThread,pbQueued) \ - ( (This)->lpVtbl -> HasQueuedCallbacks(This,pThread,pbQueued) ) + ( (This)->lpVtbl -> HasQueuedCallbacks(This,pThread,pbQueued) ) #define ICorDebugAppDomain_EnumerateThreads(This,ppThreads) \ - ( (This)->lpVtbl -> EnumerateThreads(This,ppThreads) ) + ( (This)->lpVtbl -> EnumerateThreads(This,ppThreads) ) #define ICorDebugAppDomain_SetAllThreadsDebugState(This,state,pExceptThisThread) \ - ( (This)->lpVtbl -> SetAllThreadsDebugState(This,state,pExceptThisThread) ) + ( (This)->lpVtbl -> SetAllThreadsDebugState(This,state,pExceptThisThread) ) #define ICorDebugAppDomain_Detach(This) \ - ( (This)->lpVtbl -> Detach(This) ) + ( (This)->lpVtbl -> Detach(This) ) #define ICorDebugAppDomain_Terminate(This,exitCode) \ - ( (This)->lpVtbl -> Terminate(This,exitCode) ) + ( (This)->lpVtbl -> Terminate(This,exitCode) ) #define ICorDebugAppDomain_CanCommitChanges(This,cSnapshots,pSnapshots,pError) \ - ( (This)->lpVtbl -> CanCommitChanges(This,cSnapshots,pSnapshots,pError) ) + ( (This)->lpVtbl -> CanCommitChanges(This,cSnapshots,pSnapshots,pError) ) #define ICorDebugAppDomain_CommitChanges(This,cSnapshots,pSnapshots,pError) \ - ( (This)->lpVtbl -> CommitChanges(This,cSnapshots,pSnapshots,pError) ) + ( (This)->lpVtbl -> CommitChanges(This,cSnapshots,pSnapshots,pError) ) #define ICorDebugAppDomain_GetProcess(This,ppProcess) \ - ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) + ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) #define ICorDebugAppDomain_EnumerateAssemblies(This,ppAssemblies) \ - ( (This)->lpVtbl -> EnumerateAssemblies(This,ppAssemblies) ) + ( (This)->lpVtbl -> EnumerateAssemblies(This,ppAssemblies) ) #define ICorDebugAppDomain_GetModuleFromMetaDataInterface(This,pIMetaData,ppModule) \ - ( (This)->lpVtbl -> GetModuleFromMetaDataInterface(This,pIMetaData,ppModule) ) + ( (This)->lpVtbl -> GetModuleFromMetaDataInterface(This,pIMetaData,ppModule) ) #define ICorDebugAppDomain_EnumerateBreakpoints(This,ppBreakpoints) \ - ( (This)->lpVtbl -> EnumerateBreakpoints(This,ppBreakpoints) ) + ( (This)->lpVtbl -> EnumerateBreakpoints(This,ppBreakpoints) ) #define ICorDebugAppDomain_EnumerateSteppers(This,ppSteppers) \ - ( (This)->lpVtbl -> EnumerateSteppers(This,ppSteppers) ) + ( (This)->lpVtbl -> EnumerateSteppers(This,ppSteppers) ) #define ICorDebugAppDomain_IsAttached(This,pbAttached) \ - ( (This)->lpVtbl -> IsAttached(This,pbAttached) ) + ( (This)->lpVtbl -> IsAttached(This,pbAttached) ) #define ICorDebugAppDomain_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #define ICorDebugAppDomain_GetObject(This,ppObject) \ - ( (This)->lpVtbl -> GetObject(This,ppObject) ) + ( (This)->lpVtbl -> GetObject(This,ppObject) ) #define ICorDebugAppDomain_Attach(This) \ - ( (This)->lpVtbl -> Attach(This) ) + ( (This)->lpVtbl -> Attach(This) ) #define ICorDebugAppDomain_GetID(This,pId) \ - ( (This)->lpVtbl -> GetID(This,pId) ) + ( (This)->lpVtbl -> GetID(This,pId) ) #endif /* COBJMACROS */ @@ -5517,7 +5524,7 @@ EXTERN_C const IID IID_ICorDebugAppDomain; /* interface __MIDL_itf_cordebug_0000_0026 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -5529,67 +5536,67 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0026_v0_0_s_ifspec; #define __ICorDebugAppDomain2_INTERFACE_DEFINED__ /* interface ICorDebugAppDomain2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAppDomain2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("096E81D5-ECDA-4202-83F5-C65980A9EF75") ICorDebugAppDomain2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetArrayOrPointerType( + virtual HRESULT STDMETHODCALLTYPE GetArrayOrPointerType( /* [in] */ CorElementType elementType, /* [in] */ ULONG32 nRank, /* [in] */ ICorDebugType *pTypeArg, /* [out] */ ICorDebugType **ppType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionPointerType( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionPointerType( /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [out] */ ICorDebugType **ppType) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAppDomain2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAppDomain2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAppDomain2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAppDomain2 * This); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain2, GetArrayOrPointerType) - HRESULT ( STDMETHODCALLTYPE *GetArrayOrPointerType )( + HRESULT ( STDMETHODCALLTYPE *GetArrayOrPointerType )( ICorDebugAppDomain2 * This, /* [in] */ CorElementType elementType, /* [in] */ ULONG32 nRank, /* [in] */ ICorDebugType *pTypeArg, /* [out] */ ICorDebugType **ppType); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain2, GetFunctionPointerType) - HRESULT ( STDMETHODCALLTYPE *GetFunctionPointerType )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionPointerType )( ICorDebugAppDomain2 * This, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [out] */ ICorDebugType **ppType); - + END_INTERFACE } ICorDebugAppDomain2Vtbl; @@ -5598,26 +5605,26 @@ EXTERN_C const IID IID_ICorDebugAppDomain2; CONST_VTBL struct ICorDebugAppDomain2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAppDomain2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAppDomain2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAppDomain2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAppDomain2_GetArrayOrPointerType(This,elementType,nRank,pTypeArg,ppType) \ - ( (This)->lpVtbl -> GetArrayOrPointerType(This,elementType,nRank,pTypeArg,ppType) ) + ( (This)->lpVtbl -> GetArrayOrPointerType(This,elementType,nRank,pTypeArg,ppType) ) #define ICorDebugAppDomain2_GetFunctionPointerType(This,nTypeArgs,ppTypeArgs,ppType) \ - ( (This)->lpVtbl -> GetFunctionPointerType(This,nTypeArgs,ppTypeArgs,ppType) ) + ( (This)->lpVtbl -> GetFunctionPointerType(This,nTypeArgs,ppTypeArgs,ppType) ) #endif /* COBJMACROS */ @@ -5634,71 +5641,71 @@ EXTERN_C const IID IID_ICorDebugAppDomain2; #define __ICorDebugEnum_INTERFACE_DEFINED__ /* interface ICorDebugEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB01-8A68-11d2-983C-0000F808342D") ICorDebugEnum : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Skip( + virtual HRESULT STDMETHODCALLTYPE Skip( /* [in] */ ULONG celt) = 0; - + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( + + virtual HRESULT STDMETHODCALLTYPE Clone( /* [out] */ ICorDebugEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( + + virtual HRESULT STDMETHODCALLTYPE GetCount( /* [out] */ ULONG *pcelt) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugEnum * This, /* [out] */ ULONG *pcelt); - + END_INTERFACE } ICorDebugEnumVtbl; @@ -5707,32 +5714,32 @@ EXTERN_C const IID IID_ICorDebugEnum; CONST_VTBL struct ICorDebugEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #endif /* COBJMACROS */ @@ -5749,72 +5756,72 @@ EXTERN_C const IID IID_ICorDebugEnum; #define __ICorDebugGuidToTypeEnum_INTERFACE_DEFINED__ /* interface ICorDebugGuidToTypeEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugGuidToTypeEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("6164D242-1015-4BD6-8CBE-D0DBD4B8275A") ICorDebugGuidToTypeEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CorDebugGuidToTypeMapping values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugGuidToTypeEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugGuidToTypeEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugGuidToTypeEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugGuidToTypeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugGuidToTypeEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugGuidToTypeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugGuidToTypeEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugGuidToTypeEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugGuidToTypeEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugGuidToTypeEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CorDebugGuidToTypeMapping values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugGuidToTypeEnumVtbl; @@ -5823,36 +5830,36 @@ EXTERN_C const IID IID_ICorDebugGuidToTypeEnum; CONST_VTBL struct ICorDebugGuidToTypeEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugGuidToTypeEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugGuidToTypeEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugGuidToTypeEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugGuidToTypeEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugGuidToTypeEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugGuidToTypeEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugGuidToTypeEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugGuidToTypeEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -5869,61 +5876,61 @@ EXTERN_C const IID IID_ICorDebugGuidToTypeEnum; #define __ICorDebugAppDomain3_INTERFACE_DEFINED__ /* interface ICorDebugAppDomain3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAppDomain3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("8CB96A16-B588-42E2-B71C-DD849FC2ECCC") ICorDebugAppDomain3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetCachedWinRTTypesForIIDs( + virtual HRESULT STDMETHODCALLTYPE GetCachedWinRTTypesForIIDs( /* [in] */ ULONG32 cReqTypes, /* [size_is][in] */ GUID *iidsToResolve, /* [out] */ ICorDebugTypeEnum **ppTypesEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCachedWinRTTypes( + + virtual HRESULT STDMETHODCALLTYPE GetCachedWinRTTypes( /* [out] */ ICorDebugGuidToTypeEnum **ppGuidToTypeEnum) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAppDomain3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAppDomain3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAppDomain3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAppDomain3 * This); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain3, GetCachedWinRTTypesForIIDs) - HRESULT ( STDMETHODCALLTYPE *GetCachedWinRTTypesForIIDs )( + HRESULT ( STDMETHODCALLTYPE *GetCachedWinRTTypesForIIDs )( ICorDebugAppDomain3 * This, /* [in] */ ULONG32 cReqTypes, /* [size_is][in] */ GUID *iidsToResolve, /* [out] */ ICorDebugTypeEnum **ppTypesEnum); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain3, GetCachedWinRTTypes) - HRESULT ( STDMETHODCALLTYPE *GetCachedWinRTTypes )( + HRESULT ( STDMETHODCALLTYPE *GetCachedWinRTTypes )( ICorDebugAppDomain3 * This, /* [out] */ ICorDebugGuidToTypeEnum **ppGuidToTypeEnum); - + END_INTERFACE } ICorDebugAppDomain3Vtbl; @@ -5932,26 +5939,26 @@ EXTERN_C const IID IID_ICorDebugAppDomain3; CONST_VTBL struct ICorDebugAppDomain3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAppDomain3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAppDomain3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAppDomain3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAppDomain3_GetCachedWinRTTypesForIIDs(This,cReqTypes,iidsToResolve,ppTypesEnum) \ - ( (This)->lpVtbl -> GetCachedWinRTTypesForIIDs(This,cReqTypes,iidsToResolve,ppTypesEnum) ) + ( (This)->lpVtbl -> GetCachedWinRTTypesForIIDs(This,cReqTypes,iidsToResolve,ppTypesEnum) ) #define ICorDebugAppDomain3_GetCachedWinRTTypes(This,ppGuidToTypeEnum) \ - ( (This)->lpVtbl -> GetCachedWinRTTypes(This,ppGuidToTypeEnum) ) + ( (This)->lpVtbl -> GetCachedWinRTTypes(This,ppGuidToTypeEnum) ) #endif /* COBJMACROS */ @@ -5968,51 +5975,51 @@ EXTERN_C const IID IID_ICorDebugAppDomain3; #define __ICorDebugAppDomain4_INTERFACE_DEFINED__ /* interface ICorDebugAppDomain4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAppDomain4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("FB99CC40-83BE-4724-AB3B-768E796EBAC2") ICorDebugAppDomain4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetObjectForCCW( + virtual HRESULT STDMETHODCALLTYPE GetObjectForCCW( /* [in] */ CORDB_ADDRESS ccwPointer, /* [out] */ ICorDebugValue **ppManagedObject) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAppDomain4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAppDomain4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAppDomain4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAppDomain4 * This); - + DECLSPEC_XFGVIRT(ICorDebugAppDomain4, GetObjectForCCW) - HRESULT ( STDMETHODCALLTYPE *GetObjectForCCW )( + HRESULT ( STDMETHODCALLTYPE *GetObjectForCCW )( ICorDebugAppDomain4 * This, /* [in] */ CORDB_ADDRESS ccwPointer, /* [out] */ ICorDebugValue **ppManagedObject); - + END_INTERFACE } ICorDebugAppDomain4Vtbl; @@ -6021,23 +6028,23 @@ EXTERN_C const IID IID_ICorDebugAppDomain4; CONST_VTBL struct ICorDebugAppDomain4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAppDomain4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAppDomain4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAppDomain4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAppDomain4_GetObjectForCCW(This,ccwPointer,ppManagedObject) \ - ( (This)->lpVtbl -> GetObjectForCCW(This,ccwPointer,ppManagedObject) ) + ( (This)->lpVtbl -> GetObjectForCCW(This,ccwPointer,ppManagedObject) ) #endif /* COBJMACROS */ @@ -6051,10 +6058,10 @@ EXTERN_C const IID IID_ICorDebugAppDomain4; /* interface __MIDL_itf_cordebug_0000_0030 */ -/* [local] */ +/* [local] */ #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0030_v0_0_c_ifspec; @@ -6064,89 +6071,89 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0030_v0_0_s_ifspec; #define __ICorDebugAssembly_INTERFACE_DEFINED__ /* interface ICorDebugAssembly */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAssembly; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("df59507c-d47a-459e-bce2-6427eac8fd06") ICorDebugAssembly : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetProcess( + virtual HRESULT STDMETHODCALLTYPE GetProcess( /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAppDomain( + + virtual HRESULT STDMETHODCALLTYPE GetAppDomain( /* [out] */ ICorDebugAppDomain **ppAppDomain) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateModules( + + virtual HRESULT STDMETHODCALLTYPE EnumerateModules( /* [out] */ ICorDebugModuleEnum **ppModules) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCodeBase( + + virtual HRESULT STDMETHODCALLTYPE GetCodeBase( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetName( + + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAssemblyVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAssembly * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAssembly * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAssembly * This); - + DECLSPEC_XFGVIRT(ICorDebugAssembly, GetProcess) - HRESULT ( STDMETHODCALLTYPE *GetProcess )( + HRESULT ( STDMETHODCALLTYPE *GetProcess )( ICorDebugAssembly * This, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebugAssembly, GetAppDomain) - HRESULT ( STDMETHODCALLTYPE *GetAppDomain )( + HRESULT ( STDMETHODCALLTYPE *GetAppDomain )( ICorDebugAssembly * This, /* [out] */ ICorDebugAppDomain **ppAppDomain); - + DECLSPEC_XFGVIRT(ICorDebugAssembly, EnumerateModules) - HRESULT ( STDMETHODCALLTYPE *EnumerateModules )( + HRESULT ( STDMETHODCALLTYPE *EnumerateModules )( ICorDebugAssembly * This, /* [out] */ ICorDebugModuleEnum **ppModules); - + DECLSPEC_XFGVIRT(ICorDebugAssembly, GetCodeBase) - HRESULT ( STDMETHODCALLTYPE *GetCodeBase )( + HRESULT ( STDMETHODCALLTYPE *GetCodeBase )( ICorDebugAssembly * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugAssembly, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugAssembly * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + END_INTERFACE } ICorDebugAssemblyVtbl; @@ -6155,35 +6162,35 @@ EXTERN_C const IID IID_ICorDebugAssembly; CONST_VTBL struct ICorDebugAssemblyVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAssembly_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAssembly_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAssembly_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAssembly_GetProcess(This,ppProcess) \ - ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) + ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) #define ICorDebugAssembly_GetAppDomain(This,ppAppDomain) \ - ( (This)->lpVtbl -> GetAppDomain(This,ppAppDomain) ) + ( (This)->lpVtbl -> GetAppDomain(This,ppAppDomain) ) #define ICorDebugAssembly_EnumerateModules(This,ppModules) \ - ( (This)->lpVtbl -> EnumerateModules(This,ppModules) ) + ( (This)->lpVtbl -> EnumerateModules(This,ppModules) ) #define ICorDebugAssembly_GetCodeBase(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetCodeBase(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetCodeBase(This,cchName,pcchName,szName) ) #define ICorDebugAssembly_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #endif /* COBJMACROS */ @@ -6197,7 +6204,7 @@ EXTERN_C const IID IID_ICorDebugAssembly; /* interface __MIDL_itf_cordebug_0000_0031 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -6209,49 +6216,49 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0031_v0_0_s_ifspec; #define __ICorDebugAssembly2_INTERFACE_DEFINED__ /* interface ICorDebugAssembly2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAssembly2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("426d1f9e-6dd4-44c8-aec7-26cdbaf4e398") ICorDebugAssembly2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE IsFullyTrusted( + virtual HRESULT STDMETHODCALLTYPE IsFullyTrusted( /* [out] */ BOOL *pbFullyTrusted) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAssembly2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAssembly2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAssembly2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAssembly2 * This); - + DECLSPEC_XFGVIRT(ICorDebugAssembly2, IsFullyTrusted) - HRESULT ( STDMETHODCALLTYPE *IsFullyTrusted )( + HRESULT ( STDMETHODCALLTYPE *IsFullyTrusted )( ICorDebugAssembly2 * This, /* [out] */ BOOL *pbFullyTrusted); - + END_INTERFACE } ICorDebugAssembly2Vtbl; @@ -6260,23 +6267,23 @@ EXTERN_C const IID IID_ICorDebugAssembly2; CONST_VTBL struct ICorDebugAssembly2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAssembly2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAssembly2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAssembly2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAssembly2_IsFullyTrusted(This,pbFullyTrusted) \ - ( (This)->lpVtbl -> IsFullyTrusted(This,pbFullyTrusted) ) + ( (This)->lpVtbl -> IsFullyTrusted(This,pbFullyTrusted) ) #endif /* COBJMACROS */ @@ -6293,57 +6300,57 @@ EXTERN_C const IID IID_ICorDebugAssembly2; #define __ICorDebugAssembly3_INTERFACE_DEFINED__ /* interface ICorDebugAssembly3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAssembly3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("76361AB2-8C86-4FE9-96F2-F73D8843570A") ICorDebugAssembly3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetContainerAssembly( + virtual HRESULT STDMETHODCALLTYPE GetContainerAssembly( ICorDebugAssembly **ppAssembly) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateContainedAssemblies( + + virtual HRESULT STDMETHODCALLTYPE EnumerateContainedAssemblies( ICorDebugAssemblyEnum **ppAssemblies) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAssembly3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAssembly3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAssembly3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAssembly3 * This); - + DECLSPEC_XFGVIRT(ICorDebugAssembly3, GetContainerAssembly) - HRESULT ( STDMETHODCALLTYPE *GetContainerAssembly )( + HRESULT ( STDMETHODCALLTYPE *GetContainerAssembly )( ICorDebugAssembly3 * This, ICorDebugAssembly **ppAssembly); - + DECLSPEC_XFGVIRT(ICorDebugAssembly3, EnumerateContainedAssemblies) - HRESULT ( STDMETHODCALLTYPE *EnumerateContainedAssemblies )( + HRESULT ( STDMETHODCALLTYPE *EnumerateContainedAssemblies )( ICorDebugAssembly3 * This, ICorDebugAssemblyEnum **ppAssemblies); - + END_INTERFACE } ICorDebugAssembly3Vtbl; @@ -6352,26 +6359,26 @@ EXTERN_C const IID IID_ICorDebugAssembly3; CONST_VTBL struct ICorDebugAssembly3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAssembly3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAssembly3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAssembly3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAssembly3_GetContainerAssembly(This,ppAssembly) \ - ( (This)->lpVtbl -> GetContainerAssembly(This,ppAssembly) ) + ( (This)->lpVtbl -> GetContainerAssembly(This,ppAssembly) ) #define ICorDebugAssembly3_EnumerateContainedAssemblies(This,ppAssemblies) \ - ( (This)->lpVtbl -> EnumerateContainedAssemblies(This,ppAssemblies) ) + ( (This)->lpVtbl -> EnumerateContainedAssemblies(This,ppAssemblies) ) #endif /* COBJMACROS */ @@ -6385,7 +6392,7 @@ EXTERN_C const IID IID_ICorDebugAssembly3; /* interface __MIDL_itf_cordebug_0000_0033 */ -/* [local] */ +/* [local] */ #ifndef _DEF_COR_TYPEID_ #define _DEF_COR_TYPEID_ @@ -6412,72 +6419,72 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0033_v0_0_s_ifspec; #define __ICorDebugHeapEnum_INTERFACE_DEFINED__ /* interface ICorDebugHeapEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugHeapEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("76D7DAB8-D044-11DF-9A15-7E29DFD72085") ICorDebugHeapEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_HEAPOBJECT objects[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugHeapEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugHeapEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugHeapEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugHeapEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugHeapEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugHeapEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugHeapEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugHeapEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugHeapEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugHeapEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_HEAPOBJECT objects[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugHeapEnumVtbl; @@ -6486,36 +6493,36 @@ EXTERN_C const IID IID_ICorDebugHeapEnum; CONST_VTBL struct ICorDebugHeapEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugHeapEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugHeapEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugHeapEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugHeapEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugHeapEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugHeapEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugHeapEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugHeapEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) #endif /* COBJMACROS */ @@ -6529,9 +6536,9 @@ EXTERN_C const IID IID_ICorDebugHeapEnum; /* interface __MIDL_itf_cordebug_0000_0034 */ -/* [local] */ +/* [local] */ -typedef +typedef enum CorDebugGenerationTypes { CorDebug_Gen0 = 0, @@ -6550,11 +6557,11 @@ typedef struct _COR_SEGMENT ULONG heap; } COR_SEGMENT; -typedef +typedef enum CorDebugGCType { CorDebugWorkstationGC = 0, - CorDebugServerGC = ( CorDebugWorkstationGC + 1 ) + CorDebugServerGC = ( CorDebugWorkstationGC + 1 ) } CorDebugGCType; typedef struct _COR_HEAPINFO @@ -6575,72 +6582,72 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0034_v0_0_s_ifspec; #define __ICorDebugHeapSegmentEnum_INTERFACE_DEFINED__ /* interface ICorDebugHeapSegmentEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugHeapSegmentEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("A2FA0F8E-D045-11DF-AC8E-CE2ADFD72085") ICorDebugHeapSegmentEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_SEGMENT segments[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugHeapSegmentEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugHeapSegmentEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugHeapSegmentEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugHeapSegmentEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugHeapSegmentEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugHeapSegmentEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugHeapSegmentEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugHeapSegmentEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugHeapSegmentEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugHeapSegmentEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_SEGMENT segments[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugHeapSegmentEnumVtbl; @@ -6649,36 +6656,36 @@ EXTERN_C const IID IID_ICorDebugHeapSegmentEnum; CONST_VTBL struct ICorDebugHeapSegmentEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugHeapSegmentEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugHeapSegmentEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugHeapSegmentEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugHeapSegmentEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugHeapSegmentEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugHeapSegmentEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugHeapSegmentEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugHeapSegmentEnum_Next(This,celt,segments,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,segments,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,segments,pceltFetched) ) #endif /* COBJMACROS */ @@ -6692,9 +6699,9 @@ EXTERN_C const IID IID_ICorDebugHeapSegmentEnum; /* interface __MIDL_itf_cordebug_0000_0035 */ -/* [local] */ +/* [local] */ -typedef +typedef enum CorGCReferenceType { CorHandleStrong = ( 1 << 0 ) , @@ -6735,72 +6742,72 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0035_v0_0_s_ifspec; #define __ICorDebugGCReferenceEnum_INTERFACE_DEFINED__ /* interface ICorDebugGCReferenceEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugGCReferenceEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("7F3C24D3-7E1D-4245-AC3A-F72F8859C80C") ICorDebugGCReferenceEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_GC_REFERENCE roots[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugGCReferenceEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugGCReferenceEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugGCReferenceEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugGCReferenceEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugGCReferenceEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugGCReferenceEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugGCReferenceEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugGCReferenceEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugGCReferenceEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugGCReferenceEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_GC_REFERENCE roots[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugGCReferenceEnumVtbl; @@ -6809,36 +6816,36 @@ EXTERN_C const IID IID_ICorDebugGCReferenceEnum; CONST_VTBL struct ICorDebugGCReferenceEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugGCReferenceEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugGCReferenceEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugGCReferenceEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugGCReferenceEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugGCReferenceEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugGCReferenceEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugGCReferenceEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugGCReferenceEnum_Next(This,celt,roots,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,roots,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,roots,pceltFetched) ) #endif /* COBJMACROS */ @@ -6852,7 +6859,7 @@ EXTERN_C const IID IID_ICorDebugGCReferenceEnum; /* interface __MIDL_itf_cordebug_0000_0036 */ -/* [local] */ +/* [local] */ #ifndef _DEF_COR_ARRAY_LAYOUT_ #define _DEF_COR_ARRAY_LAYOUT_ @@ -6893,7 +6900,7 @@ typedef struct COR_FIELD #endif // _DEF_COR_FIELD_ #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0036_v0_0_c_ifspec; @@ -6903,264 +6910,264 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0036_v0_0_s_ifspec; #define __ICorDebugProcess_INTERFACE_DEFINED__ /* interface ICorDebugProcess */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("3d6f5f64-7538-11d3-8d5b-00104b35e7ef") ICorDebugProcess : public ICorDebugController { public: - virtual HRESULT STDMETHODCALLTYPE GetID( + virtual HRESULT STDMETHODCALLTYPE GetID( /* [out] */ DWORD *pdwProcessId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetHandle( + + virtual HRESULT STDMETHODCALLTYPE GetHandle( /* [out] */ HPROCESS *phProcessHandle) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThread( + + virtual HRESULT STDMETHODCALLTYPE GetThread( /* [in] */ DWORD dwThreadId, /* [out] */ ICorDebugThread **ppThread) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateObjects( + + virtual HRESULT STDMETHODCALLTYPE EnumerateObjects( /* [out] */ ICorDebugObjectEnum **ppObjects) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsTransitionStub( + + virtual HRESULT STDMETHODCALLTYPE IsTransitionStub( /* [in] */ CORDB_ADDRESS address, /* [out] */ BOOL *pbTransitionStub) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsOSSuspended( + + virtual HRESULT STDMETHODCALLTYPE IsOSSuspended( /* [in] */ DWORD threadID, /* [out] */ BOOL *pbSuspended) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadContext( + + virtual HRESULT STDMETHODCALLTYPE GetThreadContext( /* [in] */ DWORD threadID, /* [in] */ ULONG32 contextSize, /* [size_is][length_is][out][in] */ BYTE context[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetThreadContext( + + virtual HRESULT STDMETHODCALLTYPE SetThreadContext( /* [in] */ DWORD threadID, /* [in] */ ULONG32 contextSize, /* [size_is][length_is][in] */ BYTE context[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE ReadMemory( + + virtual HRESULT STDMETHODCALLTYPE ReadMemory( /* [in] */ CORDB_ADDRESS address, /* [in] */ DWORD size, /* [length_is][size_is][out] */ BYTE buffer[ ], /* [out] */ SIZE_T *read) = 0; - - virtual HRESULT STDMETHODCALLTYPE WriteMemory( + + virtual HRESULT STDMETHODCALLTYPE WriteMemory( /* [in] */ CORDB_ADDRESS address, /* [in] */ DWORD size, /* [size_is][in] */ BYTE buffer[ ], /* [out] */ SIZE_T *written) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClearCurrentException( + + virtual HRESULT STDMETHODCALLTYPE ClearCurrentException( /* [in] */ DWORD threadID) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnableLogMessages( + + virtual HRESULT STDMETHODCALLTYPE EnableLogMessages( /* [in] */ BOOL fOnOff) = 0; - - virtual HRESULT STDMETHODCALLTYPE ModifyLogSwitch( - /* [annotation][in] */ + + virtual HRESULT STDMETHODCALLTYPE ModifyLogSwitch( + /* [annotation][in] */ _In_ WCHAR *pLogSwitchName, /* [in] */ LONG lLevel) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateAppDomains( + + virtual HRESULT STDMETHODCALLTYPE EnumerateAppDomains( /* [out] */ ICorDebugAppDomainEnum **ppAppDomains) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObject( + + virtual HRESULT STDMETHODCALLTYPE GetObject( /* [out] */ ICorDebugValue **ppObject) = 0; - - virtual HRESULT STDMETHODCALLTYPE ThreadForFiberCookie( + + virtual HRESULT STDMETHODCALLTYPE ThreadForFiberCookie( /* [in] */ DWORD fiberCookie, /* [out] */ ICorDebugThread **ppThread) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetHelperThreadID( + + virtual HRESULT STDMETHODCALLTYPE GetHelperThreadID( /* [out] */ DWORD *pThreadID) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcessVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess * This); - + DECLSPEC_XFGVIRT(ICorDebugController, Stop) - HRESULT ( STDMETHODCALLTYPE *Stop )( + HRESULT ( STDMETHODCALLTYPE *Stop )( ICorDebugProcess * This, /* [in] */ DWORD dwTimeoutIgnored); - + DECLSPEC_XFGVIRT(ICorDebugController, Continue) - HRESULT ( STDMETHODCALLTYPE *Continue )( + HRESULT ( STDMETHODCALLTYPE *Continue )( ICorDebugProcess * This, /* [in] */ BOOL fIsOutOfBand); - + DECLSPEC_XFGVIRT(ICorDebugController, IsRunning) - HRESULT ( STDMETHODCALLTYPE *IsRunning )( + HRESULT ( STDMETHODCALLTYPE *IsRunning )( ICorDebugProcess * This, /* [out] */ BOOL *pbRunning); - + DECLSPEC_XFGVIRT(ICorDebugController, HasQueuedCallbacks) - HRESULT ( STDMETHODCALLTYPE *HasQueuedCallbacks )( + HRESULT ( STDMETHODCALLTYPE *HasQueuedCallbacks )( ICorDebugProcess * This, /* [in] */ ICorDebugThread *pThread, /* [out] */ BOOL *pbQueued); - + DECLSPEC_XFGVIRT(ICorDebugController, EnumerateThreads) - HRESULT ( STDMETHODCALLTYPE *EnumerateThreads )( + HRESULT ( STDMETHODCALLTYPE *EnumerateThreads )( ICorDebugProcess * This, /* [out] */ ICorDebugThreadEnum **ppThreads); - + DECLSPEC_XFGVIRT(ICorDebugController, SetAllThreadsDebugState) - HRESULT ( STDMETHODCALLTYPE *SetAllThreadsDebugState )( + HRESULT ( STDMETHODCALLTYPE *SetAllThreadsDebugState )( ICorDebugProcess * This, /* [in] */ CorDebugThreadState state, /* [in] */ ICorDebugThread *pExceptThisThread); - + DECLSPEC_XFGVIRT(ICorDebugController, Detach) - HRESULT ( STDMETHODCALLTYPE *Detach )( + HRESULT ( STDMETHODCALLTYPE *Detach )( ICorDebugProcess * This); - + DECLSPEC_XFGVIRT(ICorDebugController, Terminate) - HRESULT ( STDMETHODCALLTYPE *Terminate )( + HRESULT ( STDMETHODCALLTYPE *Terminate )( ICorDebugProcess * This, /* [in] */ UINT exitCode); - + DECLSPEC_XFGVIRT(ICorDebugController, CanCommitChanges) - HRESULT ( STDMETHODCALLTYPE *CanCommitChanges )( + HRESULT ( STDMETHODCALLTYPE *CanCommitChanges )( ICorDebugProcess * This, /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError); - + DECLSPEC_XFGVIRT(ICorDebugController, CommitChanges) - HRESULT ( STDMETHODCALLTYPE *CommitChanges )( + HRESULT ( STDMETHODCALLTYPE *CommitChanges )( ICorDebugProcess * This, /* [in] */ ULONG cSnapshots, /* [size_is][in] */ ICorDebugEditAndContinueSnapshot *pSnapshots[ ], /* [out] */ ICorDebugErrorInfoEnum **pError); - + DECLSPEC_XFGVIRT(ICorDebugProcess, GetID) - HRESULT ( STDMETHODCALLTYPE *GetID )( + HRESULT ( STDMETHODCALLTYPE *GetID )( ICorDebugProcess * This, /* [out] */ DWORD *pdwProcessId); - + DECLSPEC_XFGVIRT(ICorDebugProcess, GetHandle) - HRESULT ( STDMETHODCALLTYPE *GetHandle )( + HRESULT ( STDMETHODCALLTYPE *GetHandle )( ICorDebugProcess * This, /* [out] */ HPROCESS *phProcessHandle); - + DECLSPEC_XFGVIRT(ICorDebugProcess, GetThread) - HRESULT ( STDMETHODCALLTYPE *GetThread )( + HRESULT ( STDMETHODCALLTYPE *GetThread )( ICorDebugProcess * This, /* [in] */ DWORD dwThreadId, /* [out] */ ICorDebugThread **ppThread); - + DECLSPEC_XFGVIRT(ICorDebugProcess, EnumerateObjects) - HRESULT ( STDMETHODCALLTYPE *EnumerateObjects )( + HRESULT ( STDMETHODCALLTYPE *EnumerateObjects )( ICorDebugProcess * This, /* [out] */ ICorDebugObjectEnum **ppObjects); - + DECLSPEC_XFGVIRT(ICorDebugProcess, IsTransitionStub) - HRESULT ( STDMETHODCALLTYPE *IsTransitionStub )( + HRESULT ( STDMETHODCALLTYPE *IsTransitionStub )( ICorDebugProcess * This, /* [in] */ CORDB_ADDRESS address, /* [out] */ BOOL *pbTransitionStub); - + DECLSPEC_XFGVIRT(ICorDebugProcess, IsOSSuspended) - HRESULT ( STDMETHODCALLTYPE *IsOSSuspended )( + HRESULT ( STDMETHODCALLTYPE *IsOSSuspended )( ICorDebugProcess * This, /* [in] */ DWORD threadID, /* [out] */ BOOL *pbSuspended); - + DECLSPEC_XFGVIRT(ICorDebugProcess, GetThreadContext) - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorDebugProcess * This, /* [in] */ DWORD threadID, /* [in] */ ULONG32 contextSize, /* [size_is][length_is][out][in] */ BYTE context[ ]); - + DECLSPEC_XFGVIRT(ICorDebugProcess, SetThreadContext) - HRESULT ( STDMETHODCALLTYPE *SetThreadContext )( + HRESULT ( STDMETHODCALLTYPE *SetThreadContext )( ICorDebugProcess * This, /* [in] */ DWORD threadID, /* [in] */ ULONG32 contextSize, /* [size_is][length_is][in] */ BYTE context[ ]); - + DECLSPEC_XFGVIRT(ICorDebugProcess, ReadMemory) - HRESULT ( STDMETHODCALLTYPE *ReadMemory )( + HRESULT ( STDMETHODCALLTYPE *ReadMemory )( ICorDebugProcess * This, /* [in] */ CORDB_ADDRESS address, /* [in] */ DWORD size, /* [length_is][size_is][out] */ BYTE buffer[ ], /* [out] */ SIZE_T *read); - + DECLSPEC_XFGVIRT(ICorDebugProcess, WriteMemory) - HRESULT ( STDMETHODCALLTYPE *WriteMemory )( + HRESULT ( STDMETHODCALLTYPE *WriteMemory )( ICorDebugProcess * This, /* [in] */ CORDB_ADDRESS address, /* [in] */ DWORD size, /* [size_is][in] */ BYTE buffer[ ], /* [out] */ SIZE_T *written); - + DECLSPEC_XFGVIRT(ICorDebugProcess, ClearCurrentException) - HRESULT ( STDMETHODCALLTYPE *ClearCurrentException )( + HRESULT ( STDMETHODCALLTYPE *ClearCurrentException )( ICorDebugProcess * This, /* [in] */ DWORD threadID); - + DECLSPEC_XFGVIRT(ICorDebugProcess, EnableLogMessages) - HRESULT ( STDMETHODCALLTYPE *EnableLogMessages )( + HRESULT ( STDMETHODCALLTYPE *EnableLogMessages )( ICorDebugProcess * This, /* [in] */ BOOL fOnOff); - + DECLSPEC_XFGVIRT(ICorDebugProcess, ModifyLogSwitch) - HRESULT ( STDMETHODCALLTYPE *ModifyLogSwitch )( + HRESULT ( STDMETHODCALLTYPE *ModifyLogSwitch )( ICorDebugProcess * This, - /* [annotation][in] */ + /* [annotation][in] */ _In_ WCHAR *pLogSwitchName, /* [in] */ LONG lLevel); - + DECLSPEC_XFGVIRT(ICorDebugProcess, EnumerateAppDomains) - HRESULT ( STDMETHODCALLTYPE *EnumerateAppDomains )( + HRESULT ( STDMETHODCALLTYPE *EnumerateAppDomains )( ICorDebugProcess * This, /* [out] */ ICorDebugAppDomainEnum **ppAppDomains); - + DECLSPEC_XFGVIRT(ICorDebugProcess, GetObject) - HRESULT ( STDMETHODCALLTYPE *GetObject )( + HRESULT ( STDMETHODCALLTYPE *GetObject )( ICorDebugProcess * This, /* [out] */ ICorDebugValue **ppObject); - + DECLSPEC_XFGVIRT(ICorDebugProcess, ThreadForFiberCookie) - HRESULT ( STDMETHODCALLTYPE *ThreadForFiberCookie )( + HRESULT ( STDMETHODCALLTYPE *ThreadForFiberCookie )( ICorDebugProcess * This, /* [in] */ DWORD fiberCookie, /* [out] */ ICorDebugThread **ppThread); - + DECLSPEC_XFGVIRT(ICorDebugProcess, GetHelperThreadID) - HRESULT ( STDMETHODCALLTYPE *GetHelperThreadID )( + HRESULT ( STDMETHODCALLTYPE *GetHelperThreadID )( ICorDebugProcess * This, /* [out] */ DWORD *pThreadID); - + END_INTERFACE } ICorDebugProcessVtbl; @@ -7169,102 +7176,102 @@ EXTERN_C const IID IID_ICorDebugProcess; CONST_VTBL struct ICorDebugProcessVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess_Stop(This,dwTimeoutIgnored) \ - ( (This)->lpVtbl -> Stop(This,dwTimeoutIgnored) ) + ( (This)->lpVtbl -> Stop(This,dwTimeoutIgnored) ) #define ICorDebugProcess_Continue(This,fIsOutOfBand) \ - ( (This)->lpVtbl -> Continue(This,fIsOutOfBand) ) + ( (This)->lpVtbl -> Continue(This,fIsOutOfBand) ) #define ICorDebugProcess_IsRunning(This,pbRunning) \ - ( (This)->lpVtbl -> IsRunning(This,pbRunning) ) + ( (This)->lpVtbl -> IsRunning(This,pbRunning) ) #define ICorDebugProcess_HasQueuedCallbacks(This,pThread,pbQueued) \ - ( (This)->lpVtbl -> HasQueuedCallbacks(This,pThread,pbQueued) ) + ( (This)->lpVtbl -> HasQueuedCallbacks(This,pThread,pbQueued) ) #define ICorDebugProcess_EnumerateThreads(This,ppThreads) \ - ( (This)->lpVtbl -> EnumerateThreads(This,ppThreads) ) + ( (This)->lpVtbl -> EnumerateThreads(This,ppThreads) ) #define ICorDebugProcess_SetAllThreadsDebugState(This,state,pExceptThisThread) \ - ( (This)->lpVtbl -> SetAllThreadsDebugState(This,state,pExceptThisThread) ) + ( (This)->lpVtbl -> SetAllThreadsDebugState(This,state,pExceptThisThread) ) #define ICorDebugProcess_Detach(This) \ - ( (This)->lpVtbl -> Detach(This) ) + ( (This)->lpVtbl -> Detach(This) ) #define ICorDebugProcess_Terminate(This,exitCode) \ - ( (This)->lpVtbl -> Terminate(This,exitCode) ) + ( (This)->lpVtbl -> Terminate(This,exitCode) ) #define ICorDebugProcess_CanCommitChanges(This,cSnapshots,pSnapshots,pError) \ - ( (This)->lpVtbl -> CanCommitChanges(This,cSnapshots,pSnapshots,pError) ) + ( (This)->lpVtbl -> CanCommitChanges(This,cSnapshots,pSnapshots,pError) ) #define ICorDebugProcess_CommitChanges(This,cSnapshots,pSnapshots,pError) \ - ( (This)->lpVtbl -> CommitChanges(This,cSnapshots,pSnapshots,pError) ) + ( (This)->lpVtbl -> CommitChanges(This,cSnapshots,pSnapshots,pError) ) #define ICorDebugProcess_GetID(This,pdwProcessId) \ - ( (This)->lpVtbl -> GetID(This,pdwProcessId) ) + ( (This)->lpVtbl -> GetID(This,pdwProcessId) ) #define ICorDebugProcess_GetHandle(This,phProcessHandle) \ - ( (This)->lpVtbl -> GetHandle(This,phProcessHandle) ) + ( (This)->lpVtbl -> GetHandle(This,phProcessHandle) ) #define ICorDebugProcess_GetThread(This,dwThreadId,ppThread) \ - ( (This)->lpVtbl -> GetThread(This,dwThreadId,ppThread) ) + ( (This)->lpVtbl -> GetThread(This,dwThreadId,ppThread) ) #define ICorDebugProcess_EnumerateObjects(This,ppObjects) \ - ( (This)->lpVtbl -> EnumerateObjects(This,ppObjects) ) + ( (This)->lpVtbl -> EnumerateObjects(This,ppObjects) ) #define ICorDebugProcess_IsTransitionStub(This,address,pbTransitionStub) \ - ( (This)->lpVtbl -> IsTransitionStub(This,address,pbTransitionStub) ) + ( (This)->lpVtbl -> IsTransitionStub(This,address,pbTransitionStub) ) #define ICorDebugProcess_IsOSSuspended(This,threadID,pbSuspended) \ - ( (This)->lpVtbl -> IsOSSuspended(This,threadID,pbSuspended) ) + ( (This)->lpVtbl -> IsOSSuspended(This,threadID,pbSuspended) ) #define ICorDebugProcess_GetThreadContext(This,threadID,contextSize,context) \ - ( (This)->lpVtbl -> GetThreadContext(This,threadID,contextSize,context) ) + ( (This)->lpVtbl -> GetThreadContext(This,threadID,contextSize,context) ) #define ICorDebugProcess_SetThreadContext(This,threadID,contextSize,context) \ - ( (This)->lpVtbl -> SetThreadContext(This,threadID,contextSize,context) ) + ( (This)->lpVtbl -> SetThreadContext(This,threadID,contextSize,context) ) #define ICorDebugProcess_ReadMemory(This,address,size,buffer,read) \ - ( (This)->lpVtbl -> ReadMemory(This,address,size,buffer,read) ) + ( (This)->lpVtbl -> ReadMemory(This,address,size,buffer,read) ) #define ICorDebugProcess_WriteMemory(This,address,size,buffer,written) \ - ( (This)->lpVtbl -> WriteMemory(This,address,size,buffer,written) ) + ( (This)->lpVtbl -> WriteMemory(This,address,size,buffer,written) ) #define ICorDebugProcess_ClearCurrentException(This,threadID) \ - ( (This)->lpVtbl -> ClearCurrentException(This,threadID) ) + ( (This)->lpVtbl -> ClearCurrentException(This,threadID) ) #define ICorDebugProcess_EnableLogMessages(This,fOnOff) \ - ( (This)->lpVtbl -> EnableLogMessages(This,fOnOff) ) + ( (This)->lpVtbl -> EnableLogMessages(This,fOnOff) ) #define ICorDebugProcess_ModifyLogSwitch(This,pLogSwitchName,lLevel) \ - ( (This)->lpVtbl -> ModifyLogSwitch(This,pLogSwitchName,lLevel) ) + ( (This)->lpVtbl -> ModifyLogSwitch(This,pLogSwitchName,lLevel) ) #define ICorDebugProcess_EnumerateAppDomains(This,ppAppDomains) \ - ( (This)->lpVtbl -> EnumerateAppDomains(This,ppAppDomains) ) + ( (This)->lpVtbl -> EnumerateAppDomains(This,ppAppDomains) ) #define ICorDebugProcess_GetObject(This,ppObject) \ - ( (This)->lpVtbl -> GetObject(This,ppObject) ) + ( (This)->lpVtbl -> GetObject(This,ppObject) ) #define ICorDebugProcess_ThreadForFiberCookie(This,fiberCookie,ppThread) \ - ( (This)->lpVtbl -> ThreadForFiberCookie(This,fiberCookie,ppThread) ) + ( (This)->lpVtbl -> ThreadForFiberCookie(This,fiberCookie,ppThread) ) #define ICorDebugProcess_GetHelperThreadID(This,pThreadID) \ - ( (This)->lpVtbl -> GetHelperThreadID(This,pThreadID) ) + ( (This)->lpVtbl -> GetHelperThreadID(This,pThreadID) ) #endif /* COBJMACROS */ @@ -7278,7 +7285,7 @@ EXTERN_C const IID IID_ICorDebugProcess; /* interface __MIDL_itf_cordebug_0000_0037 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -7290,107 +7297,107 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0037_v0_0_s_ifspec; #define __ICorDebugProcess2_INTERFACE_DEFINED__ /* interface ICorDebugProcess2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("AD1B3588-0EF0-4744-A496-AA09A9F80371") ICorDebugProcess2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetThreadForTaskID( + virtual HRESULT STDMETHODCALLTYPE GetThreadForTaskID( /* [in] */ TASKID taskid, /* [out] */ ICorDebugThread2 **ppThread) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetVersion( + + virtual HRESULT STDMETHODCALLTYPE GetVersion( /* [out] */ COR_VERSION *version) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetUnmanagedBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE SetUnmanagedBreakpoint( /* [in] */ CORDB_ADDRESS address, /* [in] */ ULONG32 bufsize, /* [length_is][size_is][out] */ BYTE buffer[ ], /* [out] */ ULONG32 *bufLen) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClearUnmanagedBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE ClearUnmanagedBreakpoint( /* [in] */ CORDB_ADDRESS address) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetDesiredNGENCompilerFlags( + + virtual HRESULT STDMETHODCALLTYPE SetDesiredNGENCompilerFlags( /* [in] */ DWORD pdwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDesiredNGENCompilerFlags( + + virtual HRESULT STDMETHODCALLTYPE GetDesiredNGENCompilerFlags( /* [out] */ DWORD *pdwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetReferenceValueFromGCHandle( + + virtual HRESULT STDMETHODCALLTYPE GetReferenceValueFromGCHandle( /* [in] */ UINT_PTR handle, /* [out] */ ICorDebugReferenceValue **pOutValue) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess2 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess2, GetThreadForTaskID) - HRESULT ( STDMETHODCALLTYPE *GetThreadForTaskID )( + HRESULT ( STDMETHODCALLTYPE *GetThreadForTaskID )( ICorDebugProcess2 * This, /* [in] */ TASKID taskid, /* [out] */ ICorDebugThread2 **ppThread); - + DECLSPEC_XFGVIRT(ICorDebugProcess2, GetVersion) - HRESULT ( STDMETHODCALLTYPE *GetVersion )( + HRESULT ( STDMETHODCALLTYPE *GetVersion )( ICorDebugProcess2 * This, /* [out] */ COR_VERSION *version); - + DECLSPEC_XFGVIRT(ICorDebugProcess2, SetUnmanagedBreakpoint) - HRESULT ( STDMETHODCALLTYPE *SetUnmanagedBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *SetUnmanagedBreakpoint )( ICorDebugProcess2 * This, /* [in] */ CORDB_ADDRESS address, /* [in] */ ULONG32 bufsize, /* [length_is][size_is][out] */ BYTE buffer[ ], /* [out] */ ULONG32 *bufLen); - + DECLSPEC_XFGVIRT(ICorDebugProcess2, ClearUnmanagedBreakpoint) - HRESULT ( STDMETHODCALLTYPE *ClearUnmanagedBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *ClearUnmanagedBreakpoint )( ICorDebugProcess2 * This, /* [in] */ CORDB_ADDRESS address); - + DECLSPEC_XFGVIRT(ICorDebugProcess2, SetDesiredNGENCompilerFlags) - HRESULT ( STDMETHODCALLTYPE *SetDesiredNGENCompilerFlags )( + HRESULT ( STDMETHODCALLTYPE *SetDesiredNGENCompilerFlags )( ICorDebugProcess2 * This, /* [in] */ DWORD pdwFlags); - + DECLSPEC_XFGVIRT(ICorDebugProcess2, GetDesiredNGENCompilerFlags) - HRESULT ( STDMETHODCALLTYPE *GetDesiredNGENCompilerFlags )( + HRESULT ( STDMETHODCALLTYPE *GetDesiredNGENCompilerFlags )( ICorDebugProcess2 * This, /* [out] */ DWORD *pdwFlags); - + DECLSPEC_XFGVIRT(ICorDebugProcess2, GetReferenceValueFromGCHandle) - HRESULT ( STDMETHODCALLTYPE *GetReferenceValueFromGCHandle )( + HRESULT ( STDMETHODCALLTYPE *GetReferenceValueFromGCHandle )( ICorDebugProcess2 * This, /* [in] */ UINT_PTR handle, /* [out] */ ICorDebugReferenceValue **pOutValue); - + END_INTERFACE } ICorDebugProcess2Vtbl; @@ -7399,41 +7406,41 @@ EXTERN_C const IID IID_ICorDebugProcess2; CONST_VTBL struct ICorDebugProcess2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess2_GetThreadForTaskID(This,taskid,ppThread) \ - ( (This)->lpVtbl -> GetThreadForTaskID(This,taskid,ppThread) ) + ( (This)->lpVtbl -> GetThreadForTaskID(This,taskid,ppThread) ) #define ICorDebugProcess2_GetVersion(This,version) \ - ( (This)->lpVtbl -> GetVersion(This,version) ) + ( (This)->lpVtbl -> GetVersion(This,version) ) #define ICorDebugProcess2_SetUnmanagedBreakpoint(This,address,bufsize,buffer,bufLen) \ - ( (This)->lpVtbl -> SetUnmanagedBreakpoint(This,address,bufsize,buffer,bufLen) ) + ( (This)->lpVtbl -> SetUnmanagedBreakpoint(This,address,bufsize,buffer,bufLen) ) #define ICorDebugProcess2_ClearUnmanagedBreakpoint(This,address) \ - ( (This)->lpVtbl -> ClearUnmanagedBreakpoint(This,address) ) + ( (This)->lpVtbl -> ClearUnmanagedBreakpoint(This,address) ) #define ICorDebugProcess2_SetDesiredNGENCompilerFlags(This,pdwFlags) \ - ( (This)->lpVtbl -> SetDesiredNGENCompilerFlags(This,pdwFlags) ) + ( (This)->lpVtbl -> SetDesiredNGENCompilerFlags(This,pdwFlags) ) #define ICorDebugProcess2_GetDesiredNGENCompilerFlags(This,pdwFlags) \ - ( (This)->lpVtbl -> GetDesiredNGENCompilerFlags(This,pdwFlags) ) + ( (This)->lpVtbl -> GetDesiredNGENCompilerFlags(This,pdwFlags) ) #define ICorDebugProcess2_GetReferenceValueFromGCHandle(This,handle,pOutValue) \ - ( (This)->lpVtbl -> GetReferenceValueFromGCHandle(This,handle,pOutValue) ) + ( (This)->lpVtbl -> GetReferenceValueFromGCHandle(This,handle,pOutValue) ) #endif /* COBJMACROS */ @@ -7450,51 +7457,51 @@ EXTERN_C const IID IID_ICorDebugProcess2; #define __ICorDebugProcess3_INTERFACE_DEFINED__ /* interface ICorDebugProcess3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("2EE06488-C0D4-42B1-B26D-F3795EF606FB") ICorDebugProcess3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE SetEnableCustomNotification( + virtual HRESULT STDMETHODCALLTYPE SetEnableCustomNotification( ICorDebugClass *pClass, BOOL fEnable) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess3 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess3, SetEnableCustomNotification) - HRESULT ( STDMETHODCALLTYPE *SetEnableCustomNotification )( + HRESULT ( STDMETHODCALLTYPE *SetEnableCustomNotification )( ICorDebugProcess3 * This, ICorDebugClass *pClass, BOOL fEnable); - + END_INTERFACE } ICorDebugProcess3Vtbl; @@ -7503,23 +7510,23 @@ EXTERN_C const IID IID_ICorDebugProcess3; CONST_VTBL struct ICorDebugProcess3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess3_SetEnableCustomNotification(This,pClass,fEnable) \ - ( (This)->lpVtbl -> SetEnableCustomNotification(This,pClass,fEnable) ) + ( (This)->lpVtbl -> SetEnableCustomNotification(This,pClass,fEnable) ) #endif /* COBJMACROS */ @@ -7536,157 +7543,157 @@ EXTERN_C const IID IID_ICorDebugProcess3; #define __ICorDebugProcess5_INTERFACE_DEFINED__ /* interface ICorDebugProcess5 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess5; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("21e9d9c0-fcb8-11df-8cff-0800200c9a66") ICorDebugProcess5 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetGCHeapInformation( + virtual HRESULT STDMETHODCALLTYPE GetGCHeapInformation( /* [out] */ COR_HEAPINFO *pHeapInfo) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateHeap( + + virtual HRESULT STDMETHODCALLTYPE EnumerateHeap( /* [out] */ ICorDebugHeapEnum **ppObjects) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateHeapRegions( + + virtual HRESULT STDMETHODCALLTYPE EnumerateHeapRegions( /* [out] */ ICorDebugHeapSegmentEnum **ppRegions) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObject( + + virtual HRESULT STDMETHODCALLTYPE GetObject( /* [in] */ CORDB_ADDRESS addr, /* [out] */ ICorDebugObjectValue **pObject) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateGCReferences( + + virtual HRESULT STDMETHODCALLTYPE EnumerateGCReferences( /* [in] */ BOOL enumerateWeakReferences, /* [out] */ ICorDebugGCReferenceEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateHandles( + + virtual HRESULT STDMETHODCALLTYPE EnumerateHandles( /* [in] */ CorGCReferenceType types, /* [out] */ ICorDebugGCReferenceEnum **ppEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTypeID( + + virtual HRESULT STDMETHODCALLTYPE GetTypeID( /* [in] */ CORDB_ADDRESS obj, /* [out] */ COR_TYPEID *pId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTypeForTypeID( + + virtual HRESULT STDMETHODCALLTYPE GetTypeForTypeID( /* [in] */ COR_TYPEID id, /* [out] */ ICorDebugType **ppType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetArrayLayout( + + virtual HRESULT STDMETHODCALLTYPE GetArrayLayout( /* [in] */ COR_TYPEID id, /* [out] */ COR_ARRAY_LAYOUT *pLayout) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTypeLayout( + + virtual HRESULT STDMETHODCALLTYPE GetTypeLayout( /* [in] */ COR_TYPEID id, /* [out] */ COR_TYPE_LAYOUT *pLayout) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTypeFields( + + virtual HRESULT STDMETHODCALLTYPE GetTypeFields( /* [in] */ COR_TYPEID id, ULONG32 celt, COR_FIELD fields[ ], ULONG32 *pceltNeeded) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnableNGENPolicy( + + virtual HRESULT STDMETHODCALLTYPE EnableNGENPolicy( /* [in] */ CorDebugNGENPolicy ePolicy) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess5Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess5 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess5 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess5 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, GetGCHeapInformation) - HRESULT ( STDMETHODCALLTYPE *GetGCHeapInformation )( + HRESULT ( STDMETHODCALLTYPE *GetGCHeapInformation )( ICorDebugProcess5 * This, /* [out] */ COR_HEAPINFO *pHeapInfo); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, EnumerateHeap) - HRESULT ( STDMETHODCALLTYPE *EnumerateHeap )( + HRESULT ( STDMETHODCALLTYPE *EnumerateHeap )( ICorDebugProcess5 * This, /* [out] */ ICorDebugHeapEnum **ppObjects); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, EnumerateHeapRegions) - HRESULT ( STDMETHODCALLTYPE *EnumerateHeapRegions )( + HRESULT ( STDMETHODCALLTYPE *EnumerateHeapRegions )( ICorDebugProcess5 * This, /* [out] */ ICorDebugHeapSegmentEnum **ppRegions); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, GetObject) - HRESULT ( STDMETHODCALLTYPE *GetObject )( + HRESULT ( STDMETHODCALLTYPE *GetObject )( ICorDebugProcess5 * This, /* [in] */ CORDB_ADDRESS addr, /* [out] */ ICorDebugObjectValue **pObject); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, EnumerateGCReferences) - HRESULT ( STDMETHODCALLTYPE *EnumerateGCReferences )( + HRESULT ( STDMETHODCALLTYPE *EnumerateGCReferences )( ICorDebugProcess5 * This, /* [in] */ BOOL enumerateWeakReferences, /* [out] */ ICorDebugGCReferenceEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, EnumerateHandles) - HRESULT ( STDMETHODCALLTYPE *EnumerateHandles )( + HRESULT ( STDMETHODCALLTYPE *EnumerateHandles )( ICorDebugProcess5 * This, /* [in] */ CorGCReferenceType types, /* [out] */ ICorDebugGCReferenceEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, GetTypeID) - HRESULT ( STDMETHODCALLTYPE *GetTypeID )( + HRESULT ( STDMETHODCALLTYPE *GetTypeID )( ICorDebugProcess5 * This, /* [in] */ CORDB_ADDRESS obj, /* [out] */ COR_TYPEID *pId); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, GetTypeForTypeID) - HRESULT ( STDMETHODCALLTYPE *GetTypeForTypeID )( + HRESULT ( STDMETHODCALLTYPE *GetTypeForTypeID )( ICorDebugProcess5 * This, /* [in] */ COR_TYPEID id, /* [out] */ ICorDebugType **ppType); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, GetArrayLayout) - HRESULT ( STDMETHODCALLTYPE *GetArrayLayout )( + HRESULT ( STDMETHODCALLTYPE *GetArrayLayout )( ICorDebugProcess5 * This, /* [in] */ COR_TYPEID id, /* [out] */ COR_ARRAY_LAYOUT *pLayout); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, GetTypeLayout) - HRESULT ( STDMETHODCALLTYPE *GetTypeLayout )( + HRESULT ( STDMETHODCALLTYPE *GetTypeLayout )( ICorDebugProcess5 * This, /* [in] */ COR_TYPEID id, /* [out] */ COR_TYPE_LAYOUT *pLayout); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, GetTypeFields) - HRESULT ( STDMETHODCALLTYPE *GetTypeFields )( + HRESULT ( STDMETHODCALLTYPE *GetTypeFields )( ICorDebugProcess5 * This, /* [in] */ COR_TYPEID id, ULONG32 celt, COR_FIELD fields[ ], ULONG32 *pceltNeeded); - + DECLSPEC_XFGVIRT(ICorDebugProcess5, EnableNGENPolicy) - HRESULT ( STDMETHODCALLTYPE *EnableNGENPolicy )( + HRESULT ( STDMETHODCALLTYPE *EnableNGENPolicy )( ICorDebugProcess5 * This, /* [in] */ CorDebugNGENPolicy ePolicy); - + END_INTERFACE } ICorDebugProcess5Vtbl; @@ -7695,56 +7702,56 @@ EXTERN_C const IID IID_ICorDebugProcess5; CONST_VTBL struct ICorDebugProcess5Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess5_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess5_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess5_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess5_GetGCHeapInformation(This,pHeapInfo) \ - ( (This)->lpVtbl -> GetGCHeapInformation(This,pHeapInfo) ) + ( (This)->lpVtbl -> GetGCHeapInformation(This,pHeapInfo) ) #define ICorDebugProcess5_EnumerateHeap(This,ppObjects) \ - ( (This)->lpVtbl -> EnumerateHeap(This,ppObjects) ) + ( (This)->lpVtbl -> EnumerateHeap(This,ppObjects) ) #define ICorDebugProcess5_EnumerateHeapRegions(This,ppRegions) \ - ( (This)->lpVtbl -> EnumerateHeapRegions(This,ppRegions) ) + ( (This)->lpVtbl -> EnumerateHeapRegions(This,ppRegions) ) #define ICorDebugProcess5_GetObject(This,addr,pObject) \ - ( (This)->lpVtbl -> GetObject(This,addr,pObject) ) + ( (This)->lpVtbl -> GetObject(This,addr,pObject) ) #define ICorDebugProcess5_EnumerateGCReferences(This,enumerateWeakReferences,ppEnum) \ - ( (This)->lpVtbl -> EnumerateGCReferences(This,enumerateWeakReferences,ppEnum) ) + ( (This)->lpVtbl -> EnumerateGCReferences(This,enumerateWeakReferences,ppEnum) ) #define ICorDebugProcess5_EnumerateHandles(This,types,ppEnum) \ - ( (This)->lpVtbl -> EnumerateHandles(This,types,ppEnum) ) + ( (This)->lpVtbl -> EnumerateHandles(This,types,ppEnum) ) #define ICorDebugProcess5_GetTypeID(This,obj,pId) \ - ( (This)->lpVtbl -> GetTypeID(This,obj,pId) ) + ( (This)->lpVtbl -> GetTypeID(This,obj,pId) ) #define ICorDebugProcess5_GetTypeForTypeID(This,id,ppType) \ - ( (This)->lpVtbl -> GetTypeForTypeID(This,id,ppType) ) + ( (This)->lpVtbl -> GetTypeForTypeID(This,id,ppType) ) #define ICorDebugProcess5_GetArrayLayout(This,id,pLayout) \ - ( (This)->lpVtbl -> GetArrayLayout(This,id,pLayout) ) + ( (This)->lpVtbl -> GetArrayLayout(This,id,pLayout) ) #define ICorDebugProcess5_GetTypeLayout(This,id,pLayout) \ - ( (This)->lpVtbl -> GetTypeLayout(This,id,pLayout) ) + ( (This)->lpVtbl -> GetTypeLayout(This,id,pLayout) ) #define ICorDebugProcess5_GetTypeFields(This,id,celt,fields,pceltNeeded) \ - ( (This)->lpVtbl -> GetTypeFields(This,id,celt,fields,pceltNeeded) ) + ( (This)->lpVtbl -> GetTypeFields(This,id,celt,fields,pceltNeeded) ) #define ICorDebugProcess5_EnableNGENPolicy(This,ePolicy) \ - ( (This)->lpVtbl -> EnableNGENPolicy(This,ePolicy) ) + ( (This)->lpVtbl -> EnableNGENPolicy(This,ePolicy) ) #endif /* COBJMACROS */ @@ -7758,22 +7765,22 @@ EXTERN_C const IID IID_ICorDebugProcess5; /* interface __MIDL_itf_cordebug_0000_0040 */ -/* [local] */ +/* [local] */ -typedef +typedef enum CorDebugRecordFormat { FORMAT_WINDOWS_EXCEPTIONRECORD32 = 1, FORMAT_WINDOWS_EXCEPTIONRECORD64 = 2 } CorDebugRecordFormat; -typedef +typedef enum CorDebugDecodeEventFlagsWindows { IS_FIRST_CHANCE = 1 } CorDebugDecodeEventFlagsWindows; -typedef +typedef enum CorDebugDebugEventKind { DEBUG_EVENT_KIND_MODULE_LOADED = 1, @@ -7784,7 +7791,7 @@ enum CorDebugDebugEventKind DEBUG_EVENT_KIND_MANAGED_EXCEPTION_UNHANDLED = 6 } CorDebugDebugEventKind; -typedef +typedef enum CorDebugStateChange { PROCESS_RUNNING = 0x1, @@ -7800,57 +7807,57 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0040_v0_0_s_ifspec; #define __ICorDebugDebugEvent_INTERFACE_DEFINED__ /* interface ICorDebugDebugEvent */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugDebugEvent; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("41BD395D-DE99-48F1-BF7A-CC0F44A6D281") ICorDebugDebugEvent : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetEventKind( + virtual HRESULT STDMETHODCALLTYPE GetEventKind( /* [out] */ CorDebugDebugEventKind *pDebugEventKind) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThread( + + virtual HRESULT STDMETHODCALLTYPE GetThread( /* [out] */ ICorDebugThread **ppThread) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugDebugEventVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugDebugEvent * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugDebugEvent * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugDebugEvent * This); - + DECLSPEC_XFGVIRT(ICorDebugDebugEvent, GetEventKind) - HRESULT ( STDMETHODCALLTYPE *GetEventKind )( + HRESULT ( STDMETHODCALLTYPE *GetEventKind )( ICorDebugDebugEvent * This, /* [out] */ CorDebugDebugEventKind *pDebugEventKind); - + DECLSPEC_XFGVIRT(ICorDebugDebugEvent, GetThread) - HRESULT ( STDMETHODCALLTYPE *GetThread )( + HRESULT ( STDMETHODCALLTYPE *GetThread )( ICorDebugDebugEvent * This, /* [out] */ ICorDebugThread **ppThread); - + END_INTERFACE } ICorDebugDebugEventVtbl; @@ -7859,26 +7866,26 @@ EXTERN_C const IID IID_ICorDebugDebugEvent; CONST_VTBL struct ICorDebugDebugEventVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugDebugEvent_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugDebugEvent_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugDebugEvent_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugDebugEvent_GetEventKind(This,pDebugEventKind) \ - ( (This)->lpVtbl -> GetEventKind(This,pDebugEventKind) ) + ( (This)->lpVtbl -> GetEventKind(This,pDebugEventKind) ) #define ICorDebugDebugEvent_GetThread(This,ppThread) \ - ( (This)->lpVtbl -> GetThread(This,ppThread) ) + ( (This)->lpVtbl -> GetThread(This,ppThread) ) #endif /* COBJMACROS */ @@ -7892,23 +7899,23 @@ EXTERN_C const IID IID_ICorDebugDebugEvent; /* interface __MIDL_itf_cordebug_0000_0041 */ -/* [local] */ +/* [local] */ -typedef +typedef enum CorDebugCodeInvokeKind { CODE_INVOKE_KIND_NONE = 0, CODE_INVOKE_KIND_RETURN = ( CODE_INVOKE_KIND_NONE + 1 ) , - CODE_INVOKE_KIND_TAILCALL = ( CODE_INVOKE_KIND_RETURN + 1 ) + CODE_INVOKE_KIND_TAILCALL = ( CODE_INVOKE_KIND_RETURN + 1 ) } CorDebugCodeInvokeKind; -typedef +typedef enum CorDebugCodeInvokePurpose { CODE_INVOKE_PURPOSE_NONE = 0, CODE_INVOKE_PURPOSE_NATIVE_TO_MANAGED_TRANSITION = ( CODE_INVOKE_PURPOSE_NONE + 1 ) , CODE_INVOKE_PURPOSE_CLASS_INIT = ( CODE_INVOKE_PURPOSE_NATIVE_TO_MANAGED_TRANSITION + 1 ) , - CODE_INVOKE_PURPOSE_INTERFACE_DISPATCH = ( CODE_INVOKE_PURPOSE_CLASS_INIT + 1 ) + CODE_INVOKE_PURPOSE_INTERFACE_DISPATCH = ( CODE_INVOKE_PURPOSE_CLASS_INIT + 1 ) } CorDebugCodeInvokePurpose; @@ -7920,69 +7927,69 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0041_v0_0_s_ifspec; #define __ICorDebugProcess6_INTERFACE_DEFINED__ /* interface ICorDebugProcess6 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess6; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("11588775-7205-4CEB-A41A-93753C3153E9") ICorDebugProcess6 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE DecodeEvent( + virtual HRESULT STDMETHODCALLTYPE DecodeEvent( /* [size_is][length_is][in] */ const BYTE pRecord[ ], /* [in] */ DWORD countBytes, /* [in] */ CorDebugRecordFormat format, /* [in] */ DWORD dwFlags, /* [in] */ DWORD dwThreadId, /* [out] */ ICorDebugDebugEvent **ppEvent) = 0; - - virtual HRESULT STDMETHODCALLTYPE ProcessStateChanged( + + virtual HRESULT STDMETHODCALLTYPE ProcessStateChanged( /* [in] */ CorDebugStateChange change) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCode( + + virtual HRESULT STDMETHODCALLTYPE GetCode( /* [in] */ CORDB_ADDRESS codeAddress, /* [out] */ ICorDebugCode **ppCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnableVirtualModuleSplitting( + + virtual HRESULT STDMETHODCALLTYPE EnableVirtualModuleSplitting( BOOL enableSplitting) = 0; - - virtual HRESULT STDMETHODCALLTYPE MarkDebuggerAttached( + + virtual HRESULT STDMETHODCALLTYPE MarkDebuggerAttached( BOOL fIsAttached) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetExportStepInfo( + + virtual HRESULT STDMETHODCALLTYPE GetExportStepInfo( /* [in] */ LPCWSTR pszExportName, /* [out] */ CorDebugCodeInvokeKind *pInvokeKind, /* [out] */ CorDebugCodeInvokePurpose *pInvokePurpose) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess6Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess6 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess6 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess6 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess6, DecodeEvent) - HRESULT ( STDMETHODCALLTYPE *DecodeEvent )( + HRESULT ( STDMETHODCALLTYPE *DecodeEvent )( ICorDebugProcess6 * This, /* [size_is][length_is][in] */ const BYTE pRecord[ ], /* [in] */ DWORD countBytes, @@ -7990,35 +7997,35 @@ EXTERN_C const IID IID_ICorDebugProcess6; /* [in] */ DWORD dwFlags, /* [in] */ DWORD dwThreadId, /* [out] */ ICorDebugDebugEvent **ppEvent); - + DECLSPEC_XFGVIRT(ICorDebugProcess6, ProcessStateChanged) - HRESULT ( STDMETHODCALLTYPE *ProcessStateChanged )( + HRESULT ( STDMETHODCALLTYPE *ProcessStateChanged )( ICorDebugProcess6 * This, /* [in] */ CorDebugStateChange change); - + DECLSPEC_XFGVIRT(ICorDebugProcess6, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugProcess6 * This, /* [in] */ CORDB_ADDRESS codeAddress, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugProcess6, EnableVirtualModuleSplitting) - HRESULT ( STDMETHODCALLTYPE *EnableVirtualModuleSplitting )( + HRESULT ( STDMETHODCALLTYPE *EnableVirtualModuleSplitting )( ICorDebugProcess6 * This, BOOL enableSplitting); - + DECLSPEC_XFGVIRT(ICorDebugProcess6, MarkDebuggerAttached) - HRESULT ( STDMETHODCALLTYPE *MarkDebuggerAttached )( + HRESULT ( STDMETHODCALLTYPE *MarkDebuggerAttached )( ICorDebugProcess6 * This, BOOL fIsAttached); - + DECLSPEC_XFGVIRT(ICorDebugProcess6, GetExportStepInfo) - HRESULT ( STDMETHODCALLTYPE *GetExportStepInfo )( + HRESULT ( STDMETHODCALLTYPE *GetExportStepInfo )( ICorDebugProcess6 * This, /* [in] */ LPCWSTR pszExportName, /* [out] */ CorDebugCodeInvokeKind *pInvokeKind, /* [out] */ CorDebugCodeInvokePurpose *pInvokePurpose); - + END_INTERFACE } ICorDebugProcess6Vtbl; @@ -8027,38 +8034,38 @@ EXTERN_C const IID IID_ICorDebugProcess6; CONST_VTBL struct ICorDebugProcess6Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess6_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess6_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess6_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess6_DecodeEvent(This,pRecord,countBytes,format,dwFlags,dwThreadId,ppEvent) \ - ( (This)->lpVtbl -> DecodeEvent(This,pRecord,countBytes,format,dwFlags,dwThreadId,ppEvent) ) + ( (This)->lpVtbl -> DecodeEvent(This,pRecord,countBytes,format,dwFlags,dwThreadId,ppEvent) ) #define ICorDebugProcess6_ProcessStateChanged(This,change) \ - ( (This)->lpVtbl -> ProcessStateChanged(This,change) ) + ( (This)->lpVtbl -> ProcessStateChanged(This,change) ) #define ICorDebugProcess6_GetCode(This,codeAddress,ppCode) \ - ( (This)->lpVtbl -> GetCode(This,codeAddress,ppCode) ) + ( (This)->lpVtbl -> GetCode(This,codeAddress,ppCode) ) #define ICorDebugProcess6_EnableVirtualModuleSplitting(This,enableSplitting) \ - ( (This)->lpVtbl -> EnableVirtualModuleSplitting(This,enableSplitting) ) + ( (This)->lpVtbl -> EnableVirtualModuleSplitting(This,enableSplitting) ) #define ICorDebugProcess6_MarkDebuggerAttached(This,fIsAttached) \ - ( (This)->lpVtbl -> MarkDebuggerAttached(This,fIsAttached) ) + ( (This)->lpVtbl -> MarkDebuggerAttached(This,fIsAttached) ) #define ICorDebugProcess6_GetExportStepInfo(This,pszExportName,pInvokeKind,pInvokePurpose) \ - ( (This)->lpVtbl -> GetExportStepInfo(This,pszExportName,pInvokeKind,pInvokePurpose) ) + ( (This)->lpVtbl -> GetExportStepInfo(This,pszExportName,pInvokeKind,pInvokePurpose) ) #endif /* COBJMACROS */ @@ -8072,13 +8079,13 @@ EXTERN_C const IID IID_ICorDebugProcess6; /* interface __MIDL_itf_cordebug_0000_0042 */ -/* [local] */ +/* [local] */ -typedef +typedef enum WriteableMetadataUpdateMode { LegacyCompatPolicy = 0, - AlwaysShowUpdates = ( LegacyCompatPolicy + 1 ) + AlwaysShowUpdates = ( LegacyCompatPolicy + 1 ) } WriteableMetadataUpdateMode; @@ -8090,49 +8097,49 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0042_v0_0_s_ifspec; #define __ICorDebugProcess7_INTERFACE_DEFINED__ /* interface ICorDebugProcess7 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess7; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("9B2C54E4-119F-4D6F-B402-527603266D69") ICorDebugProcess7 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE SetWriteableMetadataUpdateMode( + virtual HRESULT STDMETHODCALLTYPE SetWriteableMetadataUpdateMode( WriteableMetadataUpdateMode flags) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess7Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess7 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess7 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess7 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess7, SetWriteableMetadataUpdateMode) - HRESULT ( STDMETHODCALLTYPE *SetWriteableMetadataUpdateMode )( + HRESULT ( STDMETHODCALLTYPE *SetWriteableMetadataUpdateMode )( ICorDebugProcess7 * This, WriteableMetadataUpdateMode flags); - + END_INTERFACE } ICorDebugProcess7Vtbl; @@ -8141,23 +8148,23 @@ EXTERN_C const IID IID_ICorDebugProcess7; CONST_VTBL struct ICorDebugProcess7Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess7_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess7_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess7_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess7_SetWriteableMetadataUpdateMode(This,flags) \ - ( (This)->lpVtbl -> SetWriteableMetadataUpdateMode(This,flags) ) + ( (This)->lpVtbl -> SetWriteableMetadataUpdateMode(This,flags) ) #endif /* COBJMACROS */ @@ -8174,49 +8181,49 @@ EXTERN_C const IID IID_ICorDebugProcess7; #define __ICorDebugProcess8_INTERFACE_DEFINED__ /* interface ICorDebugProcess8 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess8; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("2E6F28C1-85EB-4141-80AD-0A90944B9639") ICorDebugProcess8 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE EnableExceptionCallbacksOutsideOfMyCode( + virtual HRESULT STDMETHODCALLTYPE EnableExceptionCallbacksOutsideOfMyCode( /* [in] */ BOOL enableExceptionsOutsideOfJMC) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess8Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess8 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess8 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess8 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess8, EnableExceptionCallbacksOutsideOfMyCode) - HRESULT ( STDMETHODCALLTYPE *EnableExceptionCallbacksOutsideOfMyCode )( + HRESULT ( STDMETHODCALLTYPE *EnableExceptionCallbacksOutsideOfMyCode )( ICorDebugProcess8 * This, /* [in] */ BOOL enableExceptionsOutsideOfJMC); - + END_INTERFACE } ICorDebugProcess8Vtbl; @@ -8225,23 +8232,23 @@ EXTERN_C const IID IID_ICorDebugProcess8; CONST_VTBL struct ICorDebugProcess8Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess8_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess8_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess8_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess8_EnableExceptionCallbacksOutsideOfMyCode(This,enableExceptionsOutsideOfJMC) \ - ( (This)->lpVtbl -> EnableExceptionCallbacksOutsideOfMyCode(This,enableExceptionsOutsideOfJMC) ) + ( (This)->lpVtbl -> EnableExceptionCallbacksOutsideOfMyCode(This,enableExceptionsOutsideOfJMC) ) #endif /* COBJMACROS */ @@ -8258,49 +8265,49 @@ EXTERN_C const IID IID_ICorDebugProcess8; #define __ICorDebugProcess10_INTERFACE_DEFINED__ /* interface ICorDebugProcess10 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess10; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("8F378F6F-1017-4461-9890-ECF64C54079F") ICorDebugProcess10 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE EnableGCNotificationEvents( + virtual HRESULT STDMETHODCALLTYPE EnableGCNotificationEvents( BOOL fEnable) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess10Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess10 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess10 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess10 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess10, EnableGCNotificationEvents) - HRESULT ( STDMETHODCALLTYPE *EnableGCNotificationEvents )( + HRESULT ( STDMETHODCALLTYPE *EnableGCNotificationEvents )( ICorDebugProcess10 * This, BOOL fEnable); - + END_INTERFACE } ICorDebugProcess10Vtbl; @@ -8309,23 +8316,23 @@ EXTERN_C const IID IID_ICorDebugProcess10; CONST_VTBL struct ICorDebugProcess10Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess10_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess10_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess10_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess10_EnableGCNotificationEvents(This,fEnable) \ - ( (This)->lpVtbl -> EnableGCNotificationEvents(This,fEnable) ) + ( (This)->lpVtbl -> EnableGCNotificationEvents(This,fEnable) ) #endif /* COBJMACROS */ @@ -8339,7 +8346,7 @@ EXTERN_C const IID IID_ICorDebugProcess10; /* interface __MIDL_itf_cordebug_0000_0045 */ -/* [local] */ +/* [local] */ typedef struct _COR_MEMORY_RANGE { @@ -8356,72 +8363,72 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0045_v0_0_s_ifspec; #define __ICorDebugMemoryRangeEnum_INTERFACE_DEFINED__ /* interface ICorDebugMemoryRangeEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugMemoryRangeEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("D1A0BCFC-5865-4437-BE3F-36F022951F8A") ICorDebugMemoryRangeEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_MEMORY_RANGE objects[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugMemoryRangeEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugMemoryRangeEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugMemoryRangeEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugMemoryRangeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugMemoryRangeEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugMemoryRangeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugMemoryRangeEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugMemoryRangeEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugMemoryRangeEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugMemoryRangeEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ COR_MEMORY_RANGE objects[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugMemoryRangeEnumVtbl; @@ -8430,36 +8437,36 @@ EXTERN_C const IID IID_ICorDebugMemoryRangeEnum; CONST_VTBL struct ICorDebugMemoryRangeEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugMemoryRangeEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugMemoryRangeEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugMemoryRangeEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugMemoryRangeEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugMemoryRangeEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugMemoryRangeEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugMemoryRangeEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugMemoryRangeEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) #endif /* COBJMACROS */ @@ -8476,49 +8483,49 @@ EXTERN_C const IID IID_ICorDebugMemoryRangeEnum; #define __ICorDebugProcess11_INTERFACE_DEFINED__ /* interface ICorDebugProcess11 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcess11; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("344B37AA-F2C0-4D3B-9909-91CCF787DA8C") ICorDebugProcess11 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE EnumerateLoaderHeapMemoryRegions( + virtual HRESULT STDMETHODCALLTYPE EnumerateLoaderHeapMemoryRegions( /* [out] */ ICorDebugMemoryRangeEnum **ppRanges) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcess11Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcess11 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcess11 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcess11 * This); - + DECLSPEC_XFGVIRT(ICorDebugProcess11, EnumerateLoaderHeapMemoryRegions) - HRESULT ( STDMETHODCALLTYPE *EnumerateLoaderHeapMemoryRegions )( + HRESULT ( STDMETHODCALLTYPE *EnumerateLoaderHeapMemoryRegions )( ICorDebugProcess11 * This, /* [out] */ ICorDebugMemoryRangeEnum **ppRanges); - + END_INTERFACE } ICorDebugProcess11Vtbl; @@ -8527,23 +8534,23 @@ EXTERN_C const IID IID_ICorDebugProcess11; CONST_VTBL struct ICorDebugProcess11Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcess11_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcess11_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcess11_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcess11_EnumerateLoaderHeapMemoryRegions(This,ppRanges) \ - ( (This)->lpVtbl -> EnumerateLoaderHeapMemoryRegions(This,ppRanges) ) + ( (This)->lpVtbl -> EnumerateLoaderHeapMemoryRegions(This,ppRanges) ) #endif /* COBJMACROS */ @@ -8560,59 +8567,59 @@ EXTERN_C const IID IID_ICorDebugProcess11; #define __ICorDebugModuleDebugEvent_INTERFACE_DEFINED__ /* interface ICorDebugModuleDebugEvent */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugModuleDebugEvent; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("51A15E8D-9FFF-4864-9B87-F4FBDEA747A2") ICorDebugModuleDebugEvent : public ICorDebugDebugEvent { public: - virtual HRESULT STDMETHODCALLTYPE GetModule( + virtual HRESULT STDMETHODCALLTYPE GetModule( /* [out] */ ICorDebugModule **ppModule) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugModuleDebugEventVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugModuleDebugEvent * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugModuleDebugEvent * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugModuleDebugEvent * This); - + DECLSPEC_XFGVIRT(ICorDebugDebugEvent, GetEventKind) - HRESULT ( STDMETHODCALLTYPE *GetEventKind )( + HRESULT ( STDMETHODCALLTYPE *GetEventKind )( ICorDebugModuleDebugEvent * This, /* [out] */ CorDebugDebugEventKind *pDebugEventKind); - + DECLSPEC_XFGVIRT(ICorDebugDebugEvent, GetThread) - HRESULT ( STDMETHODCALLTYPE *GetThread )( + HRESULT ( STDMETHODCALLTYPE *GetThread )( ICorDebugModuleDebugEvent * This, /* [out] */ ICorDebugThread **ppThread); - + DECLSPEC_XFGVIRT(ICorDebugModuleDebugEvent, GetModule) - HRESULT ( STDMETHODCALLTYPE *GetModule )( + HRESULT ( STDMETHODCALLTYPE *GetModule )( ICorDebugModuleDebugEvent * This, /* [out] */ ICorDebugModule **ppModule); - + END_INTERFACE } ICorDebugModuleDebugEventVtbl; @@ -8621,30 +8628,30 @@ EXTERN_C const IID IID_ICorDebugModuleDebugEvent; CONST_VTBL struct ICorDebugModuleDebugEventVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugModuleDebugEvent_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugModuleDebugEvent_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugModuleDebugEvent_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugModuleDebugEvent_GetEventKind(This,pDebugEventKind) \ - ( (This)->lpVtbl -> GetEventKind(This,pDebugEventKind) ) + ( (This)->lpVtbl -> GetEventKind(This,pDebugEventKind) ) #define ICorDebugModuleDebugEvent_GetThread(This,ppThread) \ - ( (This)->lpVtbl -> GetThread(This,ppThread) ) + ( (This)->lpVtbl -> GetThread(This,ppThread) ) #define ICorDebugModuleDebugEvent_GetModule(This,ppModule) \ - ( (This)->lpVtbl -> GetModule(This,ppModule) ) + ( (This)->lpVtbl -> GetModule(This,ppModule) ) #endif /* COBJMACROS */ @@ -8661,75 +8668,75 @@ EXTERN_C const IID IID_ICorDebugModuleDebugEvent; #define __ICorDebugExceptionDebugEvent_INTERFACE_DEFINED__ /* interface ICorDebugExceptionDebugEvent */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugExceptionDebugEvent; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("AF79EC94-4752-419C-A626-5FB1CC1A5AB7") ICorDebugExceptionDebugEvent : public ICorDebugDebugEvent { public: - virtual HRESULT STDMETHODCALLTYPE GetStackPointer( + virtual HRESULT STDMETHODCALLTYPE GetStackPointer( /* [out] */ CORDB_ADDRESS *pStackPointer) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetNativeIP( + + virtual HRESULT STDMETHODCALLTYPE GetNativeIP( /* [out] */ CORDB_ADDRESS *pIP) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFlags( + + virtual HRESULT STDMETHODCALLTYPE GetFlags( /* [out] */ CorDebugExceptionFlags *pdwFlags) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugExceptionDebugEventVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugExceptionDebugEvent * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugExceptionDebugEvent * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugExceptionDebugEvent * This); - + DECLSPEC_XFGVIRT(ICorDebugDebugEvent, GetEventKind) - HRESULT ( STDMETHODCALLTYPE *GetEventKind )( + HRESULT ( STDMETHODCALLTYPE *GetEventKind )( ICorDebugExceptionDebugEvent * This, /* [out] */ CorDebugDebugEventKind *pDebugEventKind); - + DECLSPEC_XFGVIRT(ICorDebugDebugEvent, GetThread) - HRESULT ( STDMETHODCALLTYPE *GetThread )( + HRESULT ( STDMETHODCALLTYPE *GetThread )( ICorDebugExceptionDebugEvent * This, /* [out] */ ICorDebugThread **ppThread); - + DECLSPEC_XFGVIRT(ICorDebugExceptionDebugEvent, GetStackPointer) - HRESULT ( STDMETHODCALLTYPE *GetStackPointer )( + HRESULT ( STDMETHODCALLTYPE *GetStackPointer )( ICorDebugExceptionDebugEvent * This, /* [out] */ CORDB_ADDRESS *pStackPointer); - + DECLSPEC_XFGVIRT(ICorDebugExceptionDebugEvent, GetNativeIP) - HRESULT ( STDMETHODCALLTYPE *GetNativeIP )( + HRESULT ( STDMETHODCALLTYPE *GetNativeIP )( ICorDebugExceptionDebugEvent * This, /* [out] */ CORDB_ADDRESS *pIP); - + DECLSPEC_XFGVIRT(ICorDebugExceptionDebugEvent, GetFlags) - HRESULT ( STDMETHODCALLTYPE *GetFlags )( + HRESULT ( STDMETHODCALLTYPE *GetFlags )( ICorDebugExceptionDebugEvent * This, /* [out] */ CorDebugExceptionFlags *pdwFlags); - + END_INTERFACE } ICorDebugExceptionDebugEventVtbl; @@ -8738,36 +8745,36 @@ EXTERN_C const IID IID_ICorDebugExceptionDebugEvent; CONST_VTBL struct ICorDebugExceptionDebugEventVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugExceptionDebugEvent_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugExceptionDebugEvent_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugExceptionDebugEvent_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugExceptionDebugEvent_GetEventKind(This,pDebugEventKind) \ - ( (This)->lpVtbl -> GetEventKind(This,pDebugEventKind) ) + ( (This)->lpVtbl -> GetEventKind(This,pDebugEventKind) ) #define ICorDebugExceptionDebugEvent_GetThread(This,ppThread) \ - ( (This)->lpVtbl -> GetThread(This,ppThread) ) + ( (This)->lpVtbl -> GetThread(This,ppThread) ) #define ICorDebugExceptionDebugEvent_GetStackPointer(This,pStackPointer) \ - ( (This)->lpVtbl -> GetStackPointer(This,pStackPointer) ) + ( (This)->lpVtbl -> GetStackPointer(This,pStackPointer) ) #define ICorDebugExceptionDebugEvent_GetNativeIP(This,pIP) \ - ( (This)->lpVtbl -> GetNativeIP(This,pIP) ) + ( (This)->lpVtbl -> GetNativeIP(This,pIP) ) #define ICorDebugExceptionDebugEvent_GetFlags(This,pdwFlags) \ - ( (This)->lpVtbl -> GetFlags(This,pdwFlags) ) + ( (This)->lpVtbl -> GetFlags(This,pdwFlags) ) #endif /* COBJMACROS */ @@ -8784,57 +8791,57 @@ EXTERN_C const IID IID_ICorDebugExceptionDebugEvent; #define __ICorDebugBreakpoint_INTERFACE_DEFINED__ /* interface ICorDebugBreakpoint */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugBreakpoint; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAE8-8A68-11d2-983C-0000F808342D") ICorDebugBreakpoint : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Activate( + virtual HRESULT STDMETHODCALLTYPE Activate( /* [in] */ BOOL bActive) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsActive( + + virtual HRESULT STDMETHODCALLTYPE IsActive( /* [out] */ BOOL *pbActive) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugBreakpointVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugBreakpoint * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugBreakpoint * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugBreakpoint * This); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, Activate) - HRESULT ( STDMETHODCALLTYPE *Activate )( + HRESULT ( STDMETHODCALLTYPE *Activate )( ICorDebugBreakpoint * This, /* [in] */ BOOL bActive); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, IsActive) - HRESULT ( STDMETHODCALLTYPE *IsActive )( + HRESULT ( STDMETHODCALLTYPE *IsActive )( ICorDebugBreakpoint * This, /* [out] */ BOOL *pbActive); - + END_INTERFACE } ICorDebugBreakpointVtbl; @@ -8843,26 +8850,26 @@ EXTERN_C const IID IID_ICorDebugBreakpoint; CONST_VTBL struct ICorDebugBreakpointVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugBreakpoint_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugBreakpoint_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugBreakpoint_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugBreakpoint_Activate(This,bActive) \ - ( (This)->lpVtbl -> Activate(This,bActive) ) + ( (This)->lpVtbl -> Activate(This,bActive) ) #define ICorDebugBreakpoint_IsActive(This,pbActive) \ - ( (This)->lpVtbl -> IsActive(This,pbActive) ) + ( (This)->lpVtbl -> IsActive(This,pbActive) ) #endif /* COBJMACROS */ @@ -8879,67 +8886,67 @@ EXTERN_C const IID IID_ICorDebugBreakpoint; #define __ICorDebugFunctionBreakpoint_INTERFACE_DEFINED__ /* interface ICorDebugFunctionBreakpoint */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFunctionBreakpoint; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAE9-8A68-11d2-983C-0000F808342D") ICorDebugFunctionBreakpoint : public ICorDebugBreakpoint { public: - virtual HRESULT STDMETHODCALLTYPE GetFunction( + virtual HRESULT STDMETHODCALLTYPE GetFunction( /* [out] */ ICorDebugFunction **ppFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetOffset( + + virtual HRESULT STDMETHODCALLTYPE GetOffset( /* [out] */ ULONG32 *pnOffset) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFunctionBreakpointVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFunctionBreakpoint * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFunctionBreakpoint * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFunctionBreakpoint * This); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, Activate) - HRESULT ( STDMETHODCALLTYPE *Activate )( + HRESULT ( STDMETHODCALLTYPE *Activate )( ICorDebugFunctionBreakpoint * This, /* [in] */ BOOL bActive); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, IsActive) - HRESULT ( STDMETHODCALLTYPE *IsActive )( + HRESULT ( STDMETHODCALLTYPE *IsActive )( ICorDebugFunctionBreakpoint * This, /* [out] */ BOOL *pbActive); - + DECLSPEC_XFGVIRT(ICorDebugFunctionBreakpoint, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugFunctionBreakpoint * This, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugFunctionBreakpoint, GetOffset) - HRESULT ( STDMETHODCALLTYPE *GetOffset )( + HRESULT ( STDMETHODCALLTYPE *GetOffset )( ICorDebugFunctionBreakpoint * This, /* [out] */ ULONG32 *pnOffset); - + END_INTERFACE } ICorDebugFunctionBreakpointVtbl; @@ -8948,33 +8955,33 @@ EXTERN_C const IID IID_ICorDebugFunctionBreakpoint; CONST_VTBL struct ICorDebugFunctionBreakpointVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFunctionBreakpoint_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFunctionBreakpoint_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFunctionBreakpoint_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFunctionBreakpoint_Activate(This,bActive) \ - ( (This)->lpVtbl -> Activate(This,bActive) ) + ( (This)->lpVtbl -> Activate(This,bActive) ) #define ICorDebugFunctionBreakpoint_IsActive(This,pbActive) \ - ( (This)->lpVtbl -> IsActive(This,pbActive) ) + ( (This)->lpVtbl -> IsActive(This,pbActive) ) #define ICorDebugFunctionBreakpoint_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #define ICorDebugFunctionBreakpoint_GetOffset(This,pnOffset) \ - ( (This)->lpVtbl -> GetOffset(This,pnOffset) ) + ( (This)->lpVtbl -> GetOffset(This,pnOffset) ) #endif /* COBJMACROS */ @@ -8991,59 +8998,59 @@ EXTERN_C const IID IID_ICorDebugFunctionBreakpoint; #define __ICorDebugModuleBreakpoint_INTERFACE_DEFINED__ /* interface ICorDebugModuleBreakpoint */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugModuleBreakpoint; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAEA-8A68-11d2-983C-0000F808342D") ICorDebugModuleBreakpoint : public ICorDebugBreakpoint { public: - virtual HRESULT STDMETHODCALLTYPE GetModule( + virtual HRESULT STDMETHODCALLTYPE GetModule( /* [out] */ ICorDebugModule **ppModule) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugModuleBreakpointVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugModuleBreakpoint * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugModuleBreakpoint * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugModuleBreakpoint * This); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, Activate) - HRESULT ( STDMETHODCALLTYPE *Activate )( + HRESULT ( STDMETHODCALLTYPE *Activate )( ICorDebugModuleBreakpoint * This, /* [in] */ BOOL bActive); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, IsActive) - HRESULT ( STDMETHODCALLTYPE *IsActive )( + HRESULT ( STDMETHODCALLTYPE *IsActive )( ICorDebugModuleBreakpoint * This, /* [out] */ BOOL *pbActive); - + DECLSPEC_XFGVIRT(ICorDebugModuleBreakpoint, GetModule) - HRESULT ( STDMETHODCALLTYPE *GetModule )( + HRESULT ( STDMETHODCALLTYPE *GetModule )( ICorDebugModuleBreakpoint * This, /* [out] */ ICorDebugModule **ppModule); - + END_INTERFACE } ICorDebugModuleBreakpointVtbl; @@ -9052,30 +9059,30 @@ EXTERN_C const IID IID_ICorDebugModuleBreakpoint; CONST_VTBL struct ICorDebugModuleBreakpointVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugModuleBreakpoint_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugModuleBreakpoint_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugModuleBreakpoint_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugModuleBreakpoint_Activate(This,bActive) \ - ( (This)->lpVtbl -> Activate(This,bActive) ) + ( (This)->lpVtbl -> Activate(This,bActive) ) #define ICorDebugModuleBreakpoint_IsActive(This,pbActive) \ - ( (This)->lpVtbl -> IsActive(This,pbActive) ) + ( (This)->lpVtbl -> IsActive(This,pbActive) ) #define ICorDebugModuleBreakpoint_GetModule(This,ppModule) \ - ( (This)->lpVtbl -> GetModule(This,ppModule) ) + ( (This)->lpVtbl -> GetModule(This,ppModule) ) #endif /* COBJMACROS */ @@ -9092,59 +9099,59 @@ EXTERN_C const IID IID_ICorDebugModuleBreakpoint; #define __ICorDebugValueBreakpoint_INTERFACE_DEFINED__ /* interface ICorDebugValueBreakpoint */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugValueBreakpoint; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAEB-8A68-11d2-983C-0000F808342D") ICorDebugValueBreakpoint : public ICorDebugBreakpoint { public: - virtual HRESULT STDMETHODCALLTYPE GetValue( + virtual HRESULT STDMETHODCALLTYPE GetValue( /* [out] */ ICorDebugValue **ppValue) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugValueBreakpointVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugValueBreakpoint * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugValueBreakpoint * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugValueBreakpoint * This); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, Activate) - HRESULT ( STDMETHODCALLTYPE *Activate )( + HRESULT ( STDMETHODCALLTYPE *Activate )( ICorDebugValueBreakpoint * This, /* [in] */ BOOL bActive); - + DECLSPEC_XFGVIRT(ICorDebugBreakpoint, IsActive) - HRESULT ( STDMETHODCALLTYPE *IsActive )( + HRESULT ( STDMETHODCALLTYPE *IsActive )( ICorDebugValueBreakpoint * This, /* [out] */ BOOL *pbActive); - + DECLSPEC_XFGVIRT(ICorDebugValueBreakpoint, GetValue) - HRESULT ( STDMETHODCALLTYPE *GetValue )( + HRESULT ( STDMETHODCALLTYPE *GetValue )( ICorDebugValueBreakpoint * This, /* [out] */ ICorDebugValue **ppValue); - + END_INTERFACE } ICorDebugValueBreakpointVtbl; @@ -9153,30 +9160,30 @@ EXTERN_C const IID IID_ICorDebugValueBreakpoint; CONST_VTBL struct ICorDebugValueBreakpointVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugValueBreakpoint_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugValueBreakpoint_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugValueBreakpoint_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugValueBreakpoint_Activate(This,bActive) \ - ( (This)->lpVtbl -> Activate(This,bActive) ) + ( (This)->lpVtbl -> Activate(This,bActive) ) #define ICorDebugValueBreakpoint_IsActive(This,pbActive) \ - ( (This)->lpVtbl -> IsActive(This,pbActive) ) + ( (This)->lpVtbl -> IsActive(This,pbActive) ) #define ICorDebugValueBreakpoint_GetValue(This,ppValue) \ - ( (This)->lpVtbl -> GetValue(This,ppValue) ) + ( (This)->lpVtbl -> GetValue(This,ppValue) ) #endif /* COBJMACROS */ @@ -9193,9 +9200,9 @@ EXTERN_C const IID IID_ICorDebugValueBreakpoint; #define __ICorDebugStepper_INTERFACE_DEFINED__ /* interface ICorDebugStepper */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugIntercept { INTERCEPT_NONE = 0, @@ -9207,7 +9214,7 @@ enum CorDebugIntercept INTERCEPT_ALL = 0xffff } CorDebugIntercept; -typedef +typedef enum CorDebugUnmappedStop { STOP_NONE = 0, @@ -9229,99 +9236,99 @@ typedef struct COR_DEBUG_STEP_RANGE EXTERN_C const IID IID_ICorDebugStepper; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAEC-8A68-11d2-983C-0000F808342D") ICorDebugStepper : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE IsActive( + virtual HRESULT STDMETHODCALLTYPE IsActive( /* [out] */ BOOL *pbActive) = 0; - + virtual HRESULT STDMETHODCALLTYPE Deactivate( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetInterceptMask( + + virtual HRESULT STDMETHODCALLTYPE SetInterceptMask( /* [in] */ CorDebugIntercept mask) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetUnmappedStopMask( + + virtual HRESULT STDMETHODCALLTYPE SetUnmappedStopMask( /* [in] */ CorDebugUnmappedStop mask) = 0; - - virtual HRESULT STDMETHODCALLTYPE Step( + + virtual HRESULT STDMETHODCALLTYPE Step( /* [in] */ BOOL bStepIn) = 0; - - virtual HRESULT STDMETHODCALLTYPE StepRange( + + virtual HRESULT STDMETHODCALLTYPE StepRange( /* [in] */ BOOL bStepIn, /* [size_is][in] */ COR_DEBUG_STEP_RANGE ranges[ ], /* [in] */ ULONG32 cRangeCount) = 0; - + virtual HRESULT STDMETHODCALLTYPE StepOut( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetRangeIL( + + virtual HRESULT STDMETHODCALLTYPE SetRangeIL( /* [in] */ BOOL bIL) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugStepperVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugStepper * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugStepper * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugStepper * This); - + DECLSPEC_XFGVIRT(ICorDebugStepper, IsActive) - HRESULT ( STDMETHODCALLTYPE *IsActive )( + HRESULT ( STDMETHODCALLTYPE *IsActive )( ICorDebugStepper * This, /* [out] */ BOOL *pbActive); - + DECLSPEC_XFGVIRT(ICorDebugStepper, Deactivate) - HRESULT ( STDMETHODCALLTYPE *Deactivate )( + HRESULT ( STDMETHODCALLTYPE *Deactivate )( ICorDebugStepper * This); - + DECLSPEC_XFGVIRT(ICorDebugStepper, SetInterceptMask) - HRESULT ( STDMETHODCALLTYPE *SetInterceptMask )( + HRESULT ( STDMETHODCALLTYPE *SetInterceptMask )( ICorDebugStepper * This, /* [in] */ CorDebugIntercept mask); - + DECLSPEC_XFGVIRT(ICorDebugStepper, SetUnmappedStopMask) - HRESULT ( STDMETHODCALLTYPE *SetUnmappedStopMask )( + HRESULT ( STDMETHODCALLTYPE *SetUnmappedStopMask )( ICorDebugStepper * This, /* [in] */ CorDebugUnmappedStop mask); - + DECLSPEC_XFGVIRT(ICorDebugStepper, Step) - HRESULT ( STDMETHODCALLTYPE *Step )( + HRESULT ( STDMETHODCALLTYPE *Step )( ICorDebugStepper * This, /* [in] */ BOOL bStepIn); - + DECLSPEC_XFGVIRT(ICorDebugStepper, StepRange) - HRESULT ( STDMETHODCALLTYPE *StepRange )( + HRESULT ( STDMETHODCALLTYPE *StepRange )( ICorDebugStepper * This, /* [in] */ BOOL bStepIn, /* [size_is][in] */ COR_DEBUG_STEP_RANGE ranges[ ], /* [in] */ ULONG32 cRangeCount); - + DECLSPEC_XFGVIRT(ICorDebugStepper, StepOut) - HRESULT ( STDMETHODCALLTYPE *StepOut )( + HRESULT ( STDMETHODCALLTYPE *StepOut )( ICorDebugStepper * This); - + DECLSPEC_XFGVIRT(ICorDebugStepper, SetRangeIL) - HRESULT ( STDMETHODCALLTYPE *SetRangeIL )( + HRESULT ( STDMETHODCALLTYPE *SetRangeIL )( ICorDebugStepper * This, /* [in] */ BOOL bIL); - + END_INTERFACE } ICorDebugStepperVtbl; @@ -9330,44 +9337,44 @@ EXTERN_C const IID IID_ICorDebugStepper; CONST_VTBL struct ICorDebugStepperVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugStepper_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugStepper_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugStepper_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugStepper_IsActive(This,pbActive) \ - ( (This)->lpVtbl -> IsActive(This,pbActive) ) + ( (This)->lpVtbl -> IsActive(This,pbActive) ) #define ICorDebugStepper_Deactivate(This) \ - ( (This)->lpVtbl -> Deactivate(This) ) + ( (This)->lpVtbl -> Deactivate(This) ) #define ICorDebugStepper_SetInterceptMask(This,mask) \ - ( (This)->lpVtbl -> SetInterceptMask(This,mask) ) + ( (This)->lpVtbl -> SetInterceptMask(This,mask) ) #define ICorDebugStepper_SetUnmappedStopMask(This,mask) \ - ( (This)->lpVtbl -> SetUnmappedStopMask(This,mask) ) + ( (This)->lpVtbl -> SetUnmappedStopMask(This,mask) ) #define ICorDebugStepper_Step(This,bStepIn) \ - ( (This)->lpVtbl -> Step(This,bStepIn) ) + ( (This)->lpVtbl -> Step(This,bStepIn) ) #define ICorDebugStepper_StepRange(This,bStepIn,ranges,cRangeCount) \ - ( (This)->lpVtbl -> StepRange(This,bStepIn,ranges,cRangeCount) ) + ( (This)->lpVtbl -> StepRange(This,bStepIn,ranges,cRangeCount) ) #define ICorDebugStepper_StepOut(This) \ - ( (This)->lpVtbl -> StepOut(This) ) + ( (This)->lpVtbl -> StepOut(This) ) #define ICorDebugStepper_SetRangeIL(This,bIL) \ - ( (This)->lpVtbl -> SetRangeIL(This,bIL) ) + ( (This)->lpVtbl -> SetRangeIL(This,bIL) ) #endif /* COBJMACROS */ @@ -9384,49 +9391,49 @@ EXTERN_C const IID IID_ICorDebugStepper; #define __ICorDebugStepper2_INTERFACE_DEFINED__ /* interface ICorDebugStepper2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugStepper2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("C5B6E9C3-E7D1-4a8e-873B-7F047F0706F7") ICorDebugStepper2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE SetJMC( + virtual HRESULT STDMETHODCALLTYPE SetJMC( /* [in] */ BOOL fIsJMCStepper) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugStepper2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugStepper2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugStepper2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugStepper2 * This); - + DECLSPEC_XFGVIRT(ICorDebugStepper2, SetJMC) - HRESULT ( STDMETHODCALLTYPE *SetJMC )( + HRESULT ( STDMETHODCALLTYPE *SetJMC )( ICorDebugStepper2 * This, /* [in] */ BOOL fIsJMCStepper); - + END_INTERFACE } ICorDebugStepper2Vtbl; @@ -9435,23 +9442,23 @@ EXTERN_C const IID IID_ICorDebugStepper2; CONST_VTBL struct ICorDebugStepper2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugStepper2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugStepper2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugStepper2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugStepper2_SetJMC(This,fIsJMCStepper) \ - ( (This)->lpVtbl -> SetJMC(This,fIsJMCStepper) ) + ( (This)->lpVtbl -> SetJMC(This,fIsJMCStepper) ) #endif /* COBJMACROS */ @@ -9468,9 +9475,9 @@ EXTERN_C const IID IID_ICorDebugStepper2; #define __ICorDebugRegisterSet_INTERFACE_DEFINED__ /* interface ICorDebugRegisterSet */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugRegister { REGISTER_INSTRUCTION_POINTER = 0, @@ -9776,87 +9783,87 @@ enum CorDebugRegister EXTERN_C const IID IID_ICorDebugRegisterSet; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB0B-8A68-11d2-983C-0000F808342D") ICorDebugRegisterSet : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetRegistersAvailable( + virtual HRESULT STDMETHODCALLTYPE GetRegistersAvailable( /* [out] */ ULONG64 *pAvailable) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRegisters( + + virtual HRESULT STDMETHODCALLTYPE GetRegisters( /* [in] */ ULONG64 mask, /* [in] */ ULONG32 regCount, /* [length_is][size_is][out] */ CORDB_REGISTER regBuffer[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetRegisters( + + virtual HRESULT STDMETHODCALLTYPE SetRegisters( /* [in] */ ULONG64 mask, /* [in] */ ULONG32 regCount, /* [size_is][in] */ CORDB_REGISTER regBuffer[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThreadContext( + + virtual HRESULT STDMETHODCALLTYPE GetThreadContext( /* [in] */ ULONG32 contextSize, /* [size_is][length_is][out][in] */ BYTE context[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetThreadContext( + + virtual HRESULT STDMETHODCALLTYPE SetThreadContext( /* [in] */ ULONG32 contextSize, /* [size_is][length_is][in] */ BYTE context[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugRegisterSetVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugRegisterSet * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugRegisterSet * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugRegisterSet * This); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet, GetRegistersAvailable) - HRESULT ( STDMETHODCALLTYPE *GetRegistersAvailable )( + HRESULT ( STDMETHODCALLTYPE *GetRegistersAvailable )( ICorDebugRegisterSet * This, /* [out] */ ULONG64 *pAvailable); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet, GetRegisters) - HRESULT ( STDMETHODCALLTYPE *GetRegisters )( + HRESULT ( STDMETHODCALLTYPE *GetRegisters )( ICorDebugRegisterSet * This, /* [in] */ ULONG64 mask, /* [in] */ ULONG32 regCount, /* [length_is][size_is][out] */ CORDB_REGISTER regBuffer[ ]); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet, SetRegisters) - HRESULT ( STDMETHODCALLTYPE *SetRegisters )( + HRESULT ( STDMETHODCALLTYPE *SetRegisters )( ICorDebugRegisterSet * This, /* [in] */ ULONG64 mask, /* [in] */ ULONG32 regCount, /* [size_is][in] */ CORDB_REGISTER regBuffer[ ]); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet, GetThreadContext) - HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( + HRESULT ( STDMETHODCALLTYPE *GetThreadContext )( ICorDebugRegisterSet * This, /* [in] */ ULONG32 contextSize, /* [size_is][length_is][out][in] */ BYTE context[ ]); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet, SetThreadContext) - HRESULT ( STDMETHODCALLTYPE *SetThreadContext )( + HRESULT ( STDMETHODCALLTYPE *SetThreadContext )( ICorDebugRegisterSet * This, /* [in] */ ULONG32 contextSize, /* [size_is][length_is][in] */ BYTE context[ ]); - + END_INTERFACE } ICorDebugRegisterSetVtbl; @@ -9865,35 +9872,35 @@ EXTERN_C const IID IID_ICorDebugRegisterSet; CONST_VTBL struct ICorDebugRegisterSetVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugRegisterSet_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugRegisterSet_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugRegisterSet_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugRegisterSet_GetRegistersAvailable(This,pAvailable) \ - ( (This)->lpVtbl -> GetRegistersAvailable(This,pAvailable) ) + ( (This)->lpVtbl -> GetRegistersAvailable(This,pAvailable) ) #define ICorDebugRegisterSet_GetRegisters(This,mask,regCount,regBuffer) \ - ( (This)->lpVtbl -> GetRegisters(This,mask,regCount,regBuffer) ) + ( (This)->lpVtbl -> GetRegisters(This,mask,regCount,regBuffer) ) #define ICorDebugRegisterSet_SetRegisters(This,mask,regCount,regBuffer) \ - ( (This)->lpVtbl -> SetRegisters(This,mask,regCount,regBuffer) ) + ( (This)->lpVtbl -> SetRegisters(This,mask,regCount,regBuffer) ) #define ICorDebugRegisterSet_GetThreadContext(This,contextSize,context) \ - ( (This)->lpVtbl -> GetThreadContext(This,contextSize,context) ) + ( (This)->lpVtbl -> GetThreadContext(This,contextSize,context) ) #define ICorDebugRegisterSet_SetThreadContext(This,contextSize,context) \ - ( (This)->lpVtbl -> SetThreadContext(This,contextSize,context) ) + ( (This)->lpVtbl -> SetThreadContext(This,contextSize,context) ) #endif /* COBJMACROS */ @@ -9910,79 +9917,79 @@ EXTERN_C const IID IID_ICorDebugRegisterSet; #define __ICorDebugRegisterSet2_INTERFACE_DEFINED__ /* interface ICorDebugRegisterSet2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugRegisterSet2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("6DC7BA3F-89BA-4459-9EC1-9D60937B468D") ICorDebugRegisterSet2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetRegistersAvailable( + virtual HRESULT STDMETHODCALLTYPE GetRegistersAvailable( /* [in] */ ULONG32 numChunks, /* [size_is][out] */ BYTE availableRegChunks[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRegisters( + + virtual HRESULT STDMETHODCALLTYPE GetRegisters( /* [in] */ ULONG32 maskCount, /* [size_is][in] */ BYTE mask[ ], /* [in] */ ULONG32 regCount, /* [size_is][out] */ CORDB_REGISTER regBuffer[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetRegisters( + + virtual HRESULT STDMETHODCALLTYPE SetRegisters( /* [in] */ ULONG32 maskCount, /* [size_is][in] */ BYTE mask[ ], /* [in] */ ULONG32 regCount, /* [size_is][in] */ CORDB_REGISTER regBuffer[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugRegisterSet2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugRegisterSet2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugRegisterSet2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugRegisterSet2 * This); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet2, GetRegistersAvailable) - HRESULT ( STDMETHODCALLTYPE *GetRegistersAvailable )( + HRESULT ( STDMETHODCALLTYPE *GetRegistersAvailable )( ICorDebugRegisterSet2 * This, /* [in] */ ULONG32 numChunks, /* [size_is][out] */ BYTE availableRegChunks[ ]); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet2, GetRegisters) - HRESULT ( STDMETHODCALLTYPE *GetRegisters )( + HRESULT ( STDMETHODCALLTYPE *GetRegisters )( ICorDebugRegisterSet2 * This, /* [in] */ ULONG32 maskCount, /* [size_is][in] */ BYTE mask[ ], /* [in] */ ULONG32 regCount, /* [size_is][out] */ CORDB_REGISTER regBuffer[ ]); - + DECLSPEC_XFGVIRT(ICorDebugRegisterSet2, SetRegisters) - HRESULT ( STDMETHODCALLTYPE *SetRegisters )( + HRESULT ( STDMETHODCALLTYPE *SetRegisters )( ICorDebugRegisterSet2 * This, /* [in] */ ULONG32 maskCount, /* [size_is][in] */ BYTE mask[ ], /* [in] */ ULONG32 regCount, /* [size_is][in] */ CORDB_REGISTER regBuffer[ ]); - + END_INTERFACE } ICorDebugRegisterSet2Vtbl; @@ -9991,29 +9998,29 @@ EXTERN_C const IID IID_ICorDebugRegisterSet2; CONST_VTBL struct ICorDebugRegisterSet2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugRegisterSet2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugRegisterSet2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugRegisterSet2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugRegisterSet2_GetRegistersAvailable(This,numChunks,availableRegChunks) \ - ( (This)->lpVtbl -> GetRegistersAvailable(This,numChunks,availableRegChunks) ) + ( (This)->lpVtbl -> GetRegistersAvailable(This,numChunks,availableRegChunks) ) #define ICorDebugRegisterSet2_GetRegisters(This,maskCount,mask,regCount,regBuffer) \ - ( (This)->lpVtbl -> GetRegisters(This,maskCount,mask,regCount,regBuffer) ) + ( (This)->lpVtbl -> GetRegisters(This,maskCount,mask,regCount,regBuffer) ) #define ICorDebugRegisterSet2_SetRegisters(This,maskCount,mask,regCount,regBuffer) \ - ( (This)->lpVtbl -> SetRegisters(This,maskCount,mask,regCount,regBuffer) ) + ( (This)->lpVtbl -> SetRegisters(This,maskCount,mask,regCount,regBuffer) ) #endif /* COBJMACROS */ @@ -10030,9 +10037,9 @@ EXTERN_C const IID IID_ICorDebugRegisterSet2; #define __ICorDebugThread_INTERFACE_DEFINED__ /* interface ICorDebugThread */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugUserState { USER_STOP_REQUESTED = 0x1, @@ -10050,161 +10057,161 @@ enum CorDebugUserState EXTERN_C const IID IID_ICorDebugThread; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("938c6d66-7fb6-4f69-b389-425b8987329b") ICorDebugThread : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetProcess( + virtual HRESULT STDMETHODCALLTYPE GetProcess( /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetID( + + virtual HRESULT STDMETHODCALLTYPE GetID( /* [out] */ DWORD *pdwThreadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetHandle( + + virtual HRESULT STDMETHODCALLTYPE GetHandle( /* [out] */ HTHREAD *phThreadHandle) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAppDomain( + + virtual HRESULT STDMETHODCALLTYPE GetAppDomain( /* [out] */ ICorDebugAppDomain **ppAppDomain) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetDebugState( + + virtual HRESULT STDMETHODCALLTYPE SetDebugState( /* [in] */ CorDebugThreadState state) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDebugState( + + virtual HRESULT STDMETHODCALLTYPE GetDebugState( /* [out] */ CorDebugThreadState *pState) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetUserState( + + virtual HRESULT STDMETHODCALLTYPE GetUserState( /* [out] */ CorDebugUserState *pState) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCurrentException( + + virtual HRESULT STDMETHODCALLTYPE GetCurrentException( /* [out] */ ICorDebugValue **ppExceptionObject) = 0; - + virtual HRESULT STDMETHODCALLTYPE ClearCurrentException( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateStepper( + + virtual HRESULT STDMETHODCALLTYPE CreateStepper( /* [out] */ ICorDebugStepper **ppStepper) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateChains( + + virtual HRESULT STDMETHODCALLTYPE EnumerateChains( /* [out] */ ICorDebugChainEnum **ppChains) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetActiveChain( + + virtual HRESULT STDMETHODCALLTYPE GetActiveChain( /* [out] */ ICorDebugChain **ppChain) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetActiveFrame( + + virtual HRESULT STDMETHODCALLTYPE GetActiveFrame( /* [out] */ ICorDebugFrame **ppFrame) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRegisterSet( + + virtual HRESULT STDMETHODCALLTYPE GetRegisterSet( /* [out] */ ICorDebugRegisterSet **ppRegisters) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateEval( + + virtual HRESULT STDMETHODCALLTYPE CreateEval( /* [out] */ ICorDebugEval **ppEval) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetObject( + + virtual HRESULT STDMETHODCALLTYPE GetObject( /* [out] */ ICorDebugValue **ppObject) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugThreadVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugThread * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugThread * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugThread * This); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetProcess) - HRESULT ( STDMETHODCALLTYPE *GetProcess )( + HRESULT ( STDMETHODCALLTYPE *GetProcess )( ICorDebugThread * This, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetID) - HRESULT ( STDMETHODCALLTYPE *GetID )( + HRESULT ( STDMETHODCALLTYPE *GetID )( ICorDebugThread * This, /* [out] */ DWORD *pdwThreadId); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetHandle) - HRESULT ( STDMETHODCALLTYPE *GetHandle )( + HRESULT ( STDMETHODCALLTYPE *GetHandle )( ICorDebugThread * This, /* [out] */ HTHREAD *phThreadHandle); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetAppDomain) - HRESULT ( STDMETHODCALLTYPE *GetAppDomain )( + HRESULT ( STDMETHODCALLTYPE *GetAppDomain )( ICorDebugThread * This, /* [out] */ ICorDebugAppDomain **ppAppDomain); - + DECLSPEC_XFGVIRT(ICorDebugThread, SetDebugState) - HRESULT ( STDMETHODCALLTYPE *SetDebugState )( + HRESULT ( STDMETHODCALLTYPE *SetDebugState )( ICorDebugThread * This, /* [in] */ CorDebugThreadState state); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetDebugState) - HRESULT ( STDMETHODCALLTYPE *GetDebugState )( + HRESULT ( STDMETHODCALLTYPE *GetDebugState )( ICorDebugThread * This, /* [out] */ CorDebugThreadState *pState); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetUserState) - HRESULT ( STDMETHODCALLTYPE *GetUserState )( + HRESULT ( STDMETHODCALLTYPE *GetUserState )( ICorDebugThread * This, /* [out] */ CorDebugUserState *pState); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetCurrentException) - HRESULT ( STDMETHODCALLTYPE *GetCurrentException )( + HRESULT ( STDMETHODCALLTYPE *GetCurrentException )( ICorDebugThread * This, /* [out] */ ICorDebugValue **ppExceptionObject); - + DECLSPEC_XFGVIRT(ICorDebugThread, ClearCurrentException) - HRESULT ( STDMETHODCALLTYPE *ClearCurrentException )( + HRESULT ( STDMETHODCALLTYPE *ClearCurrentException )( ICorDebugThread * This); - + DECLSPEC_XFGVIRT(ICorDebugThread, CreateStepper) - HRESULT ( STDMETHODCALLTYPE *CreateStepper )( + HRESULT ( STDMETHODCALLTYPE *CreateStepper )( ICorDebugThread * This, /* [out] */ ICorDebugStepper **ppStepper); - + DECLSPEC_XFGVIRT(ICorDebugThread, EnumerateChains) - HRESULT ( STDMETHODCALLTYPE *EnumerateChains )( + HRESULT ( STDMETHODCALLTYPE *EnumerateChains )( ICorDebugThread * This, /* [out] */ ICorDebugChainEnum **ppChains); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetActiveChain) - HRESULT ( STDMETHODCALLTYPE *GetActiveChain )( + HRESULT ( STDMETHODCALLTYPE *GetActiveChain )( ICorDebugThread * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetActiveFrame) - HRESULT ( STDMETHODCALLTYPE *GetActiveFrame )( + HRESULT ( STDMETHODCALLTYPE *GetActiveFrame )( ICorDebugThread * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetRegisterSet) - HRESULT ( STDMETHODCALLTYPE *GetRegisterSet )( + HRESULT ( STDMETHODCALLTYPE *GetRegisterSet )( ICorDebugThread * This, /* [out] */ ICorDebugRegisterSet **ppRegisters); - + DECLSPEC_XFGVIRT(ICorDebugThread, CreateEval) - HRESULT ( STDMETHODCALLTYPE *CreateEval )( + HRESULT ( STDMETHODCALLTYPE *CreateEval )( ICorDebugThread * This, /* [out] */ ICorDebugEval **ppEval); - + DECLSPEC_XFGVIRT(ICorDebugThread, GetObject) - HRESULT ( STDMETHODCALLTYPE *GetObject )( + HRESULT ( STDMETHODCALLTYPE *GetObject )( ICorDebugThread * This, /* [out] */ ICorDebugValue **ppObject); - + END_INTERFACE } ICorDebugThreadVtbl; @@ -10213,68 +10220,68 @@ EXTERN_C const IID IID_ICorDebugThread; CONST_VTBL struct ICorDebugThreadVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugThread_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugThread_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugThread_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugThread_GetProcess(This,ppProcess) \ - ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) + ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) #define ICorDebugThread_GetID(This,pdwThreadId) \ - ( (This)->lpVtbl -> GetID(This,pdwThreadId) ) + ( (This)->lpVtbl -> GetID(This,pdwThreadId) ) #define ICorDebugThread_GetHandle(This,phThreadHandle) \ - ( (This)->lpVtbl -> GetHandle(This,phThreadHandle) ) + ( (This)->lpVtbl -> GetHandle(This,phThreadHandle) ) #define ICorDebugThread_GetAppDomain(This,ppAppDomain) \ - ( (This)->lpVtbl -> GetAppDomain(This,ppAppDomain) ) + ( (This)->lpVtbl -> GetAppDomain(This,ppAppDomain) ) #define ICorDebugThread_SetDebugState(This,state) \ - ( (This)->lpVtbl -> SetDebugState(This,state) ) + ( (This)->lpVtbl -> SetDebugState(This,state) ) #define ICorDebugThread_GetDebugState(This,pState) \ - ( (This)->lpVtbl -> GetDebugState(This,pState) ) + ( (This)->lpVtbl -> GetDebugState(This,pState) ) #define ICorDebugThread_GetUserState(This,pState) \ - ( (This)->lpVtbl -> GetUserState(This,pState) ) + ( (This)->lpVtbl -> GetUserState(This,pState) ) #define ICorDebugThread_GetCurrentException(This,ppExceptionObject) \ - ( (This)->lpVtbl -> GetCurrentException(This,ppExceptionObject) ) + ( (This)->lpVtbl -> GetCurrentException(This,ppExceptionObject) ) #define ICorDebugThread_ClearCurrentException(This) \ - ( (This)->lpVtbl -> ClearCurrentException(This) ) + ( (This)->lpVtbl -> ClearCurrentException(This) ) #define ICorDebugThread_CreateStepper(This,ppStepper) \ - ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) + ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) #define ICorDebugThread_EnumerateChains(This,ppChains) \ - ( (This)->lpVtbl -> EnumerateChains(This,ppChains) ) + ( (This)->lpVtbl -> EnumerateChains(This,ppChains) ) #define ICorDebugThread_GetActiveChain(This,ppChain) \ - ( (This)->lpVtbl -> GetActiveChain(This,ppChain) ) + ( (This)->lpVtbl -> GetActiveChain(This,ppChain) ) #define ICorDebugThread_GetActiveFrame(This,ppFrame) \ - ( (This)->lpVtbl -> GetActiveFrame(This,ppFrame) ) + ( (This)->lpVtbl -> GetActiveFrame(This,ppFrame) ) #define ICorDebugThread_GetRegisterSet(This,ppRegisters) \ - ( (This)->lpVtbl -> GetRegisterSet(This,ppRegisters) ) + ( (This)->lpVtbl -> GetRegisterSet(This,ppRegisters) ) #define ICorDebugThread_CreateEval(This,ppEval) \ - ( (This)->lpVtbl -> CreateEval(This,ppEval) ) + ( (This)->lpVtbl -> CreateEval(This,ppEval) ) #define ICorDebugThread_GetObject(This,ppObject) \ - ( (This)->lpVtbl -> GetObject(This,ppObject) ) + ( (This)->lpVtbl -> GetObject(This,ppObject) ) #endif /* COBJMACROS */ @@ -10291,7 +10298,7 @@ EXTERN_C const IID IID_ICorDebugThread; #define __ICorDebugThread2_INTERFACE_DEFINED__ /* interface ICorDebugThread2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ typedef struct _COR_ACTIVE_FUNCTION { @@ -10306,79 +10313,79 @@ typedef struct _COR_ACTIVE_FUNCTION EXTERN_C const IID IID_ICorDebugThread2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("2BD956D9-7B07-4bef-8A98-12AA862417C5") ICorDebugThread2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetActiveFunctions( + virtual HRESULT STDMETHODCALLTYPE GetActiveFunctions( /* [in] */ ULONG32 cFunctions, /* [out] */ ULONG32 *pcFunctions, /* [length_is][size_is][out][in] */ COR_ACTIVE_FUNCTION pFunctions[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetConnectionID( + + virtual HRESULT STDMETHODCALLTYPE GetConnectionID( /* [out] */ CONNID *pdwConnectionId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTaskID( + + virtual HRESULT STDMETHODCALLTYPE GetTaskID( /* [out] */ TASKID *pTaskId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetVolatileOSThreadID( + + virtual HRESULT STDMETHODCALLTYPE GetVolatileOSThreadID( /* [out] */ DWORD *pdwTid) = 0; - - virtual HRESULT STDMETHODCALLTYPE InterceptCurrentException( + + virtual HRESULT STDMETHODCALLTYPE InterceptCurrentException( /* [in] */ ICorDebugFrame *pFrame) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugThread2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugThread2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugThread2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugThread2 * This); - + DECLSPEC_XFGVIRT(ICorDebugThread2, GetActiveFunctions) - HRESULT ( STDMETHODCALLTYPE *GetActiveFunctions )( + HRESULT ( STDMETHODCALLTYPE *GetActiveFunctions )( ICorDebugThread2 * This, /* [in] */ ULONG32 cFunctions, /* [out] */ ULONG32 *pcFunctions, /* [length_is][size_is][out][in] */ COR_ACTIVE_FUNCTION pFunctions[ ]); - + DECLSPEC_XFGVIRT(ICorDebugThread2, GetConnectionID) - HRESULT ( STDMETHODCALLTYPE *GetConnectionID )( + HRESULT ( STDMETHODCALLTYPE *GetConnectionID )( ICorDebugThread2 * This, /* [out] */ CONNID *pdwConnectionId); - + DECLSPEC_XFGVIRT(ICorDebugThread2, GetTaskID) - HRESULT ( STDMETHODCALLTYPE *GetTaskID )( + HRESULT ( STDMETHODCALLTYPE *GetTaskID )( ICorDebugThread2 * This, /* [out] */ TASKID *pTaskId); - + DECLSPEC_XFGVIRT(ICorDebugThread2, GetVolatileOSThreadID) - HRESULT ( STDMETHODCALLTYPE *GetVolatileOSThreadID )( + HRESULT ( STDMETHODCALLTYPE *GetVolatileOSThreadID )( ICorDebugThread2 * This, /* [out] */ DWORD *pdwTid); - + DECLSPEC_XFGVIRT(ICorDebugThread2, InterceptCurrentException) - HRESULT ( STDMETHODCALLTYPE *InterceptCurrentException )( + HRESULT ( STDMETHODCALLTYPE *InterceptCurrentException )( ICorDebugThread2 * This, /* [in] */ ICorDebugFrame *pFrame); - + END_INTERFACE } ICorDebugThread2Vtbl; @@ -10387,35 +10394,35 @@ EXTERN_C const IID IID_ICorDebugThread2; CONST_VTBL struct ICorDebugThread2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugThread2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugThread2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugThread2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugThread2_GetActiveFunctions(This,cFunctions,pcFunctions,pFunctions) \ - ( (This)->lpVtbl -> GetActiveFunctions(This,cFunctions,pcFunctions,pFunctions) ) + ( (This)->lpVtbl -> GetActiveFunctions(This,cFunctions,pcFunctions,pFunctions) ) #define ICorDebugThread2_GetConnectionID(This,pdwConnectionId) \ - ( (This)->lpVtbl -> GetConnectionID(This,pdwConnectionId) ) + ( (This)->lpVtbl -> GetConnectionID(This,pdwConnectionId) ) #define ICorDebugThread2_GetTaskID(This,pTaskId) \ - ( (This)->lpVtbl -> GetTaskID(This,pTaskId) ) + ( (This)->lpVtbl -> GetTaskID(This,pTaskId) ) #define ICorDebugThread2_GetVolatileOSThreadID(This,pdwTid) \ - ( (This)->lpVtbl -> GetVolatileOSThreadID(This,pdwTid) ) + ( (This)->lpVtbl -> GetVolatileOSThreadID(This,pdwTid) ) #define ICorDebugThread2_InterceptCurrentException(This,pFrame) \ - ( (This)->lpVtbl -> InterceptCurrentException(This,pFrame) ) + ( (This)->lpVtbl -> InterceptCurrentException(This,pFrame) ) #endif /* COBJMACROS */ @@ -10432,61 +10439,61 @@ EXTERN_C const IID IID_ICorDebugThread2; #define __ICorDebugThread3_INTERFACE_DEFINED__ /* interface ICorDebugThread3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugThread3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F8544EC3-5E4E-46c7-8D3E-A52B8405B1F5") ICorDebugThread3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CreateStackWalk( + virtual HRESULT STDMETHODCALLTYPE CreateStackWalk( /* [out] */ ICorDebugStackWalk **ppStackWalk) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetActiveInternalFrames( + + virtual HRESULT STDMETHODCALLTYPE GetActiveInternalFrames( /* [in] */ ULONG32 cInternalFrames, /* [out] */ ULONG32 *pcInternalFrames, /* [length_is][size_is][out][in] */ ICorDebugInternalFrame2 *ppInternalFrames[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugThread3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugThread3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugThread3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugThread3 * This); - + DECLSPEC_XFGVIRT(ICorDebugThread3, CreateStackWalk) - HRESULT ( STDMETHODCALLTYPE *CreateStackWalk )( + HRESULT ( STDMETHODCALLTYPE *CreateStackWalk )( ICorDebugThread3 * This, /* [out] */ ICorDebugStackWalk **ppStackWalk); - + DECLSPEC_XFGVIRT(ICorDebugThread3, GetActiveInternalFrames) - HRESULT ( STDMETHODCALLTYPE *GetActiveInternalFrames )( + HRESULT ( STDMETHODCALLTYPE *GetActiveInternalFrames )( ICorDebugThread3 * This, /* [in] */ ULONG32 cInternalFrames, /* [out] */ ULONG32 *pcInternalFrames, /* [length_is][size_is][out][in] */ ICorDebugInternalFrame2 *ppInternalFrames[ ]); - + END_INTERFACE } ICorDebugThread3Vtbl; @@ -10495,26 +10502,26 @@ EXTERN_C const IID IID_ICorDebugThread3; CONST_VTBL struct ICorDebugThread3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugThread3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugThread3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugThread3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugThread3_CreateStackWalk(This,ppStackWalk) \ - ( (This)->lpVtbl -> CreateStackWalk(This,ppStackWalk) ) + ( (This)->lpVtbl -> CreateStackWalk(This,ppStackWalk) ) #define ICorDebugThread3_GetActiveInternalFrames(This,cInternalFrames,pcInternalFrames,ppInternalFrames) \ - ( (This)->lpVtbl -> GetActiveInternalFrames(This,cInternalFrames,pcInternalFrames,ppInternalFrames) ) + ( (This)->lpVtbl -> GetActiveInternalFrames(This,cInternalFrames,pcInternalFrames,ppInternalFrames) ) #endif /* COBJMACROS */ @@ -10531,63 +10538,63 @@ EXTERN_C const IID IID_ICorDebugThread3; #define __ICorDebugThread4_INTERFACE_DEFINED__ /* interface ICorDebugThread4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugThread4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("1A1F204B-1C66-4637-823F-3EE6C744A69C") ICorDebugThread4 : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE HasUnhandledException( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetBlockingObjects( + + virtual HRESULT STDMETHODCALLTYPE GetBlockingObjects( /* [out] */ ICorDebugBlockingObjectEnum **ppBlockingObjectEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCurrentCustomDebuggerNotification( + + virtual HRESULT STDMETHODCALLTYPE GetCurrentCustomDebuggerNotification( /* [out] */ ICorDebugValue **ppNotificationObject) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugThread4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugThread4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugThread4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugThread4 * This); - + DECLSPEC_XFGVIRT(ICorDebugThread4, HasUnhandledException) - HRESULT ( STDMETHODCALLTYPE *HasUnhandledException )( + HRESULT ( STDMETHODCALLTYPE *HasUnhandledException )( ICorDebugThread4 * This); - + DECLSPEC_XFGVIRT(ICorDebugThread4, GetBlockingObjects) - HRESULT ( STDMETHODCALLTYPE *GetBlockingObjects )( + HRESULT ( STDMETHODCALLTYPE *GetBlockingObjects )( ICorDebugThread4 * This, /* [out] */ ICorDebugBlockingObjectEnum **ppBlockingObjectEnum); - + DECLSPEC_XFGVIRT(ICorDebugThread4, GetCurrentCustomDebuggerNotification) - HRESULT ( STDMETHODCALLTYPE *GetCurrentCustomDebuggerNotification )( + HRESULT ( STDMETHODCALLTYPE *GetCurrentCustomDebuggerNotification )( ICorDebugThread4 * This, /* [out] */ ICorDebugValue **ppNotificationObject); - + END_INTERFACE } ICorDebugThread4Vtbl; @@ -10596,29 +10603,29 @@ EXTERN_C const IID IID_ICorDebugThread4; CONST_VTBL struct ICorDebugThread4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugThread4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugThread4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugThread4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugThread4_HasUnhandledException(This) \ - ( (This)->lpVtbl -> HasUnhandledException(This) ) + ( (This)->lpVtbl -> HasUnhandledException(This) ) #define ICorDebugThread4_GetBlockingObjects(This,ppBlockingObjectEnum) \ - ( (This)->lpVtbl -> GetBlockingObjects(This,ppBlockingObjectEnum) ) + ( (This)->lpVtbl -> GetBlockingObjects(This,ppBlockingObjectEnum) ) #define ICorDebugThread4_GetCurrentCustomDebuggerNotification(This,ppNotificationObject) \ - ( (This)->lpVtbl -> GetCurrentCustomDebuggerNotification(This,ppNotificationObject) ) + ( (This)->lpVtbl -> GetCurrentCustomDebuggerNotification(This,ppNotificationObject) ) #endif /* COBJMACROS */ @@ -10635,51 +10642,51 @@ EXTERN_C const IID IID_ICorDebugThread4; #define __ICorDebugThread5_INTERFACE_DEFINED__ /* interface ICorDebugThread5 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugThread5; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F98421C4-E506-4D24-916F-0237EE853EC6") ICorDebugThread5 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetBytesAllocated( + virtual HRESULT STDMETHODCALLTYPE GetBytesAllocated( /* [out] */ ULONG64 *pSohAllocatedBytes, /* [out] */ ULONG64 *pUohAllocatedBytes) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugThread5Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugThread5 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugThread5 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugThread5 * This); - + DECLSPEC_XFGVIRT(ICorDebugThread5, GetBytesAllocated) - HRESULT ( STDMETHODCALLTYPE *GetBytesAllocated )( + HRESULT ( STDMETHODCALLTYPE *GetBytesAllocated )( ICorDebugThread5 * This, /* [out] */ ULONG64 *pSohAllocatedBytes, /* [out] */ ULONG64 *pUohAllocatedBytes); - + END_INTERFACE } ICorDebugThread5Vtbl; @@ -10688,23 +10695,23 @@ EXTERN_C const IID IID_ICorDebugThread5; CONST_VTBL struct ICorDebugThread5Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugThread5_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugThread5_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugThread5_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugThread5_GetBytesAllocated(This,pSohAllocatedBytes,pUohAllocatedBytes) \ - ( (This)->lpVtbl -> GetBytesAllocated(This,pSohAllocatedBytes,pUohAllocatedBytes) ) + ( (This)->lpVtbl -> GetBytesAllocated(This,pSohAllocatedBytes,pUohAllocatedBytes) ) #endif /* COBJMACROS */ @@ -10721,9 +10728,9 @@ EXTERN_C const IID IID_ICorDebugThread5; #define __ICorDebugStackWalk_INTERFACE_DEFINED__ /* interface ICorDebugStackWalk */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugSetContextFlag { SET_CONTEXT_FLAG_ACTIVE_FRAME = 0x1, @@ -10734,75 +10741,75 @@ enum CorDebugSetContextFlag EXTERN_C const IID IID_ICorDebugStackWalk; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("A0647DE9-55DE-4816-929C-385271C64CF7") ICorDebugStackWalk : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetContext( + virtual HRESULT STDMETHODCALLTYPE GetContext( /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 contextBufSize, /* [out] */ ULONG32 *contextSize, /* [size_is][out] */ BYTE contextBuf[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetContext( + + virtual HRESULT STDMETHODCALLTYPE SetContext( /* [in] */ CorDebugSetContextFlag flag, /* [in] */ ULONG32 contextSize, /* [size_is][in] */ BYTE context[ ]) = 0; - + virtual HRESULT STDMETHODCALLTYPE Next( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFrame( + + virtual HRESULT STDMETHODCALLTYPE GetFrame( /* [out] */ ICorDebugFrame **pFrame) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugStackWalkVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugStackWalk * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugStackWalk * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugStackWalk * This); - + DECLSPEC_XFGVIRT(ICorDebugStackWalk, GetContext) - HRESULT ( STDMETHODCALLTYPE *GetContext )( + HRESULT ( STDMETHODCALLTYPE *GetContext )( ICorDebugStackWalk * This, /* [in] */ ULONG32 contextFlags, /* [in] */ ULONG32 contextBufSize, /* [out] */ ULONG32 *contextSize, /* [size_is][out] */ BYTE contextBuf[ ]); - + DECLSPEC_XFGVIRT(ICorDebugStackWalk, SetContext) - HRESULT ( STDMETHODCALLTYPE *SetContext )( + HRESULT ( STDMETHODCALLTYPE *SetContext )( ICorDebugStackWalk * This, /* [in] */ CorDebugSetContextFlag flag, /* [in] */ ULONG32 contextSize, /* [size_is][in] */ BYTE context[ ]); - + DECLSPEC_XFGVIRT(ICorDebugStackWalk, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugStackWalk * This); - + DECLSPEC_XFGVIRT(ICorDebugStackWalk, GetFrame) - HRESULT ( STDMETHODCALLTYPE *GetFrame )( + HRESULT ( STDMETHODCALLTYPE *GetFrame )( ICorDebugStackWalk * This, /* [out] */ ICorDebugFrame **pFrame); - + END_INTERFACE } ICorDebugStackWalkVtbl; @@ -10811,32 +10818,32 @@ EXTERN_C const IID IID_ICorDebugStackWalk; CONST_VTBL struct ICorDebugStackWalkVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugStackWalk_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugStackWalk_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugStackWalk_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugStackWalk_GetContext(This,contextFlags,contextBufSize,contextSize,contextBuf) \ - ( (This)->lpVtbl -> GetContext(This,contextFlags,contextBufSize,contextSize,contextBuf) ) + ( (This)->lpVtbl -> GetContext(This,contextFlags,contextBufSize,contextSize,contextBuf) ) #define ICorDebugStackWalk_SetContext(This,flag,contextSize,context) \ - ( (This)->lpVtbl -> SetContext(This,flag,contextSize,context) ) + ( (This)->lpVtbl -> SetContext(This,flag,contextSize,context) ) #define ICorDebugStackWalk_Next(This) \ - ( (This)->lpVtbl -> Next(This) ) + ( (This)->lpVtbl -> Next(This) ) #define ICorDebugStackWalk_GetFrame(This,pFrame) \ - ( (This)->lpVtbl -> GetFrame(This,pFrame) ) + ( (This)->lpVtbl -> GetFrame(This,pFrame) ) #endif /* COBJMACROS */ @@ -10853,9 +10860,9 @@ EXTERN_C const IID IID_ICorDebugStackWalk; #define __ICorDebugChain_INTERFACE_DEFINED__ /* interface ICorDebugChain */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugChainReason { CHAIN_NONE = 0, @@ -10877,133 +10884,133 @@ enum CorDebugChainReason EXTERN_C const IID IID_ICorDebugChain; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAEE-8A68-11d2-983C-0000F808342D") ICorDebugChain : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetThread( + virtual HRESULT STDMETHODCALLTYPE GetThread( /* [out] */ ICorDebugThread **ppThread) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStackRange( + + virtual HRESULT STDMETHODCALLTYPE GetStackRange( /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetContext( + + virtual HRESULT STDMETHODCALLTYPE GetContext( /* [out] */ ICorDebugContext **ppContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCaller( + + virtual HRESULT STDMETHODCALLTYPE GetCaller( /* [out] */ ICorDebugChain **ppChain) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCallee( + + virtual HRESULT STDMETHODCALLTYPE GetCallee( /* [out] */ ICorDebugChain **ppChain) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetPrevious( + + virtual HRESULT STDMETHODCALLTYPE GetPrevious( /* [out] */ ICorDebugChain **ppChain) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetNext( + + virtual HRESULT STDMETHODCALLTYPE GetNext( /* [out] */ ICorDebugChain **ppChain) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsManaged( + + virtual HRESULT STDMETHODCALLTYPE IsManaged( /* [out] */ BOOL *pManaged) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateFrames( + + virtual HRESULT STDMETHODCALLTYPE EnumerateFrames( /* [out] */ ICorDebugFrameEnum **ppFrames) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetActiveFrame( + + virtual HRESULT STDMETHODCALLTYPE GetActiveFrame( /* [out] */ ICorDebugFrame **ppFrame) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRegisterSet( + + virtual HRESULT STDMETHODCALLTYPE GetRegisterSet( /* [out] */ ICorDebugRegisterSet **ppRegisters) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetReason( + + virtual HRESULT STDMETHODCALLTYPE GetReason( /* [out] */ CorDebugChainReason *pReason) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugChainVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugChain * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugChain * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugChain * This); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetThread) - HRESULT ( STDMETHODCALLTYPE *GetThread )( + HRESULT ( STDMETHODCALLTYPE *GetThread )( ICorDebugChain * This, /* [out] */ ICorDebugThread **ppThread); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetStackRange) - HRESULT ( STDMETHODCALLTYPE *GetStackRange )( + HRESULT ( STDMETHODCALLTYPE *GetStackRange )( ICorDebugChain * This, /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetContext) - HRESULT ( STDMETHODCALLTYPE *GetContext )( + HRESULT ( STDMETHODCALLTYPE *GetContext )( ICorDebugChain * This, /* [out] */ ICorDebugContext **ppContext); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetCaller) - HRESULT ( STDMETHODCALLTYPE *GetCaller )( + HRESULT ( STDMETHODCALLTYPE *GetCaller )( ICorDebugChain * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetCallee) - HRESULT ( STDMETHODCALLTYPE *GetCallee )( + HRESULT ( STDMETHODCALLTYPE *GetCallee )( ICorDebugChain * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetPrevious) - HRESULT ( STDMETHODCALLTYPE *GetPrevious )( + HRESULT ( STDMETHODCALLTYPE *GetPrevious )( ICorDebugChain * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetNext) - HRESULT ( STDMETHODCALLTYPE *GetNext )( + HRESULT ( STDMETHODCALLTYPE *GetNext )( ICorDebugChain * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugChain, IsManaged) - HRESULT ( STDMETHODCALLTYPE *IsManaged )( + HRESULT ( STDMETHODCALLTYPE *IsManaged )( ICorDebugChain * This, /* [out] */ BOOL *pManaged); - + DECLSPEC_XFGVIRT(ICorDebugChain, EnumerateFrames) - HRESULT ( STDMETHODCALLTYPE *EnumerateFrames )( + HRESULT ( STDMETHODCALLTYPE *EnumerateFrames )( ICorDebugChain * This, /* [out] */ ICorDebugFrameEnum **ppFrames); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetActiveFrame) - HRESULT ( STDMETHODCALLTYPE *GetActiveFrame )( + HRESULT ( STDMETHODCALLTYPE *GetActiveFrame )( ICorDebugChain * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetRegisterSet) - HRESULT ( STDMETHODCALLTYPE *GetRegisterSet )( + HRESULT ( STDMETHODCALLTYPE *GetRegisterSet )( ICorDebugChain * This, /* [out] */ ICorDebugRegisterSet **ppRegisters); - + DECLSPEC_XFGVIRT(ICorDebugChain, GetReason) - HRESULT ( STDMETHODCALLTYPE *GetReason )( + HRESULT ( STDMETHODCALLTYPE *GetReason )( ICorDebugChain * This, /* [out] */ CorDebugChainReason *pReason); - + END_INTERFACE } ICorDebugChainVtbl; @@ -11012,56 +11019,56 @@ EXTERN_C const IID IID_ICorDebugChain; CONST_VTBL struct ICorDebugChainVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugChain_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugChain_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugChain_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugChain_GetThread(This,ppThread) \ - ( (This)->lpVtbl -> GetThread(This,ppThread) ) + ( (This)->lpVtbl -> GetThread(This,ppThread) ) #define ICorDebugChain_GetStackRange(This,pStart,pEnd) \ - ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) + ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) #define ICorDebugChain_GetContext(This,ppContext) \ - ( (This)->lpVtbl -> GetContext(This,ppContext) ) + ( (This)->lpVtbl -> GetContext(This,ppContext) ) #define ICorDebugChain_GetCaller(This,ppChain) \ - ( (This)->lpVtbl -> GetCaller(This,ppChain) ) + ( (This)->lpVtbl -> GetCaller(This,ppChain) ) #define ICorDebugChain_GetCallee(This,ppChain) \ - ( (This)->lpVtbl -> GetCallee(This,ppChain) ) + ( (This)->lpVtbl -> GetCallee(This,ppChain) ) #define ICorDebugChain_GetPrevious(This,ppChain) \ - ( (This)->lpVtbl -> GetPrevious(This,ppChain) ) + ( (This)->lpVtbl -> GetPrevious(This,ppChain) ) #define ICorDebugChain_GetNext(This,ppChain) \ - ( (This)->lpVtbl -> GetNext(This,ppChain) ) + ( (This)->lpVtbl -> GetNext(This,ppChain) ) #define ICorDebugChain_IsManaged(This,pManaged) \ - ( (This)->lpVtbl -> IsManaged(This,pManaged) ) + ( (This)->lpVtbl -> IsManaged(This,pManaged) ) #define ICorDebugChain_EnumerateFrames(This,ppFrames) \ - ( (This)->lpVtbl -> EnumerateFrames(This,ppFrames) ) + ( (This)->lpVtbl -> EnumerateFrames(This,ppFrames) ) #define ICorDebugChain_GetActiveFrame(This,ppFrame) \ - ( (This)->lpVtbl -> GetActiveFrame(This,ppFrame) ) + ( (This)->lpVtbl -> GetActiveFrame(This,ppFrame) ) #define ICorDebugChain_GetRegisterSet(This,ppRegisters) \ - ( (This)->lpVtbl -> GetRegisterSet(This,ppRegisters) ) + ( (This)->lpVtbl -> GetRegisterSet(This,ppRegisters) ) #define ICorDebugChain_GetReason(This,pReason) \ - ( (This)->lpVtbl -> GetReason(This,pReason) ) + ( (This)->lpVtbl -> GetReason(This,pReason) ) #endif /* COBJMACROS */ @@ -11078,107 +11085,107 @@ EXTERN_C const IID IID_ICorDebugChain; #define __ICorDebugFrame_INTERFACE_DEFINED__ /* interface ICorDebugFrame */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFrame; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAEF-8A68-11d2-983C-0000F808342D") ICorDebugFrame : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetChain( + virtual HRESULT STDMETHODCALLTYPE GetChain( /* [out] */ ICorDebugChain **ppChain) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCode( + + virtual HRESULT STDMETHODCALLTYPE GetCode( /* [out] */ ICorDebugCode **ppCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunction( + + virtual HRESULT STDMETHODCALLTYPE GetFunction( /* [out] */ ICorDebugFunction **ppFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionToken( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionToken( /* [out] */ mdMethodDef *pToken) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStackRange( + + virtual HRESULT STDMETHODCALLTYPE GetStackRange( /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCaller( + + virtual HRESULT STDMETHODCALLTYPE GetCaller( /* [out] */ ICorDebugFrame **ppFrame) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCallee( + + virtual HRESULT STDMETHODCALLTYPE GetCallee( /* [out] */ ICorDebugFrame **ppFrame) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateStepper( + + virtual HRESULT STDMETHODCALLTYPE CreateStepper( /* [out] */ ICorDebugStepper **ppStepper) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFrameVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFrame * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFrame * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFrame * This); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetChain) - HRESULT ( STDMETHODCALLTYPE *GetChain )( + HRESULT ( STDMETHODCALLTYPE *GetChain )( ICorDebugFrame * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugFrame * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugFrame * This, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunctionToken) - HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( ICorDebugFrame * This, /* [out] */ mdMethodDef *pToken); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetStackRange) - HRESULT ( STDMETHODCALLTYPE *GetStackRange )( + HRESULT ( STDMETHODCALLTYPE *GetStackRange )( ICorDebugFrame * This, /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCaller) - HRESULT ( STDMETHODCALLTYPE *GetCaller )( + HRESULT ( STDMETHODCALLTYPE *GetCaller )( ICorDebugFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCallee) - HRESULT ( STDMETHODCALLTYPE *GetCallee )( + HRESULT ( STDMETHODCALLTYPE *GetCallee )( ICorDebugFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, CreateStepper) - HRESULT ( STDMETHODCALLTYPE *CreateStepper )( + HRESULT ( STDMETHODCALLTYPE *CreateStepper )( ICorDebugFrame * This, /* [out] */ ICorDebugStepper **ppStepper); - + END_INTERFACE } ICorDebugFrameVtbl; @@ -11187,44 +11194,44 @@ EXTERN_C const IID IID_ICorDebugFrame; CONST_VTBL struct ICorDebugFrameVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFrame_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFrame_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFrame_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFrame_GetChain(This,ppChain) \ - ( (This)->lpVtbl -> GetChain(This,ppChain) ) + ( (This)->lpVtbl -> GetChain(This,ppChain) ) #define ICorDebugFrame_GetCode(This,ppCode) \ - ( (This)->lpVtbl -> GetCode(This,ppCode) ) + ( (This)->lpVtbl -> GetCode(This,ppCode) ) #define ICorDebugFrame_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #define ICorDebugFrame_GetFunctionToken(This,pToken) \ - ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) + ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) #define ICorDebugFrame_GetStackRange(This,pStart,pEnd) \ - ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) + ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) #define ICorDebugFrame_GetCaller(This,ppFrame) \ - ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) + ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) #define ICorDebugFrame_GetCallee(This,ppFrame) \ - ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) + ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) #define ICorDebugFrame_CreateStepper(This,ppStepper) \ - ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) + ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) #endif /* COBJMACROS */ @@ -11241,9 +11248,9 @@ EXTERN_C const IID IID_ICorDebugFrame; #define __ICorDebugInternalFrame_INTERFACE_DEFINED__ /* interface ICorDebugInternalFrame */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugInternalFrameType { STUBFRAME_NONE = 0, @@ -11263,84 +11270,84 @@ enum CorDebugInternalFrameType EXTERN_C const IID IID_ICorDebugInternalFrame; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("B92CC7F7-9D2D-45c4-BC2B-621FCC9DFBF4") ICorDebugInternalFrame : public ICorDebugFrame { public: - virtual HRESULT STDMETHODCALLTYPE GetFrameType( + virtual HRESULT STDMETHODCALLTYPE GetFrameType( /* [out] */ CorDebugInternalFrameType *pType) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugInternalFrameVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugInternalFrame * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugInternalFrame * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugInternalFrame * This); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetChain) - HRESULT ( STDMETHODCALLTYPE *GetChain )( + HRESULT ( STDMETHODCALLTYPE *GetChain )( ICorDebugInternalFrame * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugInternalFrame * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugInternalFrame * This, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunctionToken) - HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( ICorDebugInternalFrame * This, /* [out] */ mdMethodDef *pToken); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetStackRange) - HRESULT ( STDMETHODCALLTYPE *GetStackRange )( + HRESULT ( STDMETHODCALLTYPE *GetStackRange )( ICorDebugInternalFrame * This, /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCaller) - HRESULT ( STDMETHODCALLTYPE *GetCaller )( + HRESULT ( STDMETHODCALLTYPE *GetCaller )( ICorDebugInternalFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCallee) - HRESULT ( STDMETHODCALLTYPE *GetCallee )( + HRESULT ( STDMETHODCALLTYPE *GetCallee )( ICorDebugInternalFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, CreateStepper) - HRESULT ( STDMETHODCALLTYPE *CreateStepper )( + HRESULT ( STDMETHODCALLTYPE *CreateStepper )( ICorDebugInternalFrame * This, /* [out] */ ICorDebugStepper **ppStepper); - + DECLSPEC_XFGVIRT(ICorDebugInternalFrame, GetFrameType) - HRESULT ( STDMETHODCALLTYPE *GetFrameType )( + HRESULT ( STDMETHODCALLTYPE *GetFrameType )( ICorDebugInternalFrame * This, /* [out] */ CorDebugInternalFrameType *pType); - + END_INTERFACE } ICorDebugInternalFrameVtbl; @@ -11349,48 +11356,48 @@ EXTERN_C const IID IID_ICorDebugInternalFrame; CONST_VTBL struct ICorDebugInternalFrameVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugInternalFrame_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugInternalFrame_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugInternalFrame_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugInternalFrame_GetChain(This,ppChain) \ - ( (This)->lpVtbl -> GetChain(This,ppChain) ) + ( (This)->lpVtbl -> GetChain(This,ppChain) ) #define ICorDebugInternalFrame_GetCode(This,ppCode) \ - ( (This)->lpVtbl -> GetCode(This,ppCode) ) + ( (This)->lpVtbl -> GetCode(This,ppCode) ) #define ICorDebugInternalFrame_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #define ICorDebugInternalFrame_GetFunctionToken(This,pToken) \ - ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) + ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) #define ICorDebugInternalFrame_GetStackRange(This,pStart,pEnd) \ - ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) + ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) #define ICorDebugInternalFrame_GetCaller(This,ppFrame) \ - ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) + ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) #define ICorDebugInternalFrame_GetCallee(This,ppFrame) \ - ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) + ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) #define ICorDebugInternalFrame_CreateStepper(This,ppStepper) \ - ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) + ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) #define ICorDebugInternalFrame_GetFrameType(This,pType) \ - ( (This)->lpVtbl -> GetFrameType(This,pType) ) + ( (This)->lpVtbl -> GetFrameType(This,pType) ) #endif /* COBJMACROS */ @@ -11407,59 +11414,59 @@ EXTERN_C const IID IID_ICorDebugInternalFrame; #define __ICorDebugInternalFrame2_INTERFACE_DEFINED__ /* interface ICorDebugInternalFrame2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugInternalFrame2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("C0815BDC-CFAB-447e-A779-C116B454EB5B") ICorDebugInternalFrame2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetAddress( + virtual HRESULT STDMETHODCALLTYPE GetAddress( /* [out] */ CORDB_ADDRESS *pAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsCloserToLeaf( + + virtual HRESULT STDMETHODCALLTYPE IsCloserToLeaf( /* [in] */ ICorDebugFrame *pFrameToCompare, /* [out] */ BOOL *pIsCloser) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugInternalFrame2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugInternalFrame2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugInternalFrame2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugInternalFrame2 * This); - + DECLSPEC_XFGVIRT(ICorDebugInternalFrame2, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugInternalFrame2 * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugInternalFrame2, IsCloserToLeaf) - HRESULT ( STDMETHODCALLTYPE *IsCloserToLeaf )( + HRESULT ( STDMETHODCALLTYPE *IsCloserToLeaf )( ICorDebugInternalFrame2 * This, /* [in] */ ICorDebugFrame *pFrameToCompare, /* [out] */ BOOL *pIsCloser); - + END_INTERFACE } ICorDebugInternalFrame2Vtbl; @@ -11468,26 +11475,26 @@ EXTERN_C const IID IID_ICorDebugInternalFrame2; CONST_VTBL struct ICorDebugInternalFrame2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugInternalFrame2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugInternalFrame2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugInternalFrame2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugInternalFrame2_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugInternalFrame2_IsCloserToLeaf(This,pFrameToCompare,pIsCloser) \ - ( (This)->lpVtbl -> IsCloserToLeaf(This,pFrameToCompare,pIsCloser) ) + ( (This)->lpVtbl -> IsCloserToLeaf(This,pFrameToCompare,pIsCloser) ) #endif /* COBJMACROS */ @@ -11504,9 +11511,9 @@ EXTERN_C const IID IID_ICorDebugInternalFrame2; #define __ICorDebugILFrame_INTERFACE_DEFINED__ /* interface ICorDebugILFrame */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugMappingResult { MAPPING_PROLOG = 0x1, @@ -11521,156 +11528,156 @@ enum CorDebugMappingResult EXTERN_C const IID IID_ICorDebugILFrame; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("03E26311-4F76-11d3-88C6-006097945418") ICorDebugILFrame : public ICorDebugFrame { public: - virtual HRESULT STDMETHODCALLTYPE GetIP( + virtual HRESULT STDMETHODCALLTYPE GetIP( /* [out] */ ULONG32 *pnOffset, /* [out] */ CorDebugMappingResult *pMappingResult) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetIP( + + virtual HRESULT STDMETHODCALLTYPE SetIP( /* [in] */ ULONG32 nOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateLocalVariables( + + virtual HRESULT STDMETHODCALLTYPE EnumerateLocalVariables( /* [out] */ ICorDebugValueEnum **ppValueEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalVariable( + + virtual HRESULT STDMETHODCALLTYPE GetLocalVariable( /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateArguments( + + virtual HRESULT STDMETHODCALLTYPE EnumerateArguments( /* [out] */ ICorDebugValueEnum **ppValueEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetArgument( + + virtual HRESULT STDMETHODCALLTYPE GetArgument( /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStackDepth( + + virtual HRESULT STDMETHODCALLTYPE GetStackDepth( /* [out] */ ULONG32 *pDepth) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStackValue( + + virtual HRESULT STDMETHODCALLTYPE GetStackValue( /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE CanSetIP( + + virtual HRESULT STDMETHODCALLTYPE CanSetIP( /* [in] */ ULONG32 nOffset) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugILFrameVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugILFrame * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugILFrame * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugILFrame * This); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetChain) - HRESULT ( STDMETHODCALLTYPE *GetChain )( + HRESULT ( STDMETHODCALLTYPE *GetChain )( ICorDebugILFrame * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugILFrame * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugILFrame * This, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunctionToken) - HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( ICorDebugILFrame * This, /* [out] */ mdMethodDef *pToken); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetStackRange) - HRESULT ( STDMETHODCALLTYPE *GetStackRange )( + HRESULT ( STDMETHODCALLTYPE *GetStackRange )( ICorDebugILFrame * This, /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCaller) - HRESULT ( STDMETHODCALLTYPE *GetCaller )( + HRESULT ( STDMETHODCALLTYPE *GetCaller )( ICorDebugILFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCallee) - HRESULT ( STDMETHODCALLTYPE *GetCallee )( + HRESULT ( STDMETHODCALLTYPE *GetCallee )( ICorDebugILFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, CreateStepper) - HRESULT ( STDMETHODCALLTYPE *CreateStepper )( + HRESULT ( STDMETHODCALLTYPE *CreateStepper )( ICorDebugILFrame * This, /* [out] */ ICorDebugStepper **ppStepper); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, GetIP) - HRESULT ( STDMETHODCALLTYPE *GetIP )( + HRESULT ( STDMETHODCALLTYPE *GetIP )( ICorDebugILFrame * This, /* [out] */ ULONG32 *pnOffset, /* [out] */ CorDebugMappingResult *pMappingResult); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, SetIP) - HRESULT ( STDMETHODCALLTYPE *SetIP )( + HRESULT ( STDMETHODCALLTYPE *SetIP )( ICorDebugILFrame * This, /* [in] */ ULONG32 nOffset); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, EnumerateLocalVariables) - HRESULT ( STDMETHODCALLTYPE *EnumerateLocalVariables )( + HRESULT ( STDMETHODCALLTYPE *EnumerateLocalVariables )( ICorDebugILFrame * This, /* [out] */ ICorDebugValueEnum **ppValueEnum); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, GetLocalVariable) - HRESULT ( STDMETHODCALLTYPE *GetLocalVariable )( + HRESULT ( STDMETHODCALLTYPE *GetLocalVariable )( ICorDebugILFrame * This, /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, EnumerateArguments) - HRESULT ( STDMETHODCALLTYPE *EnumerateArguments )( + HRESULT ( STDMETHODCALLTYPE *EnumerateArguments )( ICorDebugILFrame * This, /* [out] */ ICorDebugValueEnum **ppValueEnum); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, GetArgument) - HRESULT ( STDMETHODCALLTYPE *GetArgument )( + HRESULT ( STDMETHODCALLTYPE *GetArgument )( ICorDebugILFrame * This, /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, GetStackDepth) - HRESULT ( STDMETHODCALLTYPE *GetStackDepth )( + HRESULT ( STDMETHODCALLTYPE *GetStackDepth )( ICorDebugILFrame * This, /* [out] */ ULONG32 *pDepth); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, GetStackValue) - HRESULT ( STDMETHODCALLTYPE *GetStackValue )( + HRESULT ( STDMETHODCALLTYPE *GetStackValue )( ICorDebugILFrame * This, /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugILFrame, CanSetIP) - HRESULT ( STDMETHODCALLTYPE *CanSetIP )( + HRESULT ( STDMETHODCALLTYPE *CanSetIP )( ICorDebugILFrame * This, /* [in] */ ULONG32 nOffset); - + END_INTERFACE } ICorDebugILFrameVtbl; @@ -11679,72 +11686,72 @@ EXTERN_C const IID IID_ICorDebugILFrame; CONST_VTBL struct ICorDebugILFrameVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugILFrame_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugILFrame_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugILFrame_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugILFrame_GetChain(This,ppChain) \ - ( (This)->lpVtbl -> GetChain(This,ppChain) ) + ( (This)->lpVtbl -> GetChain(This,ppChain) ) #define ICorDebugILFrame_GetCode(This,ppCode) \ - ( (This)->lpVtbl -> GetCode(This,ppCode) ) + ( (This)->lpVtbl -> GetCode(This,ppCode) ) #define ICorDebugILFrame_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #define ICorDebugILFrame_GetFunctionToken(This,pToken) \ - ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) + ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) #define ICorDebugILFrame_GetStackRange(This,pStart,pEnd) \ - ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) + ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) #define ICorDebugILFrame_GetCaller(This,ppFrame) \ - ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) + ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) #define ICorDebugILFrame_GetCallee(This,ppFrame) \ - ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) + ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) #define ICorDebugILFrame_CreateStepper(This,ppStepper) \ - ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) + ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) #define ICorDebugILFrame_GetIP(This,pnOffset,pMappingResult) \ - ( (This)->lpVtbl -> GetIP(This,pnOffset,pMappingResult) ) + ( (This)->lpVtbl -> GetIP(This,pnOffset,pMappingResult) ) #define ICorDebugILFrame_SetIP(This,nOffset) \ - ( (This)->lpVtbl -> SetIP(This,nOffset) ) + ( (This)->lpVtbl -> SetIP(This,nOffset) ) #define ICorDebugILFrame_EnumerateLocalVariables(This,ppValueEnum) \ - ( (This)->lpVtbl -> EnumerateLocalVariables(This,ppValueEnum) ) + ( (This)->lpVtbl -> EnumerateLocalVariables(This,ppValueEnum) ) #define ICorDebugILFrame_GetLocalVariable(This,dwIndex,ppValue) \ - ( (This)->lpVtbl -> GetLocalVariable(This,dwIndex,ppValue) ) + ( (This)->lpVtbl -> GetLocalVariable(This,dwIndex,ppValue) ) #define ICorDebugILFrame_EnumerateArguments(This,ppValueEnum) \ - ( (This)->lpVtbl -> EnumerateArguments(This,ppValueEnum) ) + ( (This)->lpVtbl -> EnumerateArguments(This,ppValueEnum) ) #define ICorDebugILFrame_GetArgument(This,dwIndex,ppValue) \ - ( (This)->lpVtbl -> GetArgument(This,dwIndex,ppValue) ) + ( (This)->lpVtbl -> GetArgument(This,dwIndex,ppValue) ) #define ICorDebugILFrame_GetStackDepth(This,pDepth) \ - ( (This)->lpVtbl -> GetStackDepth(This,pDepth) ) + ( (This)->lpVtbl -> GetStackDepth(This,pDepth) ) #define ICorDebugILFrame_GetStackValue(This,dwIndex,ppValue) \ - ( (This)->lpVtbl -> GetStackValue(This,dwIndex,ppValue) ) + ( (This)->lpVtbl -> GetStackValue(This,dwIndex,ppValue) ) #define ICorDebugILFrame_CanSetIP(This,nOffset) \ - ( (This)->lpVtbl -> CanSetIP(This,nOffset) ) + ( (This)->lpVtbl -> CanSetIP(This,nOffset) ) #endif /* COBJMACROS */ @@ -11761,57 +11768,57 @@ EXTERN_C const IID IID_ICorDebugILFrame; #define __ICorDebugILFrame2_INTERFACE_DEFINED__ /* interface ICorDebugILFrame2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugILFrame2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("5D88A994-6C30-479b-890F-BCEF88B129A5") ICorDebugILFrame2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE RemapFunction( + virtual HRESULT STDMETHODCALLTYPE RemapFunction( /* [in] */ ULONG32 newILOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateTypeParameters( + + virtual HRESULT STDMETHODCALLTYPE EnumerateTypeParameters( /* [out] */ ICorDebugTypeEnum **ppTyParEnum) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugILFrame2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugILFrame2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugILFrame2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugILFrame2 * This); - + DECLSPEC_XFGVIRT(ICorDebugILFrame2, RemapFunction) - HRESULT ( STDMETHODCALLTYPE *RemapFunction )( + HRESULT ( STDMETHODCALLTYPE *RemapFunction )( ICorDebugILFrame2 * This, /* [in] */ ULONG32 newILOffset); - + DECLSPEC_XFGVIRT(ICorDebugILFrame2, EnumerateTypeParameters) - HRESULT ( STDMETHODCALLTYPE *EnumerateTypeParameters )( + HRESULT ( STDMETHODCALLTYPE *EnumerateTypeParameters )( ICorDebugILFrame2 * This, /* [out] */ ICorDebugTypeEnum **ppTyParEnum); - + END_INTERFACE } ICorDebugILFrame2Vtbl; @@ -11820,26 +11827,26 @@ EXTERN_C const IID IID_ICorDebugILFrame2; CONST_VTBL struct ICorDebugILFrame2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugILFrame2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugILFrame2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugILFrame2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugILFrame2_RemapFunction(This,newILOffset) \ - ( (This)->lpVtbl -> RemapFunction(This,newILOffset) ) + ( (This)->lpVtbl -> RemapFunction(This,newILOffset) ) #define ICorDebugILFrame2_EnumerateTypeParameters(This,ppTyParEnum) \ - ( (This)->lpVtbl -> EnumerateTypeParameters(This,ppTyParEnum) ) + ( (This)->lpVtbl -> EnumerateTypeParameters(This,ppTyParEnum) ) #endif /* COBJMACROS */ @@ -11856,51 +11863,51 @@ EXTERN_C const IID IID_ICorDebugILFrame2; #define __ICorDebugILFrame3_INTERFACE_DEFINED__ /* interface ICorDebugILFrame3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugILFrame3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("9A9E2ED6-04DF-4FE0-BB50-CAB64126AD24") ICorDebugILFrame3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetReturnValueForILOffset( + virtual HRESULT STDMETHODCALLTYPE GetReturnValueForILOffset( ULONG32 ILoffset, /* [out] */ ICorDebugValue **ppReturnValue) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugILFrame3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugILFrame3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugILFrame3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugILFrame3 * This); - + DECLSPEC_XFGVIRT(ICorDebugILFrame3, GetReturnValueForILOffset) - HRESULT ( STDMETHODCALLTYPE *GetReturnValueForILOffset )( + HRESULT ( STDMETHODCALLTYPE *GetReturnValueForILOffset )( ICorDebugILFrame3 * This, ULONG32 ILoffset, /* [out] */ ICorDebugValue **ppReturnValue); - + END_INTERFACE } ICorDebugILFrame3Vtbl; @@ -11909,23 +11916,23 @@ EXTERN_C const IID IID_ICorDebugILFrame3; CONST_VTBL struct ICorDebugILFrame3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugILFrame3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugILFrame3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugILFrame3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugILFrame3_GetReturnValueForILOffset(This,ILoffset,ppReturnValue) \ - ( (This)->lpVtbl -> GetReturnValueForILOffset(This,ILoffset,ppReturnValue) ) + ( (This)->lpVtbl -> GetReturnValueForILOffset(This,ILoffset,ppReturnValue) ) #endif /* COBJMACROS */ @@ -11939,9 +11946,9 @@ EXTERN_C const IID IID_ICorDebugILFrame3; /* interface __MIDL_itf_cordebug_0000_0070 */ -/* [local] */ +/* [local] */ -typedef +typedef enum ILCodeKind { ILCODE_ORIGINAL_IL = 0x1, @@ -11957,73 +11964,73 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0070_v0_0_s_ifspec; #define __ICorDebugILFrame4_INTERFACE_DEFINED__ /* interface ICorDebugILFrame4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugILFrame4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("AD914A30-C6D1-4AC5-9C5E-577F3BAA8A45") ICorDebugILFrame4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE EnumerateLocalVariablesEx( + virtual HRESULT STDMETHODCALLTYPE EnumerateLocalVariablesEx( /* [in] */ ILCodeKind flags, /* [out] */ ICorDebugValueEnum **ppValueEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalVariableEx( + + virtual HRESULT STDMETHODCALLTYPE GetLocalVariableEx( /* [in] */ ILCodeKind flags, /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCodeEx( + + virtual HRESULT STDMETHODCALLTYPE GetCodeEx( /* [in] */ ILCodeKind flags, /* [out] */ ICorDebugCode **ppCode) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugILFrame4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugILFrame4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugILFrame4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugILFrame4 * This); - + DECLSPEC_XFGVIRT(ICorDebugILFrame4, EnumerateLocalVariablesEx) - HRESULT ( STDMETHODCALLTYPE *EnumerateLocalVariablesEx )( + HRESULT ( STDMETHODCALLTYPE *EnumerateLocalVariablesEx )( ICorDebugILFrame4 * This, /* [in] */ ILCodeKind flags, /* [out] */ ICorDebugValueEnum **ppValueEnum); - + DECLSPEC_XFGVIRT(ICorDebugILFrame4, GetLocalVariableEx) - HRESULT ( STDMETHODCALLTYPE *GetLocalVariableEx )( + HRESULT ( STDMETHODCALLTYPE *GetLocalVariableEx )( ICorDebugILFrame4 * This, /* [in] */ ILCodeKind flags, /* [in] */ DWORD dwIndex, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugILFrame4, GetCodeEx) - HRESULT ( STDMETHODCALLTYPE *GetCodeEx )( + HRESULT ( STDMETHODCALLTYPE *GetCodeEx )( ICorDebugILFrame4 * This, /* [in] */ ILCodeKind flags, /* [out] */ ICorDebugCode **ppCode); - + END_INTERFACE } ICorDebugILFrame4Vtbl; @@ -12032,29 +12039,29 @@ EXTERN_C const IID IID_ICorDebugILFrame4; CONST_VTBL struct ICorDebugILFrame4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugILFrame4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugILFrame4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugILFrame4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugILFrame4_EnumerateLocalVariablesEx(This,flags,ppValueEnum) \ - ( (This)->lpVtbl -> EnumerateLocalVariablesEx(This,flags,ppValueEnum) ) + ( (This)->lpVtbl -> EnumerateLocalVariablesEx(This,flags,ppValueEnum) ) #define ICorDebugILFrame4_GetLocalVariableEx(This,flags,dwIndex,ppValue) \ - ( (This)->lpVtbl -> GetLocalVariableEx(This,flags,dwIndex,ppValue) ) + ( (This)->lpVtbl -> GetLocalVariableEx(This,flags,dwIndex,ppValue) ) #define ICorDebugILFrame4_GetCodeEx(This,flags,ppCode) \ - ( (This)->lpVtbl -> GetCodeEx(This,flags,ppCode) ) + ( (This)->lpVtbl -> GetCodeEx(This,flags,ppCode) ) #endif /* COBJMACROS */ @@ -12071,190 +12078,190 @@ EXTERN_C const IID IID_ICorDebugILFrame4; #define __ICorDebugNativeFrame_INTERFACE_DEFINED__ /* interface ICorDebugNativeFrame */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugNativeFrame; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("03E26314-4F76-11d3-88C6-006097945418") ICorDebugNativeFrame : public ICorDebugFrame { public: - virtual HRESULT STDMETHODCALLTYPE GetIP( + virtual HRESULT STDMETHODCALLTYPE GetIP( /* [out] */ ULONG32 *pnOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetIP( + + virtual HRESULT STDMETHODCALLTYPE SetIP( /* [in] */ ULONG32 nOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRegisterSet( + + virtual HRESULT STDMETHODCALLTYPE GetRegisterSet( /* [out] */ ICorDebugRegisterSet **ppRegisters) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalRegisterValue( + + virtual HRESULT STDMETHODCALLTYPE GetLocalRegisterValue( /* [in] */ CorDebugRegister reg, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalDoubleRegisterValue( + + virtual HRESULT STDMETHODCALLTYPE GetLocalDoubleRegisterValue( /* [in] */ CorDebugRegister highWordReg, /* [in] */ CorDebugRegister lowWordReg, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalMemoryValue( + + virtual HRESULT STDMETHODCALLTYPE GetLocalMemoryValue( /* [in] */ CORDB_ADDRESS address, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalRegisterMemoryValue( + + virtual HRESULT STDMETHODCALLTYPE GetLocalRegisterMemoryValue( /* [in] */ CorDebugRegister highWordReg, /* [in] */ CORDB_ADDRESS lowWordAddress, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalMemoryRegisterValue( + + virtual HRESULT STDMETHODCALLTYPE GetLocalMemoryRegisterValue( /* [in] */ CORDB_ADDRESS highWordAddress, /* [in] */ CorDebugRegister lowWordRegister, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE CanSetIP( + + virtual HRESULT STDMETHODCALLTYPE CanSetIP( /* [in] */ ULONG32 nOffset) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugNativeFrameVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugNativeFrame * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugNativeFrame * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugNativeFrame * This); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetChain) - HRESULT ( STDMETHODCALLTYPE *GetChain )( + HRESULT ( STDMETHODCALLTYPE *GetChain )( ICorDebugNativeFrame * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugNativeFrame * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugNativeFrame * This, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunctionToken) - HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( ICorDebugNativeFrame * This, /* [out] */ mdMethodDef *pToken); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetStackRange) - HRESULT ( STDMETHODCALLTYPE *GetStackRange )( + HRESULT ( STDMETHODCALLTYPE *GetStackRange )( ICorDebugNativeFrame * This, /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCaller) - HRESULT ( STDMETHODCALLTYPE *GetCaller )( + HRESULT ( STDMETHODCALLTYPE *GetCaller )( ICorDebugNativeFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCallee) - HRESULT ( STDMETHODCALLTYPE *GetCallee )( + HRESULT ( STDMETHODCALLTYPE *GetCallee )( ICorDebugNativeFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, CreateStepper) - HRESULT ( STDMETHODCALLTYPE *CreateStepper )( + HRESULT ( STDMETHODCALLTYPE *CreateStepper )( ICorDebugNativeFrame * This, /* [out] */ ICorDebugStepper **ppStepper); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, GetIP) - HRESULT ( STDMETHODCALLTYPE *GetIP )( + HRESULT ( STDMETHODCALLTYPE *GetIP )( ICorDebugNativeFrame * This, /* [out] */ ULONG32 *pnOffset); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, SetIP) - HRESULT ( STDMETHODCALLTYPE *SetIP )( + HRESULT ( STDMETHODCALLTYPE *SetIP )( ICorDebugNativeFrame * This, /* [in] */ ULONG32 nOffset); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, GetRegisterSet) - HRESULT ( STDMETHODCALLTYPE *GetRegisterSet )( + HRESULT ( STDMETHODCALLTYPE *GetRegisterSet )( ICorDebugNativeFrame * This, /* [out] */ ICorDebugRegisterSet **ppRegisters); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, GetLocalRegisterValue) - HRESULT ( STDMETHODCALLTYPE *GetLocalRegisterValue )( + HRESULT ( STDMETHODCALLTYPE *GetLocalRegisterValue )( ICorDebugNativeFrame * This, /* [in] */ CorDebugRegister reg, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, GetLocalDoubleRegisterValue) - HRESULT ( STDMETHODCALLTYPE *GetLocalDoubleRegisterValue )( + HRESULT ( STDMETHODCALLTYPE *GetLocalDoubleRegisterValue )( ICorDebugNativeFrame * This, /* [in] */ CorDebugRegister highWordReg, /* [in] */ CorDebugRegister lowWordReg, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, GetLocalMemoryValue) - HRESULT ( STDMETHODCALLTYPE *GetLocalMemoryValue )( + HRESULT ( STDMETHODCALLTYPE *GetLocalMemoryValue )( ICorDebugNativeFrame * This, /* [in] */ CORDB_ADDRESS address, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, GetLocalRegisterMemoryValue) - HRESULT ( STDMETHODCALLTYPE *GetLocalRegisterMemoryValue )( + HRESULT ( STDMETHODCALLTYPE *GetLocalRegisterMemoryValue )( ICorDebugNativeFrame * This, /* [in] */ CorDebugRegister highWordReg, /* [in] */ CORDB_ADDRESS lowWordAddress, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, GetLocalMemoryRegisterValue) - HRESULT ( STDMETHODCALLTYPE *GetLocalMemoryRegisterValue )( + HRESULT ( STDMETHODCALLTYPE *GetLocalMemoryRegisterValue )( ICorDebugNativeFrame * This, /* [in] */ CORDB_ADDRESS highWordAddress, /* [in] */ CorDebugRegister lowWordRegister, /* [in] */ ULONG cbSigBlob, /* [in] */ PCCOR_SIGNATURE pvSigBlob, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame, CanSetIP) - HRESULT ( STDMETHODCALLTYPE *CanSetIP )( + HRESULT ( STDMETHODCALLTYPE *CanSetIP )( ICorDebugNativeFrame * This, /* [in] */ ULONG32 nOffset); - + END_INTERFACE } ICorDebugNativeFrameVtbl; @@ -12263,72 +12270,72 @@ EXTERN_C const IID IID_ICorDebugNativeFrame; CONST_VTBL struct ICorDebugNativeFrameVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugNativeFrame_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugNativeFrame_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugNativeFrame_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugNativeFrame_GetChain(This,ppChain) \ - ( (This)->lpVtbl -> GetChain(This,ppChain) ) + ( (This)->lpVtbl -> GetChain(This,ppChain) ) #define ICorDebugNativeFrame_GetCode(This,ppCode) \ - ( (This)->lpVtbl -> GetCode(This,ppCode) ) + ( (This)->lpVtbl -> GetCode(This,ppCode) ) #define ICorDebugNativeFrame_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #define ICorDebugNativeFrame_GetFunctionToken(This,pToken) \ - ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) + ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) #define ICorDebugNativeFrame_GetStackRange(This,pStart,pEnd) \ - ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) + ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) #define ICorDebugNativeFrame_GetCaller(This,ppFrame) \ - ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) + ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) #define ICorDebugNativeFrame_GetCallee(This,ppFrame) \ - ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) + ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) #define ICorDebugNativeFrame_CreateStepper(This,ppStepper) \ - ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) + ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) #define ICorDebugNativeFrame_GetIP(This,pnOffset) \ - ( (This)->lpVtbl -> GetIP(This,pnOffset) ) + ( (This)->lpVtbl -> GetIP(This,pnOffset) ) #define ICorDebugNativeFrame_SetIP(This,nOffset) \ - ( (This)->lpVtbl -> SetIP(This,nOffset) ) + ( (This)->lpVtbl -> SetIP(This,nOffset) ) #define ICorDebugNativeFrame_GetRegisterSet(This,ppRegisters) \ - ( (This)->lpVtbl -> GetRegisterSet(This,ppRegisters) ) + ( (This)->lpVtbl -> GetRegisterSet(This,ppRegisters) ) #define ICorDebugNativeFrame_GetLocalRegisterValue(This,reg,cbSigBlob,pvSigBlob,ppValue) \ - ( (This)->lpVtbl -> GetLocalRegisterValue(This,reg,cbSigBlob,pvSigBlob,ppValue) ) + ( (This)->lpVtbl -> GetLocalRegisterValue(This,reg,cbSigBlob,pvSigBlob,ppValue) ) #define ICorDebugNativeFrame_GetLocalDoubleRegisterValue(This,highWordReg,lowWordReg,cbSigBlob,pvSigBlob,ppValue) \ - ( (This)->lpVtbl -> GetLocalDoubleRegisterValue(This,highWordReg,lowWordReg,cbSigBlob,pvSigBlob,ppValue) ) + ( (This)->lpVtbl -> GetLocalDoubleRegisterValue(This,highWordReg,lowWordReg,cbSigBlob,pvSigBlob,ppValue) ) #define ICorDebugNativeFrame_GetLocalMemoryValue(This,address,cbSigBlob,pvSigBlob,ppValue) \ - ( (This)->lpVtbl -> GetLocalMemoryValue(This,address,cbSigBlob,pvSigBlob,ppValue) ) + ( (This)->lpVtbl -> GetLocalMemoryValue(This,address,cbSigBlob,pvSigBlob,ppValue) ) #define ICorDebugNativeFrame_GetLocalRegisterMemoryValue(This,highWordReg,lowWordAddress,cbSigBlob,pvSigBlob,ppValue) \ - ( (This)->lpVtbl -> GetLocalRegisterMemoryValue(This,highWordReg,lowWordAddress,cbSigBlob,pvSigBlob,ppValue) ) + ( (This)->lpVtbl -> GetLocalRegisterMemoryValue(This,highWordReg,lowWordAddress,cbSigBlob,pvSigBlob,ppValue) ) #define ICorDebugNativeFrame_GetLocalMemoryRegisterValue(This,highWordAddress,lowWordRegister,cbSigBlob,pvSigBlob,ppValue) \ - ( (This)->lpVtbl -> GetLocalMemoryRegisterValue(This,highWordAddress,lowWordRegister,cbSigBlob,pvSigBlob,ppValue) ) + ( (This)->lpVtbl -> GetLocalMemoryRegisterValue(This,highWordAddress,lowWordRegister,cbSigBlob,pvSigBlob,ppValue) ) #define ICorDebugNativeFrame_CanSetIP(This,nOffset) \ - ( (This)->lpVtbl -> CanSetIP(This,nOffset) ) + ( (This)->lpVtbl -> CanSetIP(This,nOffset) ) #endif /* COBJMACROS */ @@ -12342,10 +12349,10 @@ EXTERN_C const IID IID_ICorDebugNativeFrame; /* interface __MIDL_itf_cordebug_0000_0072 */ -/* [local] */ +/* [local] */ #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0072_v0_0_c_ifspec; @@ -12355,67 +12362,67 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0072_v0_0_s_ifspec; #define __ICorDebugNativeFrame2_INTERFACE_DEFINED__ /* interface ICorDebugNativeFrame2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugNativeFrame2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("35389FF1-3684-4c55-A2EE-210F26C60E5E") ICorDebugNativeFrame2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE IsChild( + virtual HRESULT STDMETHODCALLTYPE IsChild( /* [out] */ BOOL *pIsChild) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsMatchingParentFrame( + + virtual HRESULT STDMETHODCALLTYPE IsMatchingParentFrame( /* [in] */ ICorDebugNativeFrame2 *pPotentialParentFrame, /* [out] */ BOOL *pIsParent) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStackParameterSize( + + virtual HRESULT STDMETHODCALLTYPE GetStackParameterSize( /* [out] */ ULONG32 *pSize) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugNativeFrame2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugNativeFrame2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugNativeFrame2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugNativeFrame2 * This); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame2, IsChild) - HRESULT ( STDMETHODCALLTYPE *IsChild )( + HRESULT ( STDMETHODCALLTYPE *IsChild )( ICorDebugNativeFrame2 * This, /* [out] */ BOOL *pIsChild); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame2, IsMatchingParentFrame) - HRESULT ( STDMETHODCALLTYPE *IsMatchingParentFrame )( + HRESULT ( STDMETHODCALLTYPE *IsMatchingParentFrame )( ICorDebugNativeFrame2 * This, /* [in] */ ICorDebugNativeFrame2 *pPotentialParentFrame, /* [out] */ BOOL *pIsParent); - + DECLSPEC_XFGVIRT(ICorDebugNativeFrame2, GetStackParameterSize) - HRESULT ( STDMETHODCALLTYPE *GetStackParameterSize )( + HRESULT ( STDMETHODCALLTYPE *GetStackParameterSize )( ICorDebugNativeFrame2 * This, /* [out] */ ULONG32 *pSize); - + END_INTERFACE } ICorDebugNativeFrame2Vtbl; @@ -12424,29 +12431,29 @@ EXTERN_C const IID IID_ICorDebugNativeFrame2; CONST_VTBL struct ICorDebugNativeFrame2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugNativeFrame2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugNativeFrame2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugNativeFrame2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugNativeFrame2_IsChild(This,pIsChild) \ - ( (This)->lpVtbl -> IsChild(This,pIsChild) ) + ( (This)->lpVtbl -> IsChild(This,pIsChild) ) #define ICorDebugNativeFrame2_IsMatchingParentFrame(This,pPotentialParentFrame,pIsParent) \ - ( (This)->lpVtbl -> IsMatchingParentFrame(This,pPotentialParentFrame,pIsParent) ) + ( (This)->lpVtbl -> IsMatchingParentFrame(This,pPotentialParentFrame,pIsParent) ) #define ICorDebugNativeFrame2_GetStackParameterSize(This,pSize) \ - ( (This)->lpVtbl -> GetStackParameterSize(This,pSize) ) + ( (This)->lpVtbl -> GetStackParameterSize(This,pSize) ) #endif /* COBJMACROS */ @@ -12463,51 +12470,51 @@ EXTERN_C const IID IID_ICorDebugNativeFrame2; #define __ICorDebugModule3_INTERFACE_DEFINED__ /* interface ICorDebugModule3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugModule3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("86F012BF-FF15-4372-BD30-B6F11CAAE1DD") ICorDebugModule3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CreateReaderForInMemorySymbols( + virtual HRESULT STDMETHODCALLTYPE CreateReaderForInMemorySymbols( /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppObj) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugModule3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugModule3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugModule3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugModule3 * This); - + DECLSPEC_XFGVIRT(ICorDebugModule3, CreateReaderForInMemorySymbols) - HRESULT ( STDMETHODCALLTYPE *CreateReaderForInMemorySymbols )( + HRESULT ( STDMETHODCALLTYPE *CreateReaderForInMemorySymbols )( ICorDebugModule3 * This, /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppObj); - + END_INTERFACE } ICorDebugModule3Vtbl; @@ -12516,23 +12523,23 @@ EXTERN_C const IID IID_ICorDebugModule3; CONST_VTBL struct ICorDebugModule3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugModule3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugModule3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugModule3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugModule3_CreateReaderForInMemorySymbols(This,riid,ppObj) \ - ( (This)->lpVtbl -> CreateReaderForInMemorySymbols(This,riid,ppObj) ) + ( (This)->lpVtbl -> CreateReaderForInMemorySymbols(This,riid,ppObj) ) #endif /* COBJMACROS */ @@ -12549,49 +12556,49 @@ EXTERN_C const IID IID_ICorDebugModule3; #define __ICorDebugModule4_INTERFACE_DEFINED__ /* interface ICorDebugModule4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugModule4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("FF8B8EAF-25CD-4316-8859-84416DE4402E") ICorDebugModule4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE IsMappedLayout( + virtual HRESULT STDMETHODCALLTYPE IsMappedLayout( /* [out] */ BOOL *pIsMapped) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugModule4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugModule4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugModule4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugModule4 * This); - + DECLSPEC_XFGVIRT(ICorDebugModule4, IsMappedLayout) - HRESULT ( STDMETHODCALLTYPE *IsMappedLayout )( + HRESULT ( STDMETHODCALLTYPE *IsMappedLayout )( ICorDebugModule4 * This, /* [out] */ BOOL *pIsMapped); - + END_INTERFACE } ICorDebugModule4Vtbl; @@ -12600,23 +12607,23 @@ EXTERN_C const IID IID_ICorDebugModule4; CONST_VTBL struct ICorDebugModule4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugModule4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugModule4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugModule4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugModule4_IsMappedLayout(This,pIsMapped) \ - ( (This)->lpVtbl -> IsMappedLayout(This,pIsMapped) ) + ( (This)->lpVtbl -> IsMappedLayout(This,pIsMapped) ) #endif /* COBJMACROS */ @@ -12633,82 +12640,82 @@ EXTERN_C const IID IID_ICorDebugModule4; #define __ICorDebugRuntimeUnwindableFrame_INTERFACE_DEFINED__ /* interface ICorDebugRuntimeUnwindableFrame */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugRuntimeUnwindableFrame; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("879CAC0A-4A53-4668-B8E3-CB8473CB187F") ICorDebugRuntimeUnwindableFrame : public ICorDebugFrame { public: }; - - + + #else /* C style interface */ typedef struct ICorDebugRuntimeUnwindableFrameVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugRuntimeUnwindableFrame * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugRuntimeUnwindableFrame * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugRuntimeUnwindableFrame * This); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetChain) - HRESULT ( STDMETHODCALLTYPE *GetChain )( + HRESULT ( STDMETHODCALLTYPE *GetChain )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ ICorDebugChain **ppChain); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetFunctionToken) - HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionToken )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ mdMethodDef *pToken); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetStackRange) - HRESULT ( STDMETHODCALLTYPE *GetStackRange )( + HRESULT ( STDMETHODCALLTYPE *GetStackRange )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ CORDB_ADDRESS *pStart, /* [out] */ CORDB_ADDRESS *pEnd); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCaller) - HRESULT ( STDMETHODCALLTYPE *GetCaller )( + HRESULT ( STDMETHODCALLTYPE *GetCaller )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, GetCallee) - HRESULT ( STDMETHODCALLTYPE *GetCallee )( + HRESULT ( STDMETHODCALLTYPE *GetCallee )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ ICorDebugFrame **ppFrame); - + DECLSPEC_XFGVIRT(ICorDebugFrame, CreateStepper) - HRESULT ( STDMETHODCALLTYPE *CreateStepper )( + HRESULT ( STDMETHODCALLTYPE *CreateStepper )( ICorDebugRuntimeUnwindableFrame * This, /* [out] */ ICorDebugStepper **ppStepper); - + END_INTERFACE } ICorDebugRuntimeUnwindableFrameVtbl; @@ -12717,44 +12724,44 @@ EXTERN_C const IID IID_ICorDebugRuntimeUnwindableFrame; CONST_VTBL struct ICorDebugRuntimeUnwindableFrameVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugRuntimeUnwindableFrame_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugRuntimeUnwindableFrame_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugRuntimeUnwindableFrame_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugRuntimeUnwindableFrame_GetChain(This,ppChain) \ - ( (This)->lpVtbl -> GetChain(This,ppChain) ) + ( (This)->lpVtbl -> GetChain(This,ppChain) ) #define ICorDebugRuntimeUnwindableFrame_GetCode(This,ppCode) \ - ( (This)->lpVtbl -> GetCode(This,ppCode) ) + ( (This)->lpVtbl -> GetCode(This,ppCode) ) #define ICorDebugRuntimeUnwindableFrame_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #define ICorDebugRuntimeUnwindableFrame_GetFunctionToken(This,pToken) \ - ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) + ( (This)->lpVtbl -> GetFunctionToken(This,pToken) ) #define ICorDebugRuntimeUnwindableFrame_GetStackRange(This,pStart,pEnd) \ - ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) + ( (This)->lpVtbl -> GetStackRange(This,pStart,pEnd) ) #define ICorDebugRuntimeUnwindableFrame_GetCaller(This,ppFrame) \ - ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) + ( (This)->lpVtbl -> GetCaller(This,ppFrame) ) #define ICorDebugRuntimeUnwindableFrame_GetCallee(This,ppFrame) \ - ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) + ( (This)->lpVtbl -> GetCallee(This,ppFrame) ) #define ICorDebugRuntimeUnwindableFrame_CreateStepper(This,ppStepper) \ - ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) + ( (This)->lpVtbl -> CreateStepper(This,ppStepper) ) #endif /* COBJMACROS */ @@ -12772,193 +12779,193 @@ EXTERN_C const IID IID_ICorDebugRuntimeUnwindableFrame; #define __ICorDebugModule_INTERFACE_DEFINED__ /* interface ICorDebugModule */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugModule; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("dba2d8c1-e5c5-4069-8c13-10a7c6abf43d") ICorDebugModule : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetProcess( + virtual HRESULT STDMETHODCALLTYPE GetProcess( /* [out] */ ICorDebugProcess **ppProcess) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetBaseAddress( + + virtual HRESULT STDMETHODCALLTYPE GetBaseAddress( /* [out] */ CORDB_ADDRESS *pAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAssembly( + + virtual HRESULT STDMETHODCALLTYPE GetAssembly( /* [out] */ ICorDebugAssembly **ppAssembly) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetName( + + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnableJITDebugging( + + virtual HRESULT STDMETHODCALLTYPE EnableJITDebugging( /* [in] */ BOOL bTrackJITInfo, /* [in] */ BOOL bAllowJitOpts) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnableClassLoadCallbacks( + + virtual HRESULT STDMETHODCALLTYPE EnableClassLoadCallbacks( /* [in] */ BOOL bClassLoadCallbacks) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionFromToken( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionFromToken( /* [in] */ mdMethodDef methodDef, /* [out] */ ICorDebugFunction **ppFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunctionFromRVA( + + virtual HRESULT STDMETHODCALLTYPE GetFunctionFromRVA( /* [in] */ CORDB_ADDRESS rva, /* [out] */ ICorDebugFunction **ppFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClassFromToken( + + virtual HRESULT STDMETHODCALLTYPE GetClassFromToken( /* [in] */ mdTypeDef typeDef, /* [out] */ ICorDebugClass **ppClass) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( /* [out] */ ICorDebugModuleBreakpoint **ppBreakpoint) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetEditAndContinueSnapshot( + + virtual HRESULT STDMETHODCALLTYPE GetEditAndContinueSnapshot( /* [out] */ ICorDebugEditAndContinueSnapshot **ppEditAndContinueSnapshot) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetMetaDataInterface( + + virtual HRESULT STDMETHODCALLTYPE GetMetaDataInterface( /* [in] */ REFIID riid, /* [out] */ IUnknown **ppObj) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetToken( + + virtual HRESULT STDMETHODCALLTYPE GetToken( /* [out] */ mdModule *pToken) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsDynamic( + + virtual HRESULT STDMETHODCALLTYPE IsDynamic( /* [out] */ BOOL *pDynamic) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetGlobalVariableValue( + + virtual HRESULT STDMETHODCALLTYPE GetGlobalVariableValue( /* [in] */ mdFieldDef fieldDef, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pcBytes) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsInMemory( + + virtual HRESULT STDMETHODCALLTYPE IsInMemory( /* [out] */ BOOL *pInMemory) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugModuleVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugModule * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugModule * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugModule * This); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetProcess) - HRESULT ( STDMETHODCALLTYPE *GetProcess )( + HRESULT ( STDMETHODCALLTYPE *GetProcess )( ICorDebugModule * This, /* [out] */ ICorDebugProcess **ppProcess); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetBaseAddress) - HRESULT ( STDMETHODCALLTYPE *GetBaseAddress )( + HRESULT ( STDMETHODCALLTYPE *GetBaseAddress )( ICorDebugModule * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetAssembly) - HRESULT ( STDMETHODCALLTYPE *GetAssembly )( + HRESULT ( STDMETHODCALLTYPE *GetAssembly )( ICorDebugModule * This, /* [out] */ ICorDebugAssembly **ppAssembly); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugModule * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugModule, EnableJITDebugging) - HRESULT ( STDMETHODCALLTYPE *EnableJITDebugging )( + HRESULT ( STDMETHODCALLTYPE *EnableJITDebugging )( ICorDebugModule * This, /* [in] */ BOOL bTrackJITInfo, /* [in] */ BOOL bAllowJitOpts); - + DECLSPEC_XFGVIRT(ICorDebugModule, EnableClassLoadCallbacks) - HRESULT ( STDMETHODCALLTYPE *EnableClassLoadCallbacks )( + HRESULT ( STDMETHODCALLTYPE *EnableClassLoadCallbacks )( ICorDebugModule * This, /* [in] */ BOOL bClassLoadCallbacks); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetFunctionFromToken) - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )( ICorDebugModule * This, /* [in] */ mdMethodDef methodDef, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetFunctionFromRVA) - HRESULT ( STDMETHODCALLTYPE *GetFunctionFromRVA )( + HRESULT ( STDMETHODCALLTYPE *GetFunctionFromRVA )( ICorDebugModule * This, /* [in] */ CORDB_ADDRESS rva, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetClassFromToken) - HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( + HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )( ICorDebugModule * This, /* [in] */ mdTypeDef typeDef, /* [out] */ ICorDebugClass **ppClass); - + DECLSPEC_XFGVIRT(ICorDebugModule, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugModule * This, /* [out] */ ICorDebugModuleBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetEditAndContinueSnapshot) - HRESULT ( STDMETHODCALLTYPE *GetEditAndContinueSnapshot )( + HRESULT ( STDMETHODCALLTYPE *GetEditAndContinueSnapshot )( ICorDebugModule * This, /* [out] */ ICorDebugEditAndContinueSnapshot **ppEditAndContinueSnapshot); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetMetaDataInterface) - HRESULT ( STDMETHODCALLTYPE *GetMetaDataInterface )( + HRESULT ( STDMETHODCALLTYPE *GetMetaDataInterface )( ICorDebugModule * This, /* [in] */ REFIID riid, /* [out] */ IUnknown **ppObj); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetToken) - HRESULT ( STDMETHODCALLTYPE *GetToken )( + HRESULT ( STDMETHODCALLTYPE *GetToken )( ICorDebugModule * This, /* [out] */ mdModule *pToken); - + DECLSPEC_XFGVIRT(ICorDebugModule, IsDynamic) - HRESULT ( STDMETHODCALLTYPE *IsDynamic )( + HRESULT ( STDMETHODCALLTYPE *IsDynamic )( ICorDebugModule * This, /* [out] */ BOOL *pDynamic); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetGlobalVariableValue) - HRESULT ( STDMETHODCALLTYPE *GetGlobalVariableValue )( + HRESULT ( STDMETHODCALLTYPE *GetGlobalVariableValue )( ICorDebugModule * This, /* [in] */ mdFieldDef fieldDef, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugModule, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugModule * This, /* [out] */ ULONG32 *pcBytes); - + DECLSPEC_XFGVIRT(ICorDebugModule, IsInMemory) - HRESULT ( STDMETHODCALLTYPE *IsInMemory )( + HRESULT ( STDMETHODCALLTYPE *IsInMemory )( ICorDebugModule * This, /* [out] */ BOOL *pInMemory); - + END_INTERFACE } ICorDebugModuleVtbl; @@ -12967,71 +12974,71 @@ EXTERN_C const IID IID_ICorDebugModule; CONST_VTBL struct ICorDebugModuleVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugModule_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugModule_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugModule_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugModule_GetProcess(This,ppProcess) \ - ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) + ( (This)->lpVtbl -> GetProcess(This,ppProcess) ) #define ICorDebugModule_GetBaseAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetBaseAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetBaseAddress(This,pAddress) ) #define ICorDebugModule_GetAssembly(This,ppAssembly) \ - ( (This)->lpVtbl -> GetAssembly(This,ppAssembly) ) + ( (This)->lpVtbl -> GetAssembly(This,ppAssembly) ) #define ICorDebugModule_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #define ICorDebugModule_EnableJITDebugging(This,bTrackJITInfo,bAllowJitOpts) \ - ( (This)->lpVtbl -> EnableJITDebugging(This,bTrackJITInfo,bAllowJitOpts) ) + ( (This)->lpVtbl -> EnableJITDebugging(This,bTrackJITInfo,bAllowJitOpts) ) #define ICorDebugModule_EnableClassLoadCallbacks(This,bClassLoadCallbacks) \ - ( (This)->lpVtbl -> EnableClassLoadCallbacks(This,bClassLoadCallbacks) ) + ( (This)->lpVtbl -> EnableClassLoadCallbacks(This,bClassLoadCallbacks) ) #define ICorDebugModule_GetFunctionFromToken(This,methodDef,ppFunction) \ - ( (This)->lpVtbl -> GetFunctionFromToken(This,methodDef,ppFunction) ) + ( (This)->lpVtbl -> GetFunctionFromToken(This,methodDef,ppFunction) ) #define ICorDebugModule_GetFunctionFromRVA(This,rva,ppFunction) \ - ( (This)->lpVtbl -> GetFunctionFromRVA(This,rva,ppFunction) ) + ( (This)->lpVtbl -> GetFunctionFromRVA(This,rva,ppFunction) ) #define ICorDebugModule_GetClassFromToken(This,typeDef,ppClass) \ - ( (This)->lpVtbl -> GetClassFromToken(This,typeDef,ppClass) ) + ( (This)->lpVtbl -> GetClassFromToken(This,typeDef,ppClass) ) #define ICorDebugModule_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugModule_GetEditAndContinueSnapshot(This,ppEditAndContinueSnapshot) \ - ( (This)->lpVtbl -> GetEditAndContinueSnapshot(This,ppEditAndContinueSnapshot) ) + ( (This)->lpVtbl -> GetEditAndContinueSnapshot(This,ppEditAndContinueSnapshot) ) #define ICorDebugModule_GetMetaDataInterface(This,riid,ppObj) \ - ( (This)->lpVtbl -> GetMetaDataInterface(This,riid,ppObj) ) + ( (This)->lpVtbl -> GetMetaDataInterface(This,riid,ppObj) ) #define ICorDebugModule_GetToken(This,pToken) \ - ( (This)->lpVtbl -> GetToken(This,pToken) ) + ( (This)->lpVtbl -> GetToken(This,pToken) ) #define ICorDebugModule_IsDynamic(This,pDynamic) \ - ( (This)->lpVtbl -> IsDynamic(This,pDynamic) ) + ( (This)->lpVtbl -> IsDynamic(This,pDynamic) ) #define ICorDebugModule_GetGlobalVariableValue(This,fieldDef,ppValue) \ - ( (This)->lpVtbl -> GetGlobalVariableValue(This,fieldDef,ppValue) ) + ( (This)->lpVtbl -> GetGlobalVariableValue(This,fieldDef,ppValue) ) #define ICorDebugModule_GetSize(This,pcBytes) \ - ( (This)->lpVtbl -> GetSize(This,pcBytes) ) + ( (This)->lpVtbl -> GetSize(This,pcBytes) ) #define ICorDebugModule_IsInMemory(This,pInMemory) \ - ( (This)->lpVtbl -> IsInMemory(This,pInMemory) ) + ( (This)->lpVtbl -> IsInMemory(This,pInMemory) ) #endif /* COBJMACROS */ @@ -13045,7 +13052,7 @@ EXTERN_C const IID IID_ICorDebugModule; /* interface __MIDL_itf_cordebug_0000_0077 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -13057,93 +13064,93 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0077_v0_0_s_ifspec; #define __ICorDebugModule2_INTERFACE_DEFINED__ /* interface ICorDebugModule2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugModule2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("7FCC5FB5-49C0-41de-9938-3B88B5B9ADD7") ICorDebugModule2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE SetJMCStatus( + virtual HRESULT STDMETHODCALLTYPE SetJMCStatus( /* [in] */ BOOL bIsJustMyCode, /* [in] */ ULONG32 cTokens, /* [size_is][in] */ mdToken pTokens[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE ApplyChanges( + + virtual HRESULT STDMETHODCALLTYPE ApplyChanges( /* [in] */ ULONG cbMetadata, /* [size_is][in] */ BYTE pbMetadata[ ], /* [in] */ ULONG cbIL, /* [size_is][in] */ BYTE pbIL[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetJITCompilerFlags( + + virtual HRESULT STDMETHODCALLTYPE SetJITCompilerFlags( /* [in] */ DWORD dwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetJITCompilerFlags( + + virtual HRESULT STDMETHODCALLTYPE GetJITCompilerFlags( /* [out] */ DWORD *pdwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE ResolveAssembly( + + virtual HRESULT STDMETHODCALLTYPE ResolveAssembly( /* [in] */ mdToken tkAssemblyRef, /* [out] */ ICorDebugAssembly **ppAssembly) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugModule2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugModule2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugModule2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugModule2 * This); - + DECLSPEC_XFGVIRT(ICorDebugModule2, SetJMCStatus) - HRESULT ( STDMETHODCALLTYPE *SetJMCStatus )( + HRESULT ( STDMETHODCALLTYPE *SetJMCStatus )( ICorDebugModule2 * This, /* [in] */ BOOL bIsJustMyCode, /* [in] */ ULONG32 cTokens, /* [size_is][in] */ mdToken pTokens[ ]); - + DECLSPEC_XFGVIRT(ICorDebugModule2, ApplyChanges) - HRESULT ( STDMETHODCALLTYPE *ApplyChanges )( + HRESULT ( STDMETHODCALLTYPE *ApplyChanges )( ICorDebugModule2 * This, /* [in] */ ULONG cbMetadata, /* [size_is][in] */ BYTE pbMetadata[ ], /* [in] */ ULONG cbIL, /* [size_is][in] */ BYTE pbIL[ ]); - + DECLSPEC_XFGVIRT(ICorDebugModule2, SetJITCompilerFlags) - HRESULT ( STDMETHODCALLTYPE *SetJITCompilerFlags )( + HRESULT ( STDMETHODCALLTYPE *SetJITCompilerFlags )( ICorDebugModule2 * This, /* [in] */ DWORD dwFlags); - + DECLSPEC_XFGVIRT(ICorDebugModule2, GetJITCompilerFlags) - HRESULT ( STDMETHODCALLTYPE *GetJITCompilerFlags )( + HRESULT ( STDMETHODCALLTYPE *GetJITCompilerFlags )( ICorDebugModule2 * This, /* [out] */ DWORD *pdwFlags); - + DECLSPEC_XFGVIRT(ICorDebugModule2, ResolveAssembly) - HRESULT ( STDMETHODCALLTYPE *ResolveAssembly )( + HRESULT ( STDMETHODCALLTYPE *ResolveAssembly )( ICorDebugModule2 * This, /* [in] */ mdToken tkAssemblyRef, /* [out] */ ICorDebugAssembly **ppAssembly); - + END_INTERFACE } ICorDebugModule2Vtbl; @@ -13152,35 +13159,35 @@ EXTERN_C const IID IID_ICorDebugModule2; CONST_VTBL struct ICorDebugModule2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugModule2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugModule2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugModule2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugModule2_SetJMCStatus(This,bIsJustMyCode,cTokens,pTokens) \ - ( (This)->lpVtbl -> SetJMCStatus(This,bIsJustMyCode,cTokens,pTokens) ) + ( (This)->lpVtbl -> SetJMCStatus(This,bIsJustMyCode,cTokens,pTokens) ) #define ICorDebugModule2_ApplyChanges(This,cbMetadata,pbMetadata,cbIL,pbIL) \ - ( (This)->lpVtbl -> ApplyChanges(This,cbMetadata,pbMetadata,cbIL,pbIL) ) + ( (This)->lpVtbl -> ApplyChanges(This,cbMetadata,pbMetadata,cbIL,pbIL) ) #define ICorDebugModule2_SetJITCompilerFlags(This,dwFlags) \ - ( (This)->lpVtbl -> SetJITCompilerFlags(This,dwFlags) ) + ( (This)->lpVtbl -> SetJITCompilerFlags(This,dwFlags) ) #define ICorDebugModule2_GetJITCompilerFlags(This,pdwFlags) \ - ( (This)->lpVtbl -> GetJITCompilerFlags(This,pdwFlags) ) + ( (This)->lpVtbl -> GetJITCompilerFlags(This,pdwFlags) ) #define ICorDebugModule2_ResolveAssembly(This,tkAssemblyRef,ppAssembly) \ - ( (This)->lpVtbl -> ResolveAssembly(This,tkAssemblyRef,ppAssembly) ) + ( (This)->lpVtbl -> ResolveAssembly(This,tkAssemblyRef,ppAssembly) ) #endif /* COBJMACROS */ @@ -13197,105 +13204,105 @@ EXTERN_C const IID IID_ICorDebugModule2; #define __ICorDebugFunction_INTERFACE_DEFINED__ /* interface ICorDebugFunction */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFunction; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAF3-8A68-11d2-983C-0000F808342D") ICorDebugFunction : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetModule( + virtual HRESULT STDMETHODCALLTYPE GetModule( /* [out] */ ICorDebugModule **ppModule) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClass( + + virtual HRESULT STDMETHODCALLTYPE GetClass( /* [out] */ ICorDebugClass **ppClass) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetToken( + + virtual HRESULT STDMETHODCALLTYPE GetToken( /* [out] */ mdMethodDef *pMethodDef) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetILCode( + + virtual HRESULT STDMETHODCALLTYPE GetILCode( /* [out] */ ICorDebugCode **ppCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetNativeCode( + + virtual HRESULT STDMETHODCALLTYPE GetNativeCode( /* [out] */ ICorDebugCode **ppCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( /* [out] */ ICorDebugFunctionBreakpoint **ppBreakpoint) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocalVarSigToken( + + virtual HRESULT STDMETHODCALLTYPE GetLocalVarSigToken( /* [out] */ mdSignature *pmdSig) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCurrentVersionNumber( + + virtual HRESULT STDMETHODCALLTYPE GetCurrentVersionNumber( /* [out] */ ULONG32 *pnCurrentVersion) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFunctionVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFunction * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFunction * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFunction * This); - + DECLSPEC_XFGVIRT(ICorDebugFunction, GetModule) - HRESULT ( STDMETHODCALLTYPE *GetModule )( + HRESULT ( STDMETHODCALLTYPE *GetModule )( ICorDebugFunction * This, /* [out] */ ICorDebugModule **ppModule); - + DECLSPEC_XFGVIRT(ICorDebugFunction, GetClass) - HRESULT ( STDMETHODCALLTYPE *GetClass )( + HRESULT ( STDMETHODCALLTYPE *GetClass )( ICorDebugFunction * This, /* [out] */ ICorDebugClass **ppClass); - + DECLSPEC_XFGVIRT(ICorDebugFunction, GetToken) - HRESULT ( STDMETHODCALLTYPE *GetToken )( + HRESULT ( STDMETHODCALLTYPE *GetToken )( ICorDebugFunction * This, /* [out] */ mdMethodDef *pMethodDef); - + DECLSPEC_XFGVIRT(ICorDebugFunction, GetILCode) - HRESULT ( STDMETHODCALLTYPE *GetILCode )( + HRESULT ( STDMETHODCALLTYPE *GetILCode )( ICorDebugFunction * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugFunction, GetNativeCode) - HRESULT ( STDMETHODCALLTYPE *GetNativeCode )( + HRESULT ( STDMETHODCALLTYPE *GetNativeCode )( ICorDebugFunction * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugFunction, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugFunction * This, /* [out] */ ICorDebugFunctionBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugFunction, GetLocalVarSigToken) - HRESULT ( STDMETHODCALLTYPE *GetLocalVarSigToken )( + HRESULT ( STDMETHODCALLTYPE *GetLocalVarSigToken )( ICorDebugFunction * This, /* [out] */ mdSignature *pmdSig); - + DECLSPEC_XFGVIRT(ICorDebugFunction, GetCurrentVersionNumber) - HRESULT ( STDMETHODCALLTYPE *GetCurrentVersionNumber )( + HRESULT ( STDMETHODCALLTYPE *GetCurrentVersionNumber )( ICorDebugFunction * This, /* [out] */ ULONG32 *pnCurrentVersion); - + END_INTERFACE } ICorDebugFunctionVtbl; @@ -13304,44 +13311,44 @@ EXTERN_C const IID IID_ICorDebugFunction; CONST_VTBL struct ICorDebugFunctionVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFunction_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFunction_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFunction_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFunction_GetModule(This,ppModule) \ - ( (This)->lpVtbl -> GetModule(This,ppModule) ) + ( (This)->lpVtbl -> GetModule(This,ppModule) ) #define ICorDebugFunction_GetClass(This,ppClass) \ - ( (This)->lpVtbl -> GetClass(This,ppClass) ) + ( (This)->lpVtbl -> GetClass(This,ppClass) ) #define ICorDebugFunction_GetToken(This,pMethodDef) \ - ( (This)->lpVtbl -> GetToken(This,pMethodDef) ) + ( (This)->lpVtbl -> GetToken(This,pMethodDef) ) #define ICorDebugFunction_GetILCode(This,ppCode) \ - ( (This)->lpVtbl -> GetILCode(This,ppCode) ) + ( (This)->lpVtbl -> GetILCode(This,ppCode) ) #define ICorDebugFunction_GetNativeCode(This,ppCode) \ - ( (This)->lpVtbl -> GetNativeCode(This,ppCode) ) + ( (This)->lpVtbl -> GetNativeCode(This,ppCode) ) #define ICorDebugFunction_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugFunction_GetLocalVarSigToken(This,pmdSig) \ - ( (This)->lpVtbl -> GetLocalVarSigToken(This,pmdSig) ) + ( (This)->lpVtbl -> GetLocalVarSigToken(This,pmdSig) ) #define ICorDebugFunction_GetCurrentVersionNumber(This,pnCurrentVersion) \ - ( (This)->lpVtbl -> GetCurrentVersionNumber(This,pnCurrentVersion) ) + ( (This)->lpVtbl -> GetCurrentVersionNumber(This,pnCurrentVersion) ) #endif /* COBJMACROS */ @@ -13358,73 +13365,73 @@ EXTERN_C const IID IID_ICorDebugFunction; #define __ICorDebugFunction2_INTERFACE_DEFINED__ /* interface ICorDebugFunction2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFunction2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("EF0C490B-94C3-4e4d-B629-DDC134C532D8") ICorDebugFunction2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE SetJMCStatus( + virtual HRESULT STDMETHODCALLTYPE SetJMCStatus( /* [in] */ BOOL bIsJustMyCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetJMCStatus( + + virtual HRESULT STDMETHODCALLTYPE GetJMCStatus( /* [out] */ BOOL *pbIsJustMyCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateNativeCode( + + virtual HRESULT STDMETHODCALLTYPE EnumerateNativeCode( /* [out] */ ICorDebugCodeEnum **ppCodeEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetVersionNumber( + + virtual HRESULT STDMETHODCALLTYPE GetVersionNumber( /* [out] */ ULONG32 *pnVersion) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFunction2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFunction2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFunction2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFunction2 * This); - + DECLSPEC_XFGVIRT(ICorDebugFunction2, SetJMCStatus) - HRESULT ( STDMETHODCALLTYPE *SetJMCStatus )( + HRESULT ( STDMETHODCALLTYPE *SetJMCStatus )( ICorDebugFunction2 * This, /* [in] */ BOOL bIsJustMyCode); - + DECLSPEC_XFGVIRT(ICorDebugFunction2, GetJMCStatus) - HRESULT ( STDMETHODCALLTYPE *GetJMCStatus )( + HRESULT ( STDMETHODCALLTYPE *GetJMCStatus )( ICorDebugFunction2 * This, /* [out] */ BOOL *pbIsJustMyCode); - + DECLSPEC_XFGVIRT(ICorDebugFunction2, EnumerateNativeCode) - HRESULT ( STDMETHODCALLTYPE *EnumerateNativeCode )( + HRESULT ( STDMETHODCALLTYPE *EnumerateNativeCode )( ICorDebugFunction2 * This, /* [out] */ ICorDebugCodeEnum **ppCodeEnum); - + DECLSPEC_XFGVIRT(ICorDebugFunction2, GetVersionNumber) - HRESULT ( STDMETHODCALLTYPE *GetVersionNumber )( + HRESULT ( STDMETHODCALLTYPE *GetVersionNumber )( ICorDebugFunction2 * This, /* [out] */ ULONG32 *pnVersion); - + END_INTERFACE } ICorDebugFunction2Vtbl; @@ -13433,32 +13440,32 @@ EXTERN_C const IID IID_ICorDebugFunction2; CONST_VTBL struct ICorDebugFunction2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFunction2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFunction2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFunction2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFunction2_SetJMCStatus(This,bIsJustMyCode) \ - ( (This)->lpVtbl -> SetJMCStatus(This,bIsJustMyCode) ) + ( (This)->lpVtbl -> SetJMCStatus(This,bIsJustMyCode) ) #define ICorDebugFunction2_GetJMCStatus(This,pbIsJustMyCode) \ - ( (This)->lpVtbl -> GetJMCStatus(This,pbIsJustMyCode) ) + ( (This)->lpVtbl -> GetJMCStatus(This,pbIsJustMyCode) ) #define ICorDebugFunction2_EnumerateNativeCode(This,ppCodeEnum) \ - ( (This)->lpVtbl -> EnumerateNativeCode(This,ppCodeEnum) ) + ( (This)->lpVtbl -> EnumerateNativeCode(This,ppCodeEnum) ) #define ICorDebugFunction2_GetVersionNumber(This,pnVersion) \ - ( (This)->lpVtbl -> GetVersionNumber(This,pnVersion) ) + ( (This)->lpVtbl -> GetVersionNumber(This,pnVersion) ) #endif /* COBJMACROS */ @@ -13475,49 +13482,49 @@ EXTERN_C const IID IID_ICorDebugFunction2; #define __ICorDebugFunction3_INTERFACE_DEFINED__ /* interface ICorDebugFunction3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFunction3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("09B70F28-E465-482D-99E0-81A165EB0532") ICorDebugFunction3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetActiveReJitRequestILCode( + virtual HRESULT STDMETHODCALLTYPE GetActiveReJitRequestILCode( ICorDebugILCode **ppReJitedILCode) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFunction3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFunction3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFunction3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFunction3 * This); - + DECLSPEC_XFGVIRT(ICorDebugFunction3, GetActiveReJitRequestILCode) - HRESULT ( STDMETHODCALLTYPE *GetActiveReJitRequestILCode )( + HRESULT ( STDMETHODCALLTYPE *GetActiveReJitRequestILCode )( ICorDebugFunction3 * This, ICorDebugILCode **ppReJitedILCode); - + END_INTERFACE } ICorDebugFunction3Vtbl; @@ -13526,23 +13533,23 @@ EXTERN_C const IID IID_ICorDebugFunction3; CONST_VTBL struct ICorDebugFunction3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFunction3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFunction3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFunction3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFunction3_GetActiveReJitRequestILCode(This,ppReJitedILCode) \ - ( (This)->lpVtbl -> GetActiveReJitRequestILCode(This,ppReJitedILCode) ) + ( (This)->lpVtbl -> GetActiveReJitRequestILCode(This,ppReJitedILCode) ) #endif /* COBJMACROS */ @@ -13559,49 +13566,49 @@ EXTERN_C const IID IID_ICorDebugFunction3; #define __ICorDebugFunction4_INTERFACE_DEFINED__ /* interface ICorDebugFunction4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFunction4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("72965963-34fd-46e9-9434-b817fe6e7f43") ICorDebugFunction4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CreateNativeBreakpoint( + virtual HRESULT STDMETHODCALLTYPE CreateNativeBreakpoint( ICorDebugFunctionBreakpoint **ppBreakpoint) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFunction4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFunction4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFunction4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFunction4 * This); - + DECLSPEC_XFGVIRT(ICorDebugFunction4, CreateNativeBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateNativeBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateNativeBreakpoint )( ICorDebugFunction4 * This, ICorDebugFunctionBreakpoint **ppBreakpoint); - + END_INTERFACE } ICorDebugFunction4Vtbl; @@ -13610,23 +13617,23 @@ EXTERN_C const IID IID_ICorDebugFunction4; CONST_VTBL struct ICorDebugFunction4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFunction4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFunction4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFunction4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFunction4_CreateNativeBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateNativeBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateNativeBreakpoint(This,ppBreakpoint) ) #endif /* COBJMACROS */ @@ -13643,55 +13650,55 @@ EXTERN_C const IID IID_ICorDebugFunction4; #define __ICorDebugFunction5_INTERFACE_DEFINED__ /* interface ICorDebugFunction5 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFunction5; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("9D4DAB7B-3401-4F37-BD08-CA09F3FDF10F") ICorDebugFunction5 : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE DisableOptimizations( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE AreOptimizationsDisabled( + + virtual HRESULT STDMETHODCALLTYPE AreOptimizationsDisabled( BOOL *pOptimizationsDisabled) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFunction5Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFunction5 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFunction5 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFunction5 * This); - + DECLSPEC_XFGVIRT(ICorDebugFunction5, DisableOptimizations) - HRESULT ( STDMETHODCALLTYPE *DisableOptimizations )( + HRESULT ( STDMETHODCALLTYPE *DisableOptimizations )( ICorDebugFunction5 * This); - + DECLSPEC_XFGVIRT(ICorDebugFunction5, AreOptimizationsDisabled) - HRESULT ( STDMETHODCALLTYPE *AreOptimizationsDisabled )( + HRESULT ( STDMETHODCALLTYPE *AreOptimizationsDisabled )( ICorDebugFunction5 * This, BOOL *pOptimizationsDisabled); - + END_INTERFACE } ICorDebugFunction5Vtbl; @@ -13700,26 +13707,26 @@ EXTERN_C const IID IID_ICorDebugFunction5; CONST_VTBL struct ICorDebugFunction5Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFunction5_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFunction5_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFunction5_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFunction5_DisableOptimizations(This) \ - ( (This)->lpVtbl -> DisableOptimizations(This) ) + ( (This)->lpVtbl -> DisableOptimizations(This) ) #define ICorDebugFunction5_AreOptimizationsDisabled(This,pOptimizationsDisabled) \ - ( (This)->lpVtbl -> AreOptimizationsDisabled(This,pOptimizationsDisabled) ) + ( (This)->lpVtbl -> AreOptimizationsDisabled(This,pOptimizationsDisabled) ) #endif /* COBJMACROS */ @@ -13736,131 +13743,131 @@ EXTERN_C const IID IID_ICorDebugFunction5; #define __ICorDebugCode_INTERFACE_DEFINED__ /* interface ICorDebugCode */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugCode; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAF4-8A68-11d2-983C-0000F808342D") ICorDebugCode : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE IsIL( + virtual HRESULT STDMETHODCALLTYPE IsIL( /* [out] */ BOOL *pbIL) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunction( + + virtual HRESULT STDMETHODCALLTYPE GetFunction( /* [out] */ ICorDebugFunction **ppFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAddress( + + virtual HRESULT STDMETHODCALLTYPE GetAddress( /* [out] */ CORDB_ADDRESS *pStart) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pcBytes) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( /* [in] */ ULONG32 offset, /* [out] */ ICorDebugFunctionBreakpoint **ppBreakpoint) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCode( + + virtual HRESULT STDMETHODCALLTYPE GetCode( /* [in] */ ULONG32 startOffset, /* [in] */ ULONG32 endOffset, /* [in] */ ULONG32 cBufferAlloc, /* [length_is][size_is][out] */ BYTE buffer[ ], /* [out] */ ULONG32 *pcBufferSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetVersionNumber( + + virtual HRESULT STDMETHODCALLTYPE GetVersionNumber( /* [out] */ ULONG32 *nVersion) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping( + + virtual HRESULT STDMETHODCALLTYPE GetILToNativeMapping( /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetEnCRemapSequencePoints( + + virtual HRESULT STDMETHODCALLTYPE GetEnCRemapSequencePoints( /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ ULONG32 offsets[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugCodeVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugCode * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugCode * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugCode * This); - + DECLSPEC_XFGVIRT(ICorDebugCode, IsIL) - HRESULT ( STDMETHODCALLTYPE *IsIL )( + HRESULT ( STDMETHODCALLTYPE *IsIL )( ICorDebugCode * This, /* [out] */ BOOL *pbIL); - + DECLSPEC_XFGVIRT(ICorDebugCode, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugCode * This, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugCode, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugCode * This, /* [out] */ CORDB_ADDRESS *pStart); - + DECLSPEC_XFGVIRT(ICorDebugCode, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugCode * This, /* [out] */ ULONG32 *pcBytes); - + DECLSPEC_XFGVIRT(ICorDebugCode, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugCode * This, /* [in] */ ULONG32 offset, /* [out] */ ICorDebugFunctionBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugCode, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugCode * This, /* [in] */ ULONG32 startOffset, /* [in] */ ULONG32 endOffset, /* [in] */ ULONG32 cBufferAlloc, /* [length_is][size_is][out] */ BYTE buffer[ ], /* [out] */ ULONG32 *pcBufferSize); - + DECLSPEC_XFGVIRT(ICorDebugCode, GetVersionNumber) - HRESULT ( STDMETHODCALLTYPE *GetVersionNumber )( + HRESULT ( STDMETHODCALLTYPE *GetVersionNumber )( ICorDebugCode * This, /* [out] */ ULONG32 *nVersion); - + DECLSPEC_XFGVIRT(ICorDebugCode, GetILToNativeMapping) - HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( + HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )( ICorDebugCode * This, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]); - + DECLSPEC_XFGVIRT(ICorDebugCode, GetEnCRemapSequencePoints) - HRESULT ( STDMETHODCALLTYPE *GetEnCRemapSequencePoints )( + HRESULT ( STDMETHODCALLTYPE *GetEnCRemapSequencePoints )( ICorDebugCode * This, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ ULONG32 offsets[ ]); - + END_INTERFACE } ICorDebugCodeVtbl; @@ -13869,47 +13876,47 @@ EXTERN_C const IID IID_ICorDebugCode; CONST_VTBL struct ICorDebugCodeVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugCode_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugCode_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugCode_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugCode_IsIL(This,pbIL) \ - ( (This)->lpVtbl -> IsIL(This,pbIL) ) + ( (This)->lpVtbl -> IsIL(This,pbIL) ) #define ICorDebugCode_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #define ICorDebugCode_GetAddress(This,pStart) \ - ( (This)->lpVtbl -> GetAddress(This,pStart) ) + ( (This)->lpVtbl -> GetAddress(This,pStart) ) #define ICorDebugCode_GetSize(This,pcBytes) \ - ( (This)->lpVtbl -> GetSize(This,pcBytes) ) + ( (This)->lpVtbl -> GetSize(This,pcBytes) ) #define ICorDebugCode_CreateBreakpoint(This,offset,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,offset,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,offset,ppBreakpoint) ) #define ICorDebugCode_GetCode(This,startOffset,endOffset,cBufferAlloc,buffer,pcBufferSize) \ - ( (This)->lpVtbl -> GetCode(This,startOffset,endOffset,cBufferAlloc,buffer,pcBufferSize) ) + ( (This)->lpVtbl -> GetCode(This,startOffset,endOffset,cBufferAlloc,buffer,pcBufferSize) ) #define ICorDebugCode_GetVersionNumber(This,nVersion) \ - ( (This)->lpVtbl -> GetVersionNumber(This,nVersion) ) + ( (This)->lpVtbl -> GetVersionNumber(This,nVersion) ) #define ICorDebugCode_GetILToNativeMapping(This,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetILToNativeMapping(This,cMap,pcMap,map) ) + ( (This)->lpVtbl -> GetILToNativeMapping(This,cMap,pcMap,map) ) #define ICorDebugCode_GetEnCRemapSequencePoints(This,cMap,pcMap,offsets) \ - ( (This)->lpVtbl -> GetEnCRemapSequencePoints(This,cMap,pcMap,offsets) ) + ( (This)->lpVtbl -> GetEnCRemapSequencePoints(This,cMap,pcMap,offsets) ) #endif /* COBJMACROS */ @@ -13926,7 +13933,7 @@ EXTERN_C const IID IID_ICorDebugCode; #define __ICorDebugCode2_INTERFACE_DEFINED__ /* interface ICorDebugCode2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ typedef struct _CodeChunkInfo { @@ -13938,55 +13945,55 @@ typedef struct _CodeChunkInfo EXTERN_C const IID IID_ICorDebugCode2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("5F696509-452F-4436-A3FE-4D11FE7E2347") ICorDebugCode2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetCodeChunks( + virtual HRESULT STDMETHODCALLTYPE GetCodeChunks( /* [in] */ ULONG32 cbufSize, /* [out] */ ULONG32 *pcnumChunks, /* [length_is][size_is][out] */ CodeChunkInfo chunks[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCompilerFlags( + + virtual HRESULT STDMETHODCALLTYPE GetCompilerFlags( /* [out] */ DWORD *pdwFlags) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugCode2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugCode2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugCode2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugCode2 * This); - + DECLSPEC_XFGVIRT(ICorDebugCode2, GetCodeChunks) - HRESULT ( STDMETHODCALLTYPE *GetCodeChunks )( + HRESULT ( STDMETHODCALLTYPE *GetCodeChunks )( ICorDebugCode2 * This, /* [in] */ ULONG32 cbufSize, /* [out] */ ULONG32 *pcnumChunks, /* [length_is][size_is][out] */ CodeChunkInfo chunks[ ]); - + DECLSPEC_XFGVIRT(ICorDebugCode2, GetCompilerFlags) - HRESULT ( STDMETHODCALLTYPE *GetCompilerFlags )( + HRESULT ( STDMETHODCALLTYPE *GetCompilerFlags )( ICorDebugCode2 * This, /* [out] */ DWORD *pdwFlags); - + END_INTERFACE } ICorDebugCode2Vtbl; @@ -13995,26 +14002,26 @@ EXTERN_C const IID IID_ICorDebugCode2; CONST_VTBL struct ICorDebugCode2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugCode2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugCode2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugCode2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugCode2_GetCodeChunks(This,cbufSize,pcnumChunks,chunks) \ - ( (This)->lpVtbl -> GetCodeChunks(This,cbufSize,pcnumChunks,chunks) ) + ( (This)->lpVtbl -> GetCodeChunks(This,cbufSize,pcnumChunks,chunks) ) #define ICorDebugCode2_GetCompilerFlags(This,pdwFlags) \ - ( (This)->lpVtbl -> GetCompilerFlags(This,pdwFlags) ) + ( (This)->lpVtbl -> GetCompilerFlags(This,pdwFlags) ) #endif /* COBJMACROS */ @@ -14031,55 +14038,55 @@ EXTERN_C const IID IID_ICorDebugCode2; #define __ICorDebugCode3_INTERFACE_DEFINED__ /* interface ICorDebugCode3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugCode3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("D13D3E88-E1F2-4020-AA1D-3D162DCBE966") ICorDebugCode3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetReturnValueLiveOffset( + virtual HRESULT STDMETHODCALLTYPE GetReturnValueLiveOffset( /* [in] */ ULONG32 ILoffset, /* [in] */ ULONG32 bufferSize, /* [out] */ ULONG32 *pFetched, /* [length_is][size_is][out] */ ULONG32 pOffsets[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugCode3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugCode3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugCode3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugCode3 * This); - + DECLSPEC_XFGVIRT(ICorDebugCode3, GetReturnValueLiveOffset) - HRESULT ( STDMETHODCALLTYPE *GetReturnValueLiveOffset )( + HRESULT ( STDMETHODCALLTYPE *GetReturnValueLiveOffset )( ICorDebugCode3 * This, /* [in] */ ULONG32 ILoffset, /* [in] */ ULONG32 bufferSize, /* [out] */ ULONG32 *pFetched, /* [length_is][size_is][out] */ ULONG32 pOffsets[ ]); - + END_INTERFACE } ICorDebugCode3Vtbl; @@ -14088,23 +14095,23 @@ EXTERN_C const IID IID_ICorDebugCode3; CONST_VTBL struct ICorDebugCode3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugCode3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugCode3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugCode3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugCode3_GetReturnValueLiveOffset(This,ILoffset,bufferSize,pFetched,pOffsets) \ - ( (This)->lpVtbl -> GetReturnValueLiveOffset(This,ILoffset,bufferSize,pFetched,pOffsets) ) + ( (This)->lpVtbl -> GetReturnValueLiveOffset(This,ILoffset,bufferSize,pFetched,pOffsets) ) #endif /* COBJMACROS */ @@ -14121,49 +14128,49 @@ EXTERN_C const IID IID_ICorDebugCode3; #define __ICorDebugCode4_INTERFACE_DEFINED__ /* interface ICorDebugCode4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugCode4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("18221fa4-20cb-40fa-b19d-9f91c4fa8c14") ICorDebugCode4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE EnumerateVariableHomes( + virtual HRESULT STDMETHODCALLTYPE EnumerateVariableHomes( /* [out] */ ICorDebugVariableHomeEnum **ppEnum) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugCode4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugCode4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugCode4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugCode4 * This); - + DECLSPEC_XFGVIRT(ICorDebugCode4, EnumerateVariableHomes) - HRESULT ( STDMETHODCALLTYPE *EnumerateVariableHomes )( + HRESULT ( STDMETHODCALLTYPE *EnumerateVariableHomes )( ICorDebugCode4 * This, /* [out] */ ICorDebugVariableHomeEnum **ppEnum); - + END_INTERFACE } ICorDebugCode4Vtbl; @@ -14172,23 +14179,23 @@ EXTERN_C const IID IID_ICorDebugCode4; CONST_VTBL struct ICorDebugCode4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugCode4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugCode4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugCode4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugCode4_EnumerateVariableHomes(This,ppEnum) \ - ( (This)->lpVtbl -> EnumerateVariableHomes(This,ppEnum) ) + ( (This)->lpVtbl -> EnumerateVariableHomes(This,ppEnum) ) #endif /* COBJMACROS */ @@ -14205,7 +14212,7 @@ EXTERN_C const IID IID_ICorDebugCode4; #define __ICorDebugILCode_INTERFACE_DEFINED__ /* interface ICorDebugILCode */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ typedef struct _CorDebugEHClause { @@ -14222,47 +14229,47 @@ typedef struct _CorDebugEHClause EXTERN_C const IID IID_ICorDebugILCode; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("598D46C2-C877-42A7-89D2-3D0C7F1C1264") ICorDebugILCode : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetEHClauses( + virtual HRESULT STDMETHODCALLTYPE GetEHClauses( /* [in] */ ULONG32 cClauses, /* [out] */ ULONG32 *pcClauses, /* [length_is][size_is][out] */ CorDebugEHClause clauses[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugILCodeVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugILCode * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugILCode * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugILCode * This); - + DECLSPEC_XFGVIRT(ICorDebugILCode, GetEHClauses) - HRESULT ( STDMETHODCALLTYPE *GetEHClauses )( + HRESULT ( STDMETHODCALLTYPE *GetEHClauses )( ICorDebugILCode * This, /* [in] */ ULONG32 cClauses, /* [out] */ ULONG32 *pcClauses, /* [length_is][size_is][out] */ CorDebugEHClause clauses[ ]); - + END_INTERFACE } ICorDebugILCodeVtbl; @@ -14271,23 +14278,23 @@ EXTERN_C const IID IID_ICorDebugILCode; CONST_VTBL struct ICorDebugILCodeVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugILCode_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugILCode_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugILCode_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugILCode_GetEHClauses(This,cClauses,pcClauses,clauses) \ - ( (This)->lpVtbl -> GetEHClauses(This,cClauses,pcClauses,clauses) ) + ( (This)->lpVtbl -> GetEHClauses(This,cClauses,pcClauses,clauses) ) #endif /* COBJMACROS */ @@ -14304,61 +14311,61 @@ EXTERN_C const IID IID_ICorDebugILCode; #define __ICorDebugILCode2_INTERFACE_DEFINED__ /* interface ICorDebugILCode2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugILCode2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("46586093-D3F5-4DB6-ACDB-955BCE228C15") ICorDebugILCode2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetLocalVarSigToken( + virtual HRESULT STDMETHODCALLTYPE GetLocalVarSigToken( /* [out] */ mdSignature *pmdSig) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetInstrumentedILMap( + + virtual HRESULT STDMETHODCALLTYPE GetInstrumentedILMap( /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_IL_MAP map[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugILCode2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugILCode2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugILCode2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugILCode2 * This); - + DECLSPEC_XFGVIRT(ICorDebugILCode2, GetLocalVarSigToken) - HRESULT ( STDMETHODCALLTYPE *GetLocalVarSigToken )( + HRESULT ( STDMETHODCALLTYPE *GetLocalVarSigToken )( ICorDebugILCode2 * This, /* [out] */ mdSignature *pmdSig); - + DECLSPEC_XFGVIRT(ICorDebugILCode2, GetInstrumentedILMap) - HRESULT ( STDMETHODCALLTYPE *GetInstrumentedILMap )( + HRESULT ( STDMETHODCALLTYPE *GetInstrumentedILMap )( ICorDebugILCode2 * This, /* [in] */ ULONG32 cMap, /* [out] */ ULONG32 *pcMap, /* [length_is][size_is][out] */ COR_IL_MAP map[ ]); - + END_INTERFACE } ICorDebugILCode2Vtbl; @@ -14367,26 +14374,26 @@ EXTERN_C const IID IID_ICorDebugILCode2; CONST_VTBL struct ICorDebugILCode2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugILCode2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugILCode2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugILCode2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugILCode2_GetLocalVarSigToken(This,pmdSig) \ - ( (This)->lpVtbl -> GetLocalVarSigToken(This,pmdSig) ) + ( (This)->lpVtbl -> GetLocalVarSigToken(This,pmdSig) ) #define ICorDebugILCode2_GetInstrumentedILMap(This,cMap,pcMap,map) \ - ( (This)->lpVtbl -> GetInstrumentedILMap(This,cMap,pcMap,map) ) + ( (This)->lpVtbl -> GetInstrumentedILMap(This,cMap,pcMap,map) ) #endif /* COBJMACROS */ @@ -14403,69 +14410,69 @@ EXTERN_C const IID IID_ICorDebugILCode2; #define __ICorDebugClass_INTERFACE_DEFINED__ /* interface ICorDebugClass */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugClass; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAF5-8A68-11d2-983C-0000F808342D") ICorDebugClass : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetModule( + virtual HRESULT STDMETHODCALLTYPE GetModule( /* [out] */ ICorDebugModule **pModule) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetToken( + + virtual HRESULT STDMETHODCALLTYPE GetToken( /* [out] */ mdTypeDef *pTypeDef) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStaticFieldValue( + + virtual HRESULT STDMETHODCALLTYPE GetStaticFieldValue( /* [in] */ mdFieldDef fieldDef, /* [in] */ ICorDebugFrame *pFrame, /* [out] */ ICorDebugValue **ppValue) = 0; - + }; - - -#else /* C style interface */ + + +#else /* C style interface */ typedef struct ICorDebugClassVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugClass * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugClass * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugClass * This); - + DECLSPEC_XFGVIRT(ICorDebugClass, GetModule) - HRESULT ( STDMETHODCALLTYPE *GetModule )( + HRESULT ( STDMETHODCALLTYPE *GetModule )( ICorDebugClass * This, /* [out] */ ICorDebugModule **pModule); - + DECLSPEC_XFGVIRT(ICorDebugClass, GetToken) - HRESULT ( STDMETHODCALLTYPE *GetToken )( + HRESULT ( STDMETHODCALLTYPE *GetToken )( ICorDebugClass * This, /* [out] */ mdTypeDef *pTypeDef); - + DECLSPEC_XFGVIRT(ICorDebugClass, GetStaticFieldValue) - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldValue )( + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldValue )( ICorDebugClass * This, /* [in] */ mdFieldDef fieldDef, /* [in] */ ICorDebugFrame *pFrame, /* [out] */ ICorDebugValue **ppValue); - + END_INTERFACE } ICorDebugClassVtbl; @@ -14474,29 +14481,29 @@ EXTERN_C const IID IID_ICorDebugClass; CONST_VTBL struct ICorDebugClassVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugClass_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugClass_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugClass_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugClass_GetModule(This,pModule) \ - ( (This)->lpVtbl -> GetModule(This,pModule) ) + ( (This)->lpVtbl -> GetModule(This,pModule) ) #define ICorDebugClass_GetToken(This,pTypeDef) \ - ( (This)->lpVtbl -> GetToken(This,pTypeDef) ) + ( (This)->lpVtbl -> GetToken(This,pTypeDef) ) #define ICorDebugClass_GetStaticFieldValue(This,fieldDef,pFrame,ppValue) \ - ( (This)->lpVtbl -> GetStaticFieldValue(This,fieldDef,pFrame,ppValue) ) + ( (This)->lpVtbl -> GetStaticFieldValue(This,fieldDef,pFrame,ppValue) ) #endif /* COBJMACROS */ @@ -14513,63 +14520,63 @@ EXTERN_C const IID IID_ICorDebugClass; #define __ICorDebugClass2_INTERFACE_DEFINED__ /* interface ICorDebugClass2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugClass2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("B008EA8D-7AB1-43f7-BB20-FBB5A04038AE") ICorDebugClass2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetParameterizedType( + virtual HRESULT STDMETHODCALLTYPE GetParameterizedType( /* [in] */ CorElementType elementType, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [out] */ ICorDebugType **ppType) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetJMCStatus( + + virtual HRESULT STDMETHODCALLTYPE SetJMCStatus( /* [in] */ BOOL bIsJustMyCode) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugClass2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugClass2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugClass2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugClass2 * This); - + DECLSPEC_XFGVIRT(ICorDebugClass2, GetParameterizedType) - HRESULT ( STDMETHODCALLTYPE *GetParameterizedType )( + HRESULT ( STDMETHODCALLTYPE *GetParameterizedType )( ICorDebugClass2 * This, /* [in] */ CorElementType elementType, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [out] */ ICorDebugType **ppType); - + DECLSPEC_XFGVIRT(ICorDebugClass2, SetJMCStatus) - HRESULT ( STDMETHODCALLTYPE *SetJMCStatus )( + HRESULT ( STDMETHODCALLTYPE *SetJMCStatus )( ICorDebugClass2 * This, /* [in] */ BOOL bIsJustMyCode); - + END_INTERFACE } ICorDebugClass2Vtbl; @@ -14578,26 +14585,26 @@ EXTERN_C const IID IID_ICorDebugClass2; CONST_VTBL struct ICorDebugClass2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugClass2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugClass2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugClass2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugClass2_GetParameterizedType(This,elementType,nTypeArgs,ppTypeArgs,ppType) \ - ( (This)->lpVtbl -> GetParameterizedType(This,elementType,nTypeArgs,ppTypeArgs,ppType) ) + ( (This)->lpVtbl -> GetParameterizedType(This,elementType,nTypeArgs,ppTypeArgs,ppType) ) #define ICorDebugClass2_SetJMCStatus(This,bIsJustMyCode) \ - ( (This)->lpVtbl -> SetJMCStatus(This,bIsJustMyCode) ) + ( (This)->lpVtbl -> SetJMCStatus(This,bIsJustMyCode) ) #endif /* COBJMACROS */ @@ -14614,139 +14621,139 @@ EXTERN_C const IID IID_ICorDebugClass2; #define __ICorDebugEval_INTERFACE_DEFINED__ /* interface ICorDebugEval */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugEval; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAF6-8A68-11d2-983C-0000F808342D") ICorDebugEval : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CallFunction( + virtual HRESULT STDMETHODCALLTYPE CallFunction( /* [in] */ ICorDebugFunction *pFunction, /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewObject( + + virtual HRESULT STDMETHODCALLTYPE NewObject( /* [in] */ ICorDebugFunction *pConstructor, /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewObjectNoConstructor( + + virtual HRESULT STDMETHODCALLTYPE NewObjectNoConstructor( /* [in] */ ICorDebugClass *pClass) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewString( + + virtual HRESULT STDMETHODCALLTYPE NewString( /* [in] */ LPCWSTR string) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewArray( + + virtual HRESULT STDMETHODCALLTYPE NewArray( /* [in] */ CorElementType elementType, /* [in] */ ICorDebugClass *pElementClass, /* [in] */ ULONG32 rank, /* [size_is][in] */ ULONG32 dims[ ], /* [size_is][in] */ ULONG32 lowBounds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsActive( + + virtual HRESULT STDMETHODCALLTYPE IsActive( /* [out] */ BOOL *pbActive) = 0; - + virtual HRESULT STDMETHODCALLTYPE Abort( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetResult( + + virtual HRESULT STDMETHODCALLTYPE GetResult( /* [out] */ ICorDebugValue **ppResult) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetThread( + + virtual HRESULT STDMETHODCALLTYPE GetThread( /* [out] */ ICorDebugThread **ppThread) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateValue( + + virtual HRESULT STDMETHODCALLTYPE CreateValue( /* [in] */ CorElementType elementType, /* [in] */ ICorDebugClass *pElementClass, /* [out] */ ICorDebugValue **ppValue) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugEvalVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugEval * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugEval * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugEval * This); - + DECLSPEC_XFGVIRT(ICorDebugEval, CallFunction) - HRESULT ( STDMETHODCALLTYPE *CallFunction )( + HRESULT ( STDMETHODCALLTYPE *CallFunction )( ICorDebugEval * This, /* [in] */ ICorDebugFunction *pFunction, /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEval, NewObject) - HRESULT ( STDMETHODCALLTYPE *NewObject )( + HRESULT ( STDMETHODCALLTYPE *NewObject )( ICorDebugEval * This, /* [in] */ ICorDebugFunction *pConstructor, /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEval, NewObjectNoConstructor) - HRESULT ( STDMETHODCALLTYPE *NewObjectNoConstructor )( + HRESULT ( STDMETHODCALLTYPE *NewObjectNoConstructor )( ICorDebugEval * This, /* [in] */ ICorDebugClass *pClass); - + DECLSPEC_XFGVIRT(ICorDebugEval, NewString) - HRESULT ( STDMETHODCALLTYPE *NewString )( + HRESULT ( STDMETHODCALLTYPE *NewString )( ICorDebugEval * This, /* [in] */ LPCWSTR string); - + DECLSPEC_XFGVIRT(ICorDebugEval, NewArray) - HRESULT ( STDMETHODCALLTYPE *NewArray )( + HRESULT ( STDMETHODCALLTYPE *NewArray )( ICorDebugEval * This, /* [in] */ CorElementType elementType, /* [in] */ ICorDebugClass *pElementClass, /* [in] */ ULONG32 rank, /* [size_is][in] */ ULONG32 dims[ ], /* [size_is][in] */ ULONG32 lowBounds[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEval, IsActive) - HRESULT ( STDMETHODCALLTYPE *IsActive )( + HRESULT ( STDMETHODCALLTYPE *IsActive )( ICorDebugEval * This, /* [out] */ BOOL *pbActive); - + DECLSPEC_XFGVIRT(ICorDebugEval, Abort) - HRESULT ( STDMETHODCALLTYPE *Abort )( + HRESULT ( STDMETHODCALLTYPE *Abort )( ICorDebugEval * This); - + DECLSPEC_XFGVIRT(ICorDebugEval, GetResult) - HRESULT ( STDMETHODCALLTYPE *GetResult )( + HRESULT ( STDMETHODCALLTYPE *GetResult )( ICorDebugEval * This, /* [out] */ ICorDebugValue **ppResult); - + DECLSPEC_XFGVIRT(ICorDebugEval, GetThread) - HRESULT ( STDMETHODCALLTYPE *GetThread )( + HRESULT ( STDMETHODCALLTYPE *GetThread )( ICorDebugEval * This, /* [out] */ ICorDebugThread **ppThread); - + DECLSPEC_XFGVIRT(ICorDebugEval, CreateValue) - HRESULT ( STDMETHODCALLTYPE *CreateValue )( + HRESULT ( STDMETHODCALLTYPE *CreateValue )( ICorDebugEval * This, /* [in] */ CorElementType elementType, /* [in] */ ICorDebugClass *pElementClass, /* [out] */ ICorDebugValue **ppValue); - + END_INTERFACE } ICorDebugEvalVtbl; @@ -14755,50 +14762,50 @@ EXTERN_C const IID IID_ICorDebugEval; CONST_VTBL struct ICorDebugEvalVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugEval_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugEval_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugEval_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugEval_CallFunction(This,pFunction,nArgs,ppArgs) \ - ( (This)->lpVtbl -> CallFunction(This,pFunction,nArgs,ppArgs) ) + ( (This)->lpVtbl -> CallFunction(This,pFunction,nArgs,ppArgs) ) #define ICorDebugEval_NewObject(This,pConstructor,nArgs,ppArgs) \ - ( (This)->lpVtbl -> NewObject(This,pConstructor,nArgs,ppArgs) ) + ( (This)->lpVtbl -> NewObject(This,pConstructor,nArgs,ppArgs) ) #define ICorDebugEval_NewObjectNoConstructor(This,pClass) \ - ( (This)->lpVtbl -> NewObjectNoConstructor(This,pClass) ) + ( (This)->lpVtbl -> NewObjectNoConstructor(This,pClass) ) #define ICorDebugEval_NewString(This,string) \ - ( (This)->lpVtbl -> NewString(This,string) ) + ( (This)->lpVtbl -> NewString(This,string) ) #define ICorDebugEval_NewArray(This,elementType,pElementClass,rank,dims,lowBounds) \ - ( (This)->lpVtbl -> NewArray(This,elementType,pElementClass,rank,dims,lowBounds) ) + ( (This)->lpVtbl -> NewArray(This,elementType,pElementClass,rank,dims,lowBounds) ) #define ICorDebugEval_IsActive(This,pbActive) \ - ( (This)->lpVtbl -> IsActive(This,pbActive) ) + ( (This)->lpVtbl -> IsActive(This,pbActive) ) #define ICorDebugEval_Abort(This) \ - ( (This)->lpVtbl -> Abort(This) ) + ( (This)->lpVtbl -> Abort(This) ) #define ICorDebugEval_GetResult(This,ppResult) \ - ( (This)->lpVtbl -> GetResult(This,ppResult) ) + ( (This)->lpVtbl -> GetResult(This,ppResult) ) #define ICorDebugEval_GetThread(This,ppThread) \ - ( (This)->lpVtbl -> GetThread(This,ppThread) ) + ( (This)->lpVtbl -> GetThread(This,ppThread) ) #define ICorDebugEval_CreateValue(This,elementType,pElementClass,ppValue) \ - ( (This)->lpVtbl -> CreateValue(This,elementType,pElementClass,ppValue) ) + ( (This)->lpVtbl -> CreateValue(This,elementType,pElementClass,ppValue) ) #endif /* COBJMACROS */ @@ -14815,125 +14822,125 @@ EXTERN_C const IID IID_ICorDebugEval; #define __ICorDebugEval2_INTERFACE_DEFINED__ /* interface ICorDebugEval2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugEval2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("FB0D9CE7-BE66-4683-9D32-A42A04E2FD91") ICorDebugEval2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CallParameterizedFunction( + virtual HRESULT STDMETHODCALLTYPE CallParameterizedFunction( /* [in] */ ICorDebugFunction *pFunction, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateValueForType( + + virtual HRESULT STDMETHODCALLTYPE CreateValueForType( /* [in] */ ICorDebugType *pType, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewParameterizedObject( + + virtual HRESULT STDMETHODCALLTYPE NewParameterizedObject( /* [in] */ ICorDebugFunction *pConstructor, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewParameterizedObjectNoConstructor( + + virtual HRESULT STDMETHODCALLTYPE NewParameterizedObjectNoConstructor( /* [in] */ ICorDebugClass *pClass, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewParameterizedArray( + + virtual HRESULT STDMETHODCALLTYPE NewParameterizedArray( /* [in] */ ICorDebugType *pElementType, /* [in] */ ULONG32 rank, /* [size_is][in] */ ULONG32 dims[ ], /* [size_is][in] */ ULONG32 lowBounds[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE NewStringWithLength( + + virtual HRESULT STDMETHODCALLTYPE NewStringWithLength( /* [in] */ LPCWSTR string, /* [in] */ UINT uiLength) = 0; - + virtual HRESULT STDMETHODCALLTYPE RudeAbort( void) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugEval2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugEval2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugEval2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugEval2 * This); - + DECLSPEC_XFGVIRT(ICorDebugEval2, CallParameterizedFunction) - HRESULT ( STDMETHODCALLTYPE *CallParameterizedFunction )( + HRESULT ( STDMETHODCALLTYPE *CallParameterizedFunction )( ICorDebugEval2 * This, /* [in] */ ICorDebugFunction *pFunction, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEval2, CreateValueForType) - HRESULT ( STDMETHODCALLTYPE *CreateValueForType )( + HRESULT ( STDMETHODCALLTYPE *CreateValueForType )( ICorDebugEval2 * This, /* [in] */ ICorDebugType *pType, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugEval2, NewParameterizedObject) - HRESULT ( STDMETHODCALLTYPE *NewParameterizedObject )( + HRESULT ( STDMETHODCALLTYPE *NewParameterizedObject )( ICorDebugEval2 * This, /* [in] */ ICorDebugFunction *pConstructor, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ], /* [in] */ ULONG32 nArgs, /* [size_is][in] */ ICorDebugValue *ppArgs[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEval2, NewParameterizedObjectNoConstructor) - HRESULT ( STDMETHODCALLTYPE *NewParameterizedObjectNoConstructor )( + HRESULT ( STDMETHODCALLTYPE *NewParameterizedObjectNoConstructor )( ICorDebugEval2 * This, /* [in] */ ICorDebugClass *pClass, /* [in] */ ULONG32 nTypeArgs, /* [size_is][in] */ ICorDebugType *ppTypeArgs[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEval2, NewParameterizedArray) - HRESULT ( STDMETHODCALLTYPE *NewParameterizedArray )( + HRESULT ( STDMETHODCALLTYPE *NewParameterizedArray )( ICorDebugEval2 * This, /* [in] */ ICorDebugType *pElementType, /* [in] */ ULONG32 rank, /* [size_is][in] */ ULONG32 dims[ ], /* [size_is][in] */ ULONG32 lowBounds[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEval2, NewStringWithLength) - HRESULT ( STDMETHODCALLTYPE *NewStringWithLength )( + HRESULT ( STDMETHODCALLTYPE *NewStringWithLength )( ICorDebugEval2 * This, /* [in] */ LPCWSTR string, /* [in] */ UINT uiLength); - + DECLSPEC_XFGVIRT(ICorDebugEval2, RudeAbort) - HRESULT ( STDMETHODCALLTYPE *RudeAbort )( + HRESULT ( STDMETHODCALLTYPE *RudeAbort )( ICorDebugEval2 * This); - + END_INTERFACE } ICorDebugEval2Vtbl; @@ -14942,41 +14949,41 @@ EXTERN_C const IID IID_ICorDebugEval2; CONST_VTBL struct ICorDebugEval2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugEval2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugEval2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugEval2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugEval2_CallParameterizedFunction(This,pFunction,nTypeArgs,ppTypeArgs,nArgs,ppArgs) \ - ( (This)->lpVtbl -> CallParameterizedFunction(This,pFunction,nTypeArgs,ppTypeArgs,nArgs,ppArgs) ) + ( (This)->lpVtbl -> CallParameterizedFunction(This,pFunction,nTypeArgs,ppTypeArgs,nArgs,ppArgs) ) #define ICorDebugEval2_CreateValueForType(This,pType,ppValue) \ - ( (This)->lpVtbl -> CreateValueForType(This,pType,ppValue) ) + ( (This)->lpVtbl -> CreateValueForType(This,pType,ppValue) ) #define ICorDebugEval2_NewParameterizedObject(This,pConstructor,nTypeArgs,ppTypeArgs,nArgs,ppArgs) \ - ( (This)->lpVtbl -> NewParameterizedObject(This,pConstructor,nTypeArgs,ppTypeArgs,nArgs,ppArgs) ) + ( (This)->lpVtbl -> NewParameterizedObject(This,pConstructor,nTypeArgs,ppTypeArgs,nArgs,ppArgs) ) #define ICorDebugEval2_NewParameterizedObjectNoConstructor(This,pClass,nTypeArgs,ppTypeArgs) \ - ( (This)->lpVtbl -> NewParameterizedObjectNoConstructor(This,pClass,nTypeArgs,ppTypeArgs) ) + ( (This)->lpVtbl -> NewParameterizedObjectNoConstructor(This,pClass,nTypeArgs,ppTypeArgs) ) #define ICorDebugEval2_NewParameterizedArray(This,pElementType,rank,dims,lowBounds) \ - ( (This)->lpVtbl -> NewParameterizedArray(This,pElementType,rank,dims,lowBounds) ) + ( (This)->lpVtbl -> NewParameterizedArray(This,pElementType,rank,dims,lowBounds) ) #define ICorDebugEval2_NewStringWithLength(This,string,uiLength) \ - ( (This)->lpVtbl -> NewStringWithLength(This,string,uiLength) ) + ( (This)->lpVtbl -> NewStringWithLength(This,string,uiLength) ) #define ICorDebugEval2_RudeAbort(This) \ - ( (This)->lpVtbl -> RudeAbort(This) ) + ( (This)->lpVtbl -> RudeAbort(This) ) #endif /* COBJMACROS */ @@ -14993,73 +15000,73 @@ EXTERN_C const IID IID_ICorDebugEval2; #define __ICorDebugValue_INTERFACE_DEFINED__ /* interface ICorDebugValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAF7-8A68-11d2-983C-0000F808342D") ICorDebugValue : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetType( + virtual HRESULT STDMETHODCALLTYPE GetType( /* [out] */ CorElementType *pType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSize( + + virtual HRESULT STDMETHODCALLTYPE GetSize( /* [out] */ ULONG32 *pSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetAddress( + + virtual HRESULT STDMETHODCALLTYPE GetAddress( /* [out] */ CORDB_ADDRESS *pAddress) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE CreateBreakpoint( /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + END_INTERFACE } ICorDebugValueVtbl; @@ -15068,32 +15075,32 @@ EXTERN_C const IID IID_ICorDebugValue; CONST_VTBL struct ICorDebugValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #endif /* COBJMACROS */ @@ -15110,49 +15117,49 @@ EXTERN_C const IID IID_ICorDebugValue; #define __ICorDebugValue2_INTERFACE_DEFINED__ /* interface ICorDebugValue2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugValue2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("5E0B54E7-D88A-4626-9420-A691E0A78B49") ICorDebugValue2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetExactType( + virtual HRESULT STDMETHODCALLTYPE GetExactType( /* [out] */ ICorDebugType **ppType) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugValue2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugValue2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugValue2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugValue2 * This); - + DECLSPEC_XFGVIRT(ICorDebugValue2, GetExactType) - HRESULT ( STDMETHODCALLTYPE *GetExactType )( + HRESULT ( STDMETHODCALLTYPE *GetExactType )( ICorDebugValue2 * This, /* [out] */ ICorDebugType **ppType); - + END_INTERFACE } ICorDebugValue2Vtbl; @@ -15161,23 +15168,23 @@ EXTERN_C const IID IID_ICorDebugValue2; CONST_VTBL struct ICorDebugValue2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugValue2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugValue2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugValue2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugValue2_GetExactType(This,ppType) \ - ( (This)->lpVtbl -> GetExactType(This,ppType) ) + ( (This)->lpVtbl -> GetExactType(This,ppType) ) #endif /* COBJMACROS */ @@ -15194,49 +15201,49 @@ EXTERN_C const IID IID_ICorDebugValue2; #define __ICorDebugValue3_INTERFACE_DEFINED__ /* interface ICorDebugValue3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugValue3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("565005FC-0F8A-4F3E-9EDB-83102B156595") ICorDebugValue3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetSize64( + virtual HRESULT STDMETHODCALLTYPE GetSize64( /* [out] */ ULONG64 *pSize) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugValue3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugValue3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugValue3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugValue3 * This); - + DECLSPEC_XFGVIRT(ICorDebugValue3, GetSize64) - HRESULT ( STDMETHODCALLTYPE *GetSize64 )( + HRESULT ( STDMETHODCALLTYPE *GetSize64 )( ICorDebugValue3 * This, /* [out] */ ULONG64 *pSize); - + END_INTERFACE } ICorDebugValue3Vtbl; @@ -15245,23 +15252,23 @@ EXTERN_C const IID IID_ICorDebugValue3; CONST_VTBL struct ICorDebugValue3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugValue3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugValue3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugValue3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugValue3_GetSize64(This,pSize) \ - ( (This)->lpVtbl -> GetSize64(This,pSize) ) + ( (This)->lpVtbl -> GetSize64(This,pSize) ) #endif /* COBJMACROS */ @@ -15278,77 +15285,77 @@ EXTERN_C const IID IID_ICorDebugValue3; #define __ICorDebugGenericValue_INTERFACE_DEFINED__ /* interface ICorDebugGenericValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugGenericValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAF8-8A68-11d2-983C-0000F808342D") ICorDebugGenericValue : public ICorDebugValue { public: - virtual HRESULT STDMETHODCALLTYPE GetValue( + virtual HRESULT STDMETHODCALLTYPE GetValue( /* [out] */ void *pTo) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetValue( + + virtual HRESULT STDMETHODCALLTYPE SetValue( /* [in] */ void *pFrom) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugGenericValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugGenericValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugGenericValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugGenericValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugGenericValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugGenericValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugGenericValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugGenericValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugGenericValue, GetValue) - HRESULT ( STDMETHODCALLTYPE *GetValue )( + HRESULT ( STDMETHODCALLTYPE *GetValue )( ICorDebugGenericValue * This, /* [out] */ void *pTo); - + DECLSPEC_XFGVIRT(ICorDebugGenericValue, SetValue) - HRESULT ( STDMETHODCALLTYPE *SetValue )( + HRESULT ( STDMETHODCALLTYPE *SetValue )( ICorDebugGenericValue * This, /* [in] */ void *pFrom); - + END_INTERFACE } ICorDebugGenericValueVtbl; @@ -15357,39 +15364,39 @@ EXTERN_C const IID IID_ICorDebugGenericValue; CONST_VTBL struct ICorDebugGenericValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugGenericValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugGenericValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugGenericValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugGenericValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugGenericValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugGenericValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugGenericValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugGenericValue_GetValue(This,pTo) \ - ( (This)->lpVtbl -> GetValue(This,pTo) ) + ( (This)->lpVtbl -> GetValue(This,pTo) ) #define ICorDebugGenericValue_SetValue(This,pFrom) \ - ( (This)->lpVtbl -> SetValue(This,pFrom) ) + ( (This)->lpVtbl -> SetValue(This,pFrom) ) #endif /* COBJMACROS */ @@ -15406,101 +15413,101 @@ EXTERN_C const IID IID_ICorDebugGenericValue; #define __ICorDebugReferenceValue_INTERFACE_DEFINED__ /* interface ICorDebugReferenceValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugReferenceValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAF9-8A68-11d2-983C-0000F808342D") ICorDebugReferenceValue : public ICorDebugValue { public: - virtual HRESULT STDMETHODCALLTYPE IsNull( + virtual HRESULT STDMETHODCALLTYPE IsNull( /* [out] */ BOOL *pbNull) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetValue( + + virtual HRESULT STDMETHODCALLTYPE GetValue( /* [out] */ CORDB_ADDRESS *pValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetValue( + + virtual HRESULT STDMETHODCALLTYPE SetValue( /* [in] */ CORDB_ADDRESS value) = 0; - - virtual HRESULT STDMETHODCALLTYPE Dereference( + + virtual HRESULT STDMETHODCALLTYPE Dereference( /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE DereferenceStrong( + + virtual HRESULT STDMETHODCALLTYPE DereferenceStrong( /* [out] */ ICorDebugValue **ppValue) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugReferenceValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugReferenceValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugReferenceValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugReferenceValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugReferenceValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugReferenceValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugReferenceValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugReferenceValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, IsNull) - HRESULT ( STDMETHODCALLTYPE *IsNull )( + HRESULT ( STDMETHODCALLTYPE *IsNull )( ICorDebugReferenceValue * This, /* [out] */ BOOL *pbNull); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, GetValue) - HRESULT ( STDMETHODCALLTYPE *GetValue )( + HRESULT ( STDMETHODCALLTYPE *GetValue )( ICorDebugReferenceValue * This, /* [out] */ CORDB_ADDRESS *pValue); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, SetValue) - HRESULT ( STDMETHODCALLTYPE *SetValue )( + HRESULT ( STDMETHODCALLTYPE *SetValue )( ICorDebugReferenceValue * This, /* [in] */ CORDB_ADDRESS value); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, Dereference) - HRESULT ( STDMETHODCALLTYPE *Dereference )( + HRESULT ( STDMETHODCALLTYPE *Dereference )( ICorDebugReferenceValue * This, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, DereferenceStrong) - HRESULT ( STDMETHODCALLTYPE *DereferenceStrong )( + HRESULT ( STDMETHODCALLTYPE *DereferenceStrong )( ICorDebugReferenceValue * This, /* [out] */ ICorDebugValue **ppValue); - + END_INTERFACE } ICorDebugReferenceValueVtbl; @@ -15509,48 +15516,48 @@ EXTERN_C const IID IID_ICorDebugReferenceValue; CONST_VTBL struct ICorDebugReferenceValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugReferenceValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugReferenceValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugReferenceValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugReferenceValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugReferenceValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugReferenceValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugReferenceValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugReferenceValue_IsNull(This,pbNull) \ - ( (This)->lpVtbl -> IsNull(This,pbNull) ) + ( (This)->lpVtbl -> IsNull(This,pbNull) ) #define ICorDebugReferenceValue_GetValue(This,pValue) \ - ( (This)->lpVtbl -> GetValue(This,pValue) ) + ( (This)->lpVtbl -> GetValue(This,pValue) ) #define ICorDebugReferenceValue_SetValue(This,value) \ - ( (This)->lpVtbl -> SetValue(This,value) ) + ( (This)->lpVtbl -> SetValue(This,value) ) #define ICorDebugReferenceValue_Dereference(This,ppValue) \ - ( (This)->lpVtbl -> Dereference(This,ppValue) ) + ( (This)->lpVtbl -> Dereference(This,ppValue) ) #define ICorDebugReferenceValue_DereferenceStrong(This,ppValue) \ - ( (This)->lpVtbl -> DereferenceStrong(This,ppValue) ) + ( (This)->lpVtbl -> DereferenceStrong(This,ppValue) ) #endif /* COBJMACROS */ @@ -15567,77 +15574,77 @@ EXTERN_C const IID IID_ICorDebugReferenceValue; #define __ICorDebugHeapValue_INTERFACE_DEFINED__ /* interface ICorDebugHeapValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugHeapValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAFA-8A68-11d2-983C-0000F808342D") ICorDebugHeapValue : public ICorDebugValue { public: - virtual HRESULT STDMETHODCALLTYPE IsValid( + virtual HRESULT STDMETHODCALLTYPE IsValid( /* [out] */ BOOL *pbValid) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateRelocBreakpoint( + + virtual HRESULT STDMETHODCALLTYPE CreateRelocBreakpoint( /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugHeapValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugHeapValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugHeapValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugHeapValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugHeapValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugHeapValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugHeapValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugHeapValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, IsValid) - HRESULT ( STDMETHODCALLTYPE *IsValid )( + HRESULT ( STDMETHODCALLTYPE *IsValid )( ICorDebugHeapValue * This, /* [out] */ BOOL *pbValid); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, CreateRelocBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( ICorDebugHeapValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + END_INTERFACE } ICorDebugHeapValueVtbl; @@ -15646,39 +15653,39 @@ EXTERN_C const IID IID_ICorDebugHeapValue; CONST_VTBL struct ICorDebugHeapValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugHeapValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugHeapValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugHeapValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugHeapValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugHeapValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugHeapValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugHeapValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugHeapValue_IsValid(This,pbValid) \ - ( (This)->lpVtbl -> IsValid(This,pbValid) ) + ( (This)->lpVtbl -> IsValid(This,pbValid) ) #define ICorDebugHeapValue_CreateRelocBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) #endif /* COBJMACROS */ @@ -15695,51 +15702,51 @@ EXTERN_C const IID IID_ICorDebugHeapValue; #define __ICorDebugHeapValue2_INTERFACE_DEFINED__ /* interface ICorDebugHeapValue2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugHeapValue2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("E3AC4D6C-9CB7-43e6-96CC-B21540E5083C") ICorDebugHeapValue2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CreateHandle( + virtual HRESULT STDMETHODCALLTYPE CreateHandle( /* [in] */ CorDebugHandleType type, /* [out] */ ICorDebugHandleValue **ppHandle) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugHeapValue2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugHeapValue2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugHeapValue2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugHeapValue2 * This); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue2, CreateHandle) - HRESULT ( STDMETHODCALLTYPE *CreateHandle )( + HRESULT ( STDMETHODCALLTYPE *CreateHandle )( ICorDebugHeapValue2 * This, /* [in] */ CorDebugHandleType type, /* [out] */ ICorDebugHandleValue **ppHandle); - + END_INTERFACE } ICorDebugHeapValue2Vtbl; @@ -15748,23 +15755,23 @@ EXTERN_C const IID IID_ICorDebugHeapValue2; CONST_VTBL struct ICorDebugHeapValue2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugHeapValue2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugHeapValue2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugHeapValue2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugHeapValue2_CreateHandle(This,type,ppHandle) \ - ( (This)->lpVtbl -> CreateHandle(This,type,ppHandle) ) + ( (This)->lpVtbl -> CreateHandle(This,type,ppHandle) ) #endif /* COBJMACROS */ @@ -15781,59 +15788,59 @@ EXTERN_C const IID IID_ICorDebugHeapValue2; #define __ICorDebugHeapValue3_INTERFACE_DEFINED__ /* interface ICorDebugHeapValue3 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugHeapValue3; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("A69ACAD8-2374-46e9-9FF8-B1F14120D296") ICorDebugHeapValue3 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetThreadOwningMonitorLock( + virtual HRESULT STDMETHODCALLTYPE GetThreadOwningMonitorLock( /* [out] */ ICorDebugThread **ppThread, /* [out] */ DWORD *pAcquisitionCount) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetMonitorEventWaitList( + + virtual HRESULT STDMETHODCALLTYPE GetMonitorEventWaitList( /* [out] */ ICorDebugThreadEnum **ppThreadEnum) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugHeapValue3Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugHeapValue3 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugHeapValue3 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugHeapValue3 * This); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue3, GetThreadOwningMonitorLock) - HRESULT ( STDMETHODCALLTYPE *GetThreadOwningMonitorLock )( + HRESULT ( STDMETHODCALLTYPE *GetThreadOwningMonitorLock )( ICorDebugHeapValue3 * This, /* [out] */ ICorDebugThread **ppThread, /* [out] */ DWORD *pAcquisitionCount); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue3, GetMonitorEventWaitList) - HRESULT ( STDMETHODCALLTYPE *GetMonitorEventWaitList )( + HRESULT ( STDMETHODCALLTYPE *GetMonitorEventWaitList )( ICorDebugHeapValue3 * This, /* [out] */ ICorDebugThreadEnum **ppThreadEnum); - + END_INTERFACE } ICorDebugHeapValue3Vtbl; @@ -15842,26 +15849,26 @@ EXTERN_C const IID IID_ICorDebugHeapValue3; CONST_VTBL struct ICorDebugHeapValue3Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugHeapValue3_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugHeapValue3_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugHeapValue3_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugHeapValue3_GetThreadOwningMonitorLock(This,ppThread,pAcquisitionCount) \ - ( (This)->lpVtbl -> GetThreadOwningMonitorLock(This,ppThread,pAcquisitionCount) ) + ( (This)->lpVtbl -> GetThreadOwningMonitorLock(This,ppThread,pAcquisitionCount) ) #define ICorDebugHeapValue3_GetMonitorEventWaitList(This,ppThreadEnum) \ - ( (This)->lpVtbl -> GetMonitorEventWaitList(This,ppThreadEnum) ) + ( (This)->lpVtbl -> GetMonitorEventWaitList(This,ppThreadEnum) ) #endif /* COBJMACROS */ @@ -15878,49 +15885,49 @@ EXTERN_C const IID IID_ICorDebugHeapValue3; #define __ICorDebugHeapValue4_INTERFACE_DEFINED__ /* interface ICorDebugHeapValue4 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugHeapValue4; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("B35DD495-A555-463B-9BE9-C55338486BB8") ICorDebugHeapValue4 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CreatePinnedHandle( + virtual HRESULT STDMETHODCALLTYPE CreatePinnedHandle( /* [out] */ ICorDebugHandleValue **ppHandle) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugHeapValue4Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugHeapValue4 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugHeapValue4 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugHeapValue4 * This); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue4, CreatePinnedHandle) - HRESULT ( STDMETHODCALLTYPE *CreatePinnedHandle )( + HRESULT ( STDMETHODCALLTYPE *CreatePinnedHandle )( ICorDebugHeapValue4 * This, /* [out] */ ICorDebugHandleValue **ppHandle); - + END_INTERFACE } ICorDebugHeapValue4Vtbl; @@ -15929,23 +15936,23 @@ EXTERN_C const IID IID_ICorDebugHeapValue4; CONST_VTBL struct ICorDebugHeapValue4Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugHeapValue4_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugHeapValue4_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugHeapValue4_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugHeapValue4_CreatePinnedHandle(This,ppHandle) \ - ( (This)->lpVtbl -> CreatePinnedHandle(This,ppHandle) ) + ( (This)->lpVtbl -> CreatePinnedHandle(This,ppHandle) ) #endif /* COBJMACROS */ @@ -15962,123 +15969,123 @@ EXTERN_C const IID IID_ICorDebugHeapValue4; #define __ICorDebugObjectValue_INTERFACE_DEFINED__ /* interface ICorDebugObjectValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugObjectValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("18AD3D6E-B7D2-11d2-BD04-0000F80849BD") ICorDebugObjectValue : public ICorDebugValue { public: - virtual HRESULT STDMETHODCALLTYPE GetClass( + virtual HRESULT STDMETHODCALLTYPE GetClass( /* [out] */ ICorDebugClass **ppClass) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFieldValue( + + virtual HRESULT STDMETHODCALLTYPE GetFieldValue( /* [in] */ ICorDebugClass *pClass, /* [in] */ mdFieldDef fieldDef, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetVirtualMethod( + + virtual HRESULT STDMETHODCALLTYPE GetVirtualMethod( /* [in] */ mdMemberRef memberRef, /* [out] */ ICorDebugFunction **ppFunction) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetContext( + + virtual HRESULT STDMETHODCALLTYPE GetContext( /* [out] */ ICorDebugContext **ppContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsValueClass( + + virtual HRESULT STDMETHODCALLTYPE IsValueClass( /* [out] */ BOOL *pbIsValueClass) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetManagedCopy( + + virtual HRESULT STDMETHODCALLTYPE GetManagedCopy( /* [out] */ IUnknown **ppObject) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetFromManagedCopy( + + virtual HRESULT STDMETHODCALLTYPE SetFromManagedCopy( /* [in] */ IUnknown *pObject) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugObjectValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugObjectValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugObjectValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugObjectValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugObjectValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugObjectValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugObjectValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugObjectValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetClass) - HRESULT ( STDMETHODCALLTYPE *GetClass )( + HRESULT ( STDMETHODCALLTYPE *GetClass )( ICorDebugObjectValue * This, /* [out] */ ICorDebugClass **ppClass); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetFieldValue) - HRESULT ( STDMETHODCALLTYPE *GetFieldValue )( + HRESULT ( STDMETHODCALLTYPE *GetFieldValue )( ICorDebugObjectValue * This, /* [in] */ ICorDebugClass *pClass, /* [in] */ mdFieldDef fieldDef, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetVirtualMethod) - HRESULT ( STDMETHODCALLTYPE *GetVirtualMethod )( + HRESULT ( STDMETHODCALLTYPE *GetVirtualMethod )( ICorDebugObjectValue * This, /* [in] */ mdMemberRef memberRef, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetContext) - HRESULT ( STDMETHODCALLTYPE *GetContext )( + HRESULT ( STDMETHODCALLTYPE *GetContext )( ICorDebugObjectValue * This, /* [out] */ ICorDebugContext **ppContext); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, IsValueClass) - HRESULT ( STDMETHODCALLTYPE *IsValueClass )( + HRESULT ( STDMETHODCALLTYPE *IsValueClass )( ICorDebugObjectValue * This, /* [out] */ BOOL *pbIsValueClass); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetManagedCopy) - HRESULT ( STDMETHODCALLTYPE *GetManagedCopy )( + HRESULT ( STDMETHODCALLTYPE *GetManagedCopy )( ICorDebugObjectValue * This, /* [out] */ IUnknown **ppObject); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, SetFromManagedCopy) - HRESULT ( STDMETHODCALLTYPE *SetFromManagedCopy )( + HRESULT ( STDMETHODCALLTYPE *SetFromManagedCopy )( ICorDebugObjectValue * This, /* [in] */ IUnknown *pObject); - + END_INTERFACE } ICorDebugObjectValueVtbl; @@ -16087,54 +16094,54 @@ EXTERN_C const IID IID_ICorDebugObjectValue; CONST_VTBL struct ICorDebugObjectValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugObjectValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugObjectValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugObjectValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugObjectValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugObjectValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugObjectValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugObjectValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugObjectValue_GetClass(This,ppClass) \ - ( (This)->lpVtbl -> GetClass(This,ppClass) ) + ( (This)->lpVtbl -> GetClass(This,ppClass) ) #define ICorDebugObjectValue_GetFieldValue(This,pClass,fieldDef,ppValue) \ - ( (This)->lpVtbl -> GetFieldValue(This,pClass,fieldDef,ppValue) ) + ( (This)->lpVtbl -> GetFieldValue(This,pClass,fieldDef,ppValue) ) #define ICorDebugObjectValue_GetVirtualMethod(This,memberRef,ppFunction) \ - ( (This)->lpVtbl -> GetVirtualMethod(This,memberRef,ppFunction) ) + ( (This)->lpVtbl -> GetVirtualMethod(This,memberRef,ppFunction) ) #define ICorDebugObjectValue_GetContext(This,ppContext) \ - ( (This)->lpVtbl -> GetContext(This,ppContext) ) + ( (This)->lpVtbl -> GetContext(This,ppContext) ) #define ICorDebugObjectValue_IsValueClass(This,pbIsValueClass) \ - ( (This)->lpVtbl -> IsValueClass(This,pbIsValueClass) ) + ( (This)->lpVtbl -> IsValueClass(This,pbIsValueClass) ) #define ICorDebugObjectValue_GetManagedCopy(This,ppObject) \ - ( (This)->lpVtbl -> GetManagedCopy(This,ppObject) ) + ( (This)->lpVtbl -> GetManagedCopy(This,ppObject) ) #define ICorDebugObjectValue_SetFromManagedCopy(This,pObject) \ - ( (This)->lpVtbl -> SetFromManagedCopy(This,pObject) ) + ( (This)->lpVtbl -> SetFromManagedCopy(This,pObject) ) #endif /* COBJMACROS */ @@ -16151,53 +16158,53 @@ EXTERN_C const IID IID_ICorDebugObjectValue; #define __ICorDebugObjectValue2_INTERFACE_DEFINED__ /* interface ICorDebugObjectValue2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugObjectValue2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("49E4A320-4A9B-4eca-B105-229FB7D5009F") ICorDebugObjectValue2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetVirtualMethodAndType( + virtual HRESULT STDMETHODCALLTYPE GetVirtualMethodAndType( /* [in] */ mdMemberRef memberRef, /* [out] */ ICorDebugFunction **ppFunction, /* [out] */ ICorDebugType **ppType) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugObjectValue2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugObjectValue2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugObjectValue2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugObjectValue2 * This); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue2, GetVirtualMethodAndType) - HRESULT ( STDMETHODCALLTYPE *GetVirtualMethodAndType )( + HRESULT ( STDMETHODCALLTYPE *GetVirtualMethodAndType )( ICorDebugObjectValue2 * This, /* [in] */ mdMemberRef memberRef, /* [out] */ ICorDebugFunction **ppFunction, /* [out] */ ICorDebugType **ppType); - + END_INTERFACE } ICorDebugObjectValue2Vtbl; @@ -16206,23 +16213,23 @@ EXTERN_C const IID IID_ICorDebugObjectValue2; CONST_VTBL struct ICorDebugObjectValue2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugObjectValue2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugObjectValue2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugObjectValue2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugObjectValue2_GetVirtualMethodAndType(This,memberRef,ppFunction,ppType) \ - ( (This)->lpVtbl -> GetVirtualMethodAndType(This,memberRef,ppFunction,ppType) ) + ( (This)->lpVtbl -> GetVirtualMethodAndType(This,memberRef,ppFunction,ppType) ) #endif /* COBJMACROS */ @@ -16239,57 +16246,57 @@ EXTERN_C const IID IID_ICorDebugObjectValue2; #define __ICorDebugDelegateObjectValue_INTERFACE_DEFINED__ /* interface ICorDebugDelegateObjectValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugDelegateObjectValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("3AF70CC7-6047-47F6-A5C5-090A1A622638") ICorDebugDelegateObjectValue : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetTarget( + virtual HRESULT STDMETHODCALLTYPE GetTarget( /* [out] */ ICorDebugReferenceValue **ppObject) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFunction( + + virtual HRESULT STDMETHODCALLTYPE GetFunction( /* [out] */ ICorDebugFunction **ppFunction) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugDelegateObjectValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugDelegateObjectValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugDelegateObjectValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugDelegateObjectValue * This); - + DECLSPEC_XFGVIRT(ICorDebugDelegateObjectValue, GetTarget) - HRESULT ( STDMETHODCALLTYPE *GetTarget )( + HRESULT ( STDMETHODCALLTYPE *GetTarget )( ICorDebugDelegateObjectValue * This, /* [out] */ ICorDebugReferenceValue **ppObject); - + DECLSPEC_XFGVIRT(ICorDebugDelegateObjectValue, GetFunction) - HRESULT ( STDMETHODCALLTYPE *GetFunction )( + HRESULT ( STDMETHODCALLTYPE *GetFunction )( ICorDebugDelegateObjectValue * This, /* [out] */ ICorDebugFunction **ppFunction); - + END_INTERFACE } ICorDebugDelegateObjectValueVtbl; @@ -16298,26 +16305,26 @@ EXTERN_C const IID IID_ICorDebugDelegateObjectValue; CONST_VTBL struct ICorDebugDelegateObjectValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugDelegateObjectValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugDelegateObjectValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugDelegateObjectValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugDelegateObjectValue_GetTarget(This,ppObject) \ - ( (This)->lpVtbl -> GetTarget(This,ppObject) ) + ( (This)->lpVtbl -> GetTarget(This,ppObject) ) #define ICorDebugDelegateObjectValue_GetFunction(This,ppFunction) \ - ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) + ( (This)->lpVtbl -> GetFunction(This,ppFunction) ) #endif /* COBJMACROS */ @@ -16334,79 +16341,79 @@ EXTERN_C const IID IID_ICorDebugDelegateObjectValue; #define __ICorDebugBoxValue_INTERFACE_DEFINED__ /* interface ICorDebugBoxValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugBoxValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAFC-8A68-11d2-983C-0000F808342D") ICorDebugBoxValue : public ICorDebugHeapValue { public: - virtual HRESULT STDMETHODCALLTYPE GetObject( + virtual HRESULT STDMETHODCALLTYPE GetObject( /* [out] */ ICorDebugObjectValue **ppObject) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugBoxValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugBoxValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugBoxValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugBoxValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugBoxValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugBoxValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugBoxValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugBoxValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, IsValid) - HRESULT ( STDMETHODCALLTYPE *IsValid )( + HRESULT ( STDMETHODCALLTYPE *IsValid )( ICorDebugBoxValue * This, /* [out] */ BOOL *pbValid); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, CreateRelocBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( ICorDebugBoxValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugBoxValue, GetObject) - HRESULT ( STDMETHODCALLTYPE *GetObject )( + HRESULT ( STDMETHODCALLTYPE *GetObject )( ICorDebugBoxValue * This, /* [out] */ ICorDebugObjectValue **ppObject); - + END_INTERFACE } ICorDebugBoxValueVtbl; @@ -16415,43 +16422,43 @@ EXTERN_C const IID IID_ICorDebugBoxValue; CONST_VTBL struct ICorDebugBoxValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugBoxValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugBoxValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugBoxValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugBoxValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugBoxValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugBoxValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugBoxValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugBoxValue_IsValid(This,pbValid) \ - ( (This)->lpVtbl -> IsValid(This,pbValid) ) + ( (This)->lpVtbl -> IsValid(This,pbValid) ) #define ICorDebugBoxValue_CreateRelocBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) #define ICorDebugBoxValue_GetObject(This,ppObject) \ - ( (This)->lpVtbl -> GetObject(This,ppObject) ) + ( (This)->lpVtbl -> GetObject(This,ppObject) ) #endif /* COBJMACROS */ @@ -16465,10 +16472,10 @@ EXTERN_C const IID IID_ICorDebugBoxValue; /* interface __MIDL_itf_cordebug_0000_0106 */ -/* [local] */ +/* [local] */ #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0106_v0_0_c_ifspec; @@ -16478,91 +16485,91 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0106_v0_0_s_ifspec; #define __ICorDebugStringValue_INTERFACE_DEFINED__ /* interface ICorDebugStringValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugStringValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCAFD-8A68-11d2-983C-0000F808342D") ICorDebugStringValue : public ICorDebugHeapValue { public: - virtual HRESULT STDMETHODCALLTYPE GetLength( + virtual HRESULT STDMETHODCALLTYPE GetLength( /* [out] */ ULONG32 *pcchString) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetString( + + virtual HRESULT STDMETHODCALLTYPE GetString( /* [in] */ ULONG32 cchString, /* [out] */ ULONG32 *pcchString, /* [length_is][size_is][out] */ WCHAR szString[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugStringValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugStringValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugStringValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugStringValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugStringValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugStringValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugStringValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugStringValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, IsValid) - HRESULT ( STDMETHODCALLTYPE *IsValid )( + HRESULT ( STDMETHODCALLTYPE *IsValid )( ICorDebugStringValue * This, /* [out] */ BOOL *pbValid); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, CreateRelocBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( ICorDebugStringValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugStringValue, GetLength) - HRESULT ( STDMETHODCALLTYPE *GetLength )( + HRESULT ( STDMETHODCALLTYPE *GetLength )( ICorDebugStringValue * This, /* [out] */ ULONG32 *pcchString); - + DECLSPEC_XFGVIRT(ICorDebugStringValue, GetString) - HRESULT ( STDMETHODCALLTYPE *GetString )( + HRESULT ( STDMETHODCALLTYPE *GetString )( ICorDebugStringValue * This, /* [in] */ ULONG32 cchString, /* [out] */ ULONG32 *pcchString, /* [length_is][size_is][out] */ WCHAR szString[ ]); - + END_INTERFACE } ICorDebugStringValueVtbl; @@ -16571,46 +16578,46 @@ EXTERN_C const IID IID_ICorDebugStringValue; CONST_VTBL struct ICorDebugStringValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugStringValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugStringValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugStringValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugStringValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugStringValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugStringValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugStringValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugStringValue_IsValid(This,pbValid) \ - ( (This)->lpVtbl -> IsValid(This,pbValid) ) + ( (This)->lpVtbl -> IsValid(This,pbValid) ) #define ICorDebugStringValue_CreateRelocBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) #define ICorDebugStringValue_GetLength(This,pcchString) \ - ( (This)->lpVtbl -> GetLength(This,pcchString) ) + ( (This)->lpVtbl -> GetLength(This,pcchString) ) #define ICorDebugStringValue_GetString(This,cchString,pcchString,szString) \ - ( (This)->lpVtbl -> GetString(This,cchString,pcchString,szString) ) + ( (This)->lpVtbl -> GetString(This,cchString,pcchString,szString) ) #endif /* COBJMACROS */ @@ -16624,7 +16631,7 @@ EXTERN_C const IID IID_ICorDebugStringValue; /* interface __MIDL_itf_cordebug_0000_0107 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -16636,145 +16643,145 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0107_v0_0_s_ifspec; #define __ICorDebugArrayValue_INTERFACE_DEFINED__ /* interface ICorDebugArrayValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugArrayValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("0405B0DF-A660-11d2-BD02-0000F80849BD") ICorDebugArrayValue : public ICorDebugHeapValue { public: - virtual HRESULT STDMETHODCALLTYPE GetElementType( + virtual HRESULT STDMETHODCALLTYPE GetElementType( /* [out] */ CorElementType *pType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRank( + + virtual HRESULT STDMETHODCALLTYPE GetRank( /* [out] */ ULONG32 *pnRank) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCount( + + virtual HRESULT STDMETHODCALLTYPE GetCount( /* [out] */ ULONG32 *pnCount) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDimensions( + + virtual HRESULT STDMETHODCALLTYPE GetDimensions( /* [in] */ ULONG32 cdim, /* [length_is][size_is][out] */ ULONG32 dims[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE HasBaseIndicies( + + virtual HRESULT STDMETHODCALLTYPE HasBaseIndicies( /* [out] */ BOOL *pbHasBaseIndicies) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetBaseIndicies( + + virtual HRESULT STDMETHODCALLTYPE GetBaseIndicies( /* [in] */ ULONG32 cdim, /* [length_is][size_is][out] */ ULONG32 indices[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetElement( + + virtual HRESULT STDMETHODCALLTYPE GetElement( /* [in] */ ULONG32 cdim, /* [length_is][size_is][in] */ ULONG32 indices[ ], /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetElementAtPosition( + + virtual HRESULT STDMETHODCALLTYPE GetElementAtPosition( /* [in] */ ULONG32 nPosition, /* [out] */ ICorDebugValue **ppValue) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugArrayValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugArrayValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugArrayValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugArrayValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugArrayValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugArrayValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugArrayValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugArrayValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, IsValid) - HRESULT ( STDMETHODCALLTYPE *IsValid )( + HRESULT ( STDMETHODCALLTYPE *IsValid )( ICorDebugArrayValue * This, /* [out] */ BOOL *pbValid); - + DECLSPEC_XFGVIRT(ICorDebugHeapValue, CreateRelocBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateRelocBreakpoint )( ICorDebugArrayValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, GetElementType) - HRESULT ( STDMETHODCALLTYPE *GetElementType )( + HRESULT ( STDMETHODCALLTYPE *GetElementType )( ICorDebugArrayValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, GetRank) - HRESULT ( STDMETHODCALLTYPE *GetRank )( + HRESULT ( STDMETHODCALLTYPE *GetRank )( ICorDebugArrayValue * This, /* [out] */ ULONG32 *pnRank); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugArrayValue * This, /* [out] */ ULONG32 *pnCount); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, GetDimensions) - HRESULT ( STDMETHODCALLTYPE *GetDimensions )( + HRESULT ( STDMETHODCALLTYPE *GetDimensions )( ICorDebugArrayValue * This, /* [in] */ ULONG32 cdim, /* [length_is][size_is][out] */ ULONG32 dims[ ]); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, HasBaseIndicies) - HRESULT ( STDMETHODCALLTYPE *HasBaseIndicies )( + HRESULT ( STDMETHODCALLTYPE *HasBaseIndicies )( ICorDebugArrayValue * This, /* [out] */ BOOL *pbHasBaseIndicies); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, GetBaseIndicies) - HRESULT ( STDMETHODCALLTYPE *GetBaseIndicies )( + HRESULT ( STDMETHODCALLTYPE *GetBaseIndicies )( ICorDebugArrayValue * This, /* [in] */ ULONG32 cdim, /* [length_is][size_is][out] */ ULONG32 indices[ ]); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, GetElement) - HRESULT ( STDMETHODCALLTYPE *GetElement )( + HRESULT ( STDMETHODCALLTYPE *GetElement )( ICorDebugArrayValue * This, /* [in] */ ULONG32 cdim, /* [length_is][size_is][in] */ ULONG32 indices[ ], /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugArrayValue, GetElementAtPosition) - HRESULT ( STDMETHODCALLTYPE *GetElementAtPosition )( + HRESULT ( STDMETHODCALLTYPE *GetElementAtPosition )( ICorDebugArrayValue * This, /* [in] */ ULONG32 nPosition, /* [out] */ ICorDebugValue **ppValue); - + END_INTERFACE } ICorDebugArrayValueVtbl; @@ -16783,64 +16790,64 @@ EXTERN_C const IID IID_ICorDebugArrayValue; CONST_VTBL struct ICorDebugArrayValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugArrayValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugArrayValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugArrayValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugArrayValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugArrayValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugArrayValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugArrayValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugArrayValue_IsValid(This,pbValid) \ - ( (This)->lpVtbl -> IsValid(This,pbValid) ) + ( (This)->lpVtbl -> IsValid(This,pbValid) ) #define ICorDebugArrayValue_CreateRelocBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateRelocBreakpoint(This,ppBreakpoint) ) #define ICorDebugArrayValue_GetElementType(This,pType) \ - ( (This)->lpVtbl -> GetElementType(This,pType) ) + ( (This)->lpVtbl -> GetElementType(This,pType) ) #define ICorDebugArrayValue_GetRank(This,pnRank) \ - ( (This)->lpVtbl -> GetRank(This,pnRank) ) + ( (This)->lpVtbl -> GetRank(This,pnRank) ) #define ICorDebugArrayValue_GetCount(This,pnCount) \ - ( (This)->lpVtbl -> GetCount(This,pnCount) ) + ( (This)->lpVtbl -> GetCount(This,pnCount) ) #define ICorDebugArrayValue_GetDimensions(This,cdim,dims) \ - ( (This)->lpVtbl -> GetDimensions(This,cdim,dims) ) + ( (This)->lpVtbl -> GetDimensions(This,cdim,dims) ) #define ICorDebugArrayValue_HasBaseIndicies(This,pbHasBaseIndicies) \ - ( (This)->lpVtbl -> HasBaseIndicies(This,pbHasBaseIndicies) ) + ( (This)->lpVtbl -> HasBaseIndicies(This,pbHasBaseIndicies) ) #define ICorDebugArrayValue_GetBaseIndicies(This,cdim,indices) \ - ( (This)->lpVtbl -> GetBaseIndicies(This,cdim,indices) ) + ( (This)->lpVtbl -> GetBaseIndicies(This,cdim,indices) ) #define ICorDebugArrayValue_GetElement(This,cdim,indices,ppValue) \ - ( (This)->lpVtbl -> GetElement(This,cdim,indices,ppValue) ) + ( (This)->lpVtbl -> GetElement(This,cdim,indices,ppValue) ) #define ICorDebugArrayValue_GetElementAtPosition(This,nPosition,ppValue) \ - ( (This)->lpVtbl -> GetElementAtPosition(This,nPosition,ppValue) ) + ( (This)->lpVtbl -> GetElementAtPosition(This,nPosition,ppValue) ) #endif /* COBJMACROS */ @@ -16857,107 +16864,107 @@ EXTERN_C const IID IID_ICorDebugArrayValue; #define __ICorDebugVariableHome_INTERFACE_DEFINED__ /* interface ICorDebugVariableHome */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum VariableLocationType { VLT_REGISTER = 0, VLT_REGISTER_RELATIVE = ( VLT_REGISTER + 1 ) , - VLT_INVALID = ( VLT_REGISTER_RELATIVE + 1 ) + VLT_INVALID = ( VLT_REGISTER_RELATIVE + 1 ) } VariableLocationType; EXTERN_C const IID IID_ICorDebugVariableHome; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("50847b8d-f43f-41b0-924c-6383a5f2278b") ICorDebugVariableHome : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetCode( + virtual HRESULT STDMETHODCALLTYPE GetCode( /* [out] */ ICorDebugCode **ppCode) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetSlotIndex( + + virtual HRESULT STDMETHODCALLTYPE GetSlotIndex( /* [out] */ ULONG32 *pSlotIndex) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetArgumentIndex( + + virtual HRESULT STDMETHODCALLTYPE GetArgumentIndex( /* [out] */ ULONG32 *pArgumentIndex) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLiveRange( + + virtual HRESULT STDMETHODCALLTYPE GetLiveRange( /* [out] */ ULONG32 *pStartOffset, /* [out] */ ULONG32 *pEndOffset) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetLocationType( + + virtual HRESULT STDMETHODCALLTYPE GetLocationType( /* [out] */ VariableLocationType *pLocationType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRegister( + + virtual HRESULT STDMETHODCALLTYPE GetRegister( /* [out] */ CorDebugRegister *pRegister) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetOffset( + + virtual HRESULT STDMETHODCALLTYPE GetOffset( /* [out] */ LONG *pOffset) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugVariableHomeVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugVariableHome * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugVariableHome * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugVariableHome * This); - + DECLSPEC_XFGVIRT(ICorDebugVariableHome, GetCode) - HRESULT ( STDMETHODCALLTYPE *GetCode )( + HRESULT ( STDMETHODCALLTYPE *GetCode )( ICorDebugVariableHome * This, /* [out] */ ICorDebugCode **ppCode); - + DECLSPEC_XFGVIRT(ICorDebugVariableHome, GetSlotIndex) - HRESULT ( STDMETHODCALLTYPE *GetSlotIndex )( + HRESULT ( STDMETHODCALLTYPE *GetSlotIndex )( ICorDebugVariableHome * This, /* [out] */ ULONG32 *pSlotIndex); - + DECLSPEC_XFGVIRT(ICorDebugVariableHome, GetArgumentIndex) - HRESULT ( STDMETHODCALLTYPE *GetArgumentIndex )( + HRESULT ( STDMETHODCALLTYPE *GetArgumentIndex )( ICorDebugVariableHome * This, /* [out] */ ULONG32 *pArgumentIndex); - + DECLSPEC_XFGVIRT(ICorDebugVariableHome, GetLiveRange) - HRESULT ( STDMETHODCALLTYPE *GetLiveRange )( + HRESULT ( STDMETHODCALLTYPE *GetLiveRange )( ICorDebugVariableHome * This, /* [out] */ ULONG32 *pStartOffset, /* [out] */ ULONG32 *pEndOffset); - + DECLSPEC_XFGVIRT(ICorDebugVariableHome, GetLocationType) - HRESULT ( STDMETHODCALLTYPE *GetLocationType )( + HRESULT ( STDMETHODCALLTYPE *GetLocationType )( ICorDebugVariableHome * This, /* [out] */ VariableLocationType *pLocationType); - + DECLSPEC_XFGVIRT(ICorDebugVariableHome, GetRegister) - HRESULT ( STDMETHODCALLTYPE *GetRegister )( + HRESULT ( STDMETHODCALLTYPE *GetRegister )( ICorDebugVariableHome * This, /* [out] */ CorDebugRegister *pRegister); - + DECLSPEC_XFGVIRT(ICorDebugVariableHome, GetOffset) - HRESULT ( STDMETHODCALLTYPE *GetOffset )( + HRESULT ( STDMETHODCALLTYPE *GetOffset )( ICorDebugVariableHome * This, /* [out] */ LONG *pOffset); - + END_INTERFACE } ICorDebugVariableHomeVtbl; @@ -16966,41 +16973,41 @@ EXTERN_C const IID IID_ICorDebugVariableHome; CONST_VTBL struct ICorDebugVariableHomeVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugVariableHome_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugVariableHome_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugVariableHome_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugVariableHome_GetCode(This,ppCode) \ - ( (This)->lpVtbl -> GetCode(This,ppCode) ) + ( (This)->lpVtbl -> GetCode(This,ppCode) ) #define ICorDebugVariableHome_GetSlotIndex(This,pSlotIndex) \ - ( (This)->lpVtbl -> GetSlotIndex(This,pSlotIndex) ) + ( (This)->lpVtbl -> GetSlotIndex(This,pSlotIndex) ) #define ICorDebugVariableHome_GetArgumentIndex(This,pArgumentIndex) \ - ( (This)->lpVtbl -> GetArgumentIndex(This,pArgumentIndex) ) + ( (This)->lpVtbl -> GetArgumentIndex(This,pArgumentIndex) ) #define ICorDebugVariableHome_GetLiveRange(This,pStartOffset,pEndOffset) \ - ( (This)->lpVtbl -> GetLiveRange(This,pStartOffset,pEndOffset) ) + ( (This)->lpVtbl -> GetLiveRange(This,pStartOffset,pEndOffset) ) #define ICorDebugVariableHome_GetLocationType(This,pLocationType) \ - ( (This)->lpVtbl -> GetLocationType(This,pLocationType) ) + ( (This)->lpVtbl -> GetLocationType(This,pLocationType) ) #define ICorDebugVariableHome_GetRegister(This,pRegister) \ - ( (This)->lpVtbl -> GetRegister(This,pRegister) ) + ( (This)->lpVtbl -> GetRegister(This,pRegister) ) #define ICorDebugVariableHome_GetOffset(This,pOffset) \ - ( (This)->lpVtbl -> GetOffset(This,pOffset) ) + ( (This)->lpVtbl -> GetOffset(This,pOffset) ) #endif /* COBJMACROS */ @@ -17017,100 +17024,100 @@ EXTERN_C const IID IID_ICorDebugVariableHome; #define __ICorDebugHandleValue_INTERFACE_DEFINED__ /* interface ICorDebugHandleValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugHandleValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("029596E8-276B-46a1-9821-732E96BBB00B") ICorDebugHandleValue : public ICorDebugReferenceValue { public: - virtual HRESULT STDMETHODCALLTYPE GetHandleType( + virtual HRESULT STDMETHODCALLTYPE GetHandleType( /* [out] */ CorDebugHandleType *pType) = 0; - + virtual HRESULT STDMETHODCALLTYPE Dispose( void) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugHandleValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugHandleValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugHandleValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugHandleValue * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugHandleValue * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugHandleValue * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugHandleValue * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugHandleValue * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, IsNull) - HRESULT ( STDMETHODCALLTYPE *IsNull )( + HRESULT ( STDMETHODCALLTYPE *IsNull )( ICorDebugHandleValue * This, /* [out] */ BOOL *pbNull); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, GetValue) - HRESULT ( STDMETHODCALLTYPE *GetValue )( + HRESULT ( STDMETHODCALLTYPE *GetValue )( ICorDebugHandleValue * This, /* [out] */ CORDB_ADDRESS *pValue); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, SetValue) - HRESULT ( STDMETHODCALLTYPE *SetValue )( + HRESULT ( STDMETHODCALLTYPE *SetValue )( ICorDebugHandleValue * This, /* [in] */ CORDB_ADDRESS value); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, Dereference) - HRESULT ( STDMETHODCALLTYPE *Dereference )( + HRESULT ( STDMETHODCALLTYPE *Dereference )( ICorDebugHandleValue * This, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugReferenceValue, DereferenceStrong) - HRESULT ( STDMETHODCALLTYPE *DereferenceStrong )( + HRESULT ( STDMETHODCALLTYPE *DereferenceStrong )( ICorDebugHandleValue * This, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugHandleValue, GetHandleType) - HRESULT ( STDMETHODCALLTYPE *GetHandleType )( + HRESULT ( STDMETHODCALLTYPE *GetHandleType )( ICorDebugHandleValue * This, /* [out] */ CorDebugHandleType *pType); - + DECLSPEC_XFGVIRT(ICorDebugHandleValue, Dispose) - HRESULT ( STDMETHODCALLTYPE *Dispose )( + HRESULT ( STDMETHODCALLTYPE *Dispose )( ICorDebugHandleValue * This); - + END_INTERFACE } ICorDebugHandleValueVtbl; @@ -17119,55 +17126,55 @@ EXTERN_C const IID IID_ICorDebugHandleValue; CONST_VTBL struct ICorDebugHandleValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugHandleValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugHandleValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugHandleValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugHandleValue_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugHandleValue_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugHandleValue_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugHandleValue_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugHandleValue_IsNull(This,pbNull) \ - ( (This)->lpVtbl -> IsNull(This,pbNull) ) + ( (This)->lpVtbl -> IsNull(This,pbNull) ) #define ICorDebugHandleValue_GetValue(This,pValue) \ - ( (This)->lpVtbl -> GetValue(This,pValue) ) + ( (This)->lpVtbl -> GetValue(This,pValue) ) #define ICorDebugHandleValue_SetValue(This,value) \ - ( (This)->lpVtbl -> SetValue(This,value) ) + ( (This)->lpVtbl -> SetValue(This,value) ) #define ICorDebugHandleValue_Dereference(This,ppValue) \ - ( (This)->lpVtbl -> Dereference(This,ppValue) ) + ( (This)->lpVtbl -> Dereference(This,ppValue) ) #define ICorDebugHandleValue_DereferenceStrong(This,ppValue) \ - ( (This)->lpVtbl -> DereferenceStrong(This,ppValue) ) + ( (This)->lpVtbl -> DereferenceStrong(This,ppValue) ) #define ICorDebugHandleValue_GetHandleType(This,pType) \ - ( (This)->lpVtbl -> GetHandleType(This,pType) ) + ( (This)->lpVtbl -> GetHandleType(This,pType) ) #define ICorDebugHandleValue_Dispose(This) \ - ( (This)->lpVtbl -> Dispose(This) ) + ( (This)->lpVtbl -> Dispose(This) ) #endif /* COBJMACROS */ @@ -17184,99 +17191,99 @@ EXTERN_C const IID IID_ICorDebugHandleValue; #define __ICorDebugContext_INTERFACE_DEFINED__ /* interface ICorDebugContext */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugContext; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB00-8A68-11d2-983C-0000F808342D") ICorDebugContext : public ICorDebugObjectValue { public: }; - - + + #else /* C style interface */ typedef struct ICorDebugContextVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugContext * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugContext * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugContext * This); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugContext * This, /* [out] */ CorElementType *pType); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetSize) - HRESULT ( STDMETHODCALLTYPE *GetSize )( + HRESULT ( STDMETHODCALLTYPE *GetSize )( ICorDebugContext * This, /* [out] */ ULONG32 *pSize); - + DECLSPEC_XFGVIRT(ICorDebugValue, GetAddress) - HRESULT ( STDMETHODCALLTYPE *GetAddress )( + HRESULT ( STDMETHODCALLTYPE *GetAddress )( ICorDebugContext * This, /* [out] */ CORDB_ADDRESS *pAddress); - + DECLSPEC_XFGVIRT(ICorDebugValue, CreateBreakpoint) - HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( + HRESULT ( STDMETHODCALLTYPE *CreateBreakpoint )( ICorDebugContext * This, /* [out] */ ICorDebugValueBreakpoint **ppBreakpoint); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetClass) - HRESULT ( STDMETHODCALLTYPE *GetClass )( + HRESULT ( STDMETHODCALLTYPE *GetClass )( ICorDebugContext * This, /* [out] */ ICorDebugClass **ppClass); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetFieldValue) - HRESULT ( STDMETHODCALLTYPE *GetFieldValue )( + HRESULT ( STDMETHODCALLTYPE *GetFieldValue )( ICorDebugContext * This, /* [in] */ ICorDebugClass *pClass, /* [in] */ mdFieldDef fieldDef, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetVirtualMethod) - HRESULT ( STDMETHODCALLTYPE *GetVirtualMethod )( + HRESULT ( STDMETHODCALLTYPE *GetVirtualMethod )( ICorDebugContext * This, /* [in] */ mdMemberRef memberRef, /* [out] */ ICorDebugFunction **ppFunction); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetContext) - HRESULT ( STDMETHODCALLTYPE *GetContext )( + HRESULT ( STDMETHODCALLTYPE *GetContext )( ICorDebugContext * This, /* [out] */ ICorDebugContext **ppContext); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, IsValueClass) - HRESULT ( STDMETHODCALLTYPE *IsValueClass )( + HRESULT ( STDMETHODCALLTYPE *IsValueClass )( ICorDebugContext * This, /* [out] */ BOOL *pbIsValueClass); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, GetManagedCopy) - HRESULT ( STDMETHODCALLTYPE *GetManagedCopy )( + HRESULT ( STDMETHODCALLTYPE *GetManagedCopy )( ICorDebugContext * This, /* [out] */ IUnknown **ppObject); - + DECLSPEC_XFGVIRT(ICorDebugObjectValue, SetFromManagedCopy) - HRESULT ( STDMETHODCALLTYPE *SetFromManagedCopy )( + HRESULT ( STDMETHODCALLTYPE *SetFromManagedCopy )( ICorDebugContext * This, /* [in] */ IUnknown *pObject); - + END_INTERFACE } ICorDebugContextVtbl; @@ -17285,54 +17292,54 @@ EXTERN_C const IID IID_ICorDebugContext; CONST_VTBL struct ICorDebugContextVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugContext_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugContext_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugContext_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugContext_GetType(This,pType) \ - ( (This)->lpVtbl -> GetType(This,pType) ) + ( (This)->lpVtbl -> GetType(This,pType) ) #define ICorDebugContext_GetSize(This,pSize) \ - ( (This)->lpVtbl -> GetSize(This,pSize) ) + ( (This)->lpVtbl -> GetSize(This,pSize) ) #define ICorDebugContext_GetAddress(This,pAddress) \ - ( (This)->lpVtbl -> GetAddress(This,pAddress) ) + ( (This)->lpVtbl -> GetAddress(This,pAddress) ) #define ICorDebugContext_CreateBreakpoint(This,ppBreakpoint) \ - ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) + ( (This)->lpVtbl -> CreateBreakpoint(This,ppBreakpoint) ) #define ICorDebugContext_GetClass(This,ppClass) \ - ( (This)->lpVtbl -> GetClass(This,ppClass) ) + ( (This)->lpVtbl -> GetClass(This,ppClass) ) #define ICorDebugContext_GetFieldValue(This,pClass,fieldDef,ppValue) \ - ( (This)->lpVtbl -> GetFieldValue(This,pClass,fieldDef,ppValue) ) + ( (This)->lpVtbl -> GetFieldValue(This,pClass,fieldDef,ppValue) ) #define ICorDebugContext_GetVirtualMethod(This,memberRef,ppFunction) \ - ( (This)->lpVtbl -> GetVirtualMethod(This,memberRef,ppFunction) ) + ( (This)->lpVtbl -> GetVirtualMethod(This,memberRef,ppFunction) ) #define ICorDebugContext_GetContext(This,ppContext) \ - ( (This)->lpVtbl -> GetContext(This,ppContext) ) + ( (This)->lpVtbl -> GetContext(This,ppContext) ) #define ICorDebugContext_IsValueClass(This,pbIsValueClass) \ - ( (This)->lpVtbl -> IsValueClass(This,pbIsValueClass) ) + ( (This)->lpVtbl -> IsValueClass(This,pbIsValueClass) ) #define ICorDebugContext_GetManagedCopy(This,ppObject) \ - ( (This)->lpVtbl -> GetManagedCopy(This,ppObject) ) + ( (This)->lpVtbl -> GetManagedCopy(This,ppObject) ) #define ICorDebugContext_SetFromManagedCopy(This,pObject) \ - ( (This)->lpVtbl -> SetFromManagedCopy(This,pObject) ) + ( (This)->lpVtbl -> SetFromManagedCopy(This,pObject) ) #endif /* COBJMACROS */ @@ -17350,65 +17357,65 @@ EXTERN_C const IID IID_ICorDebugContext; #define __ICorDebugComObjectValue_INTERFACE_DEFINED__ /* interface ICorDebugComObjectValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugComObjectValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("5F69C5E5-3E12-42DF-B371-F9D761D6EE24") ICorDebugComObjectValue : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetCachedInterfaceTypes( + virtual HRESULT STDMETHODCALLTYPE GetCachedInterfaceTypes( /* [in] */ BOOL bIInspectableOnly, /* [out] */ ICorDebugTypeEnum **ppInterfacesEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCachedInterfacePointers( + + virtual HRESULT STDMETHODCALLTYPE GetCachedInterfacePointers( /* [in] */ BOOL bIInspectableOnly, /* [in] */ ULONG32 celt, /* [out] */ ULONG32 *pcEltFetched, /* [length_is][size_is][out] */ CORDB_ADDRESS *ptrs) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugComObjectValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugComObjectValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugComObjectValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugComObjectValue * This); - + DECLSPEC_XFGVIRT(ICorDebugComObjectValue, GetCachedInterfaceTypes) - HRESULT ( STDMETHODCALLTYPE *GetCachedInterfaceTypes )( + HRESULT ( STDMETHODCALLTYPE *GetCachedInterfaceTypes )( ICorDebugComObjectValue * This, /* [in] */ BOOL bIInspectableOnly, /* [out] */ ICorDebugTypeEnum **ppInterfacesEnum); - + DECLSPEC_XFGVIRT(ICorDebugComObjectValue, GetCachedInterfacePointers) - HRESULT ( STDMETHODCALLTYPE *GetCachedInterfacePointers )( + HRESULT ( STDMETHODCALLTYPE *GetCachedInterfacePointers )( ICorDebugComObjectValue * This, /* [in] */ BOOL bIInspectableOnly, /* [in] */ ULONG32 celt, /* [out] */ ULONG32 *pcEltFetched, /* [length_is][size_is][out] */ CORDB_ADDRESS *ptrs); - + END_INTERFACE } ICorDebugComObjectValueVtbl; @@ -17417,26 +17424,26 @@ EXTERN_C const IID IID_ICorDebugComObjectValue; CONST_VTBL struct ICorDebugComObjectValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugComObjectValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugComObjectValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugComObjectValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugComObjectValue_GetCachedInterfaceTypes(This,bIInspectableOnly,ppInterfacesEnum) \ - ( (This)->lpVtbl -> GetCachedInterfaceTypes(This,bIInspectableOnly,ppInterfacesEnum) ) + ( (This)->lpVtbl -> GetCachedInterfaceTypes(This,bIInspectableOnly,ppInterfacesEnum) ) #define ICorDebugComObjectValue_GetCachedInterfacePointers(This,bIInspectableOnly,celt,pcEltFetched,ptrs) \ - ( (This)->lpVtbl -> GetCachedInterfacePointers(This,bIInspectableOnly,celt,pcEltFetched,ptrs) ) + ( (This)->lpVtbl -> GetCachedInterfacePointers(This,bIInspectableOnly,celt,pcEltFetched,ptrs) ) #endif /* COBJMACROS */ @@ -17453,72 +17460,72 @@ EXTERN_C const IID IID_ICorDebugComObjectValue; #define __ICorDebugObjectEnum_INTERFACE_DEFINED__ /* interface ICorDebugObjectEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugObjectEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB02-8A68-11d2-983C-0000F808342D") ICorDebugObjectEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CORDB_ADDRESS objects[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugObjectEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugObjectEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugObjectEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugObjectEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugObjectEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugObjectEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugObjectEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugObjectEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugObjectEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugObjectEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CORDB_ADDRESS objects[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugObjectEnumVtbl; @@ -17527,36 +17534,36 @@ EXTERN_C const IID IID_ICorDebugObjectEnum; CONST_VTBL struct ICorDebugObjectEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugObjectEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugObjectEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugObjectEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugObjectEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugObjectEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugObjectEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugObjectEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugObjectEnum_Next(This,celt,objects,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,objects,pceltFetched) ) #endif /* COBJMACROS */ @@ -17573,72 +17580,72 @@ EXTERN_C const IID IID_ICorDebugObjectEnum; #define __ICorDebugBreakpointEnum_INTERFACE_DEFINED__ /* interface ICorDebugBreakpointEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugBreakpointEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB03-8A68-11d2-983C-0000F808342D") ICorDebugBreakpointEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugBreakpoint *breakpoints[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugBreakpointEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugBreakpointEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugBreakpointEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugBreakpointEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugBreakpointEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugBreakpointEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugBreakpointEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugBreakpointEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugBreakpointEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugBreakpointEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugBreakpoint *breakpoints[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugBreakpointEnumVtbl; @@ -17647,36 +17654,36 @@ EXTERN_C const IID IID_ICorDebugBreakpointEnum; CONST_VTBL struct ICorDebugBreakpointEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugBreakpointEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugBreakpointEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugBreakpointEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugBreakpointEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugBreakpointEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugBreakpointEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugBreakpointEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugBreakpointEnum_Next(This,celt,breakpoints,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,breakpoints,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,breakpoints,pceltFetched) ) #endif /* COBJMACROS */ @@ -17693,72 +17700,72 @@ EXTERN_C const IID IID_ICorDebugBreakpointEnum; #define __ICorDebugStepperEnum_INTERFACE_DEFINED__ /* interface ICorDebugStepperEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugStepperEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB04-8A68-11d2-983C-0000F808342D") ICorDebugStepperEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugStepper *steppers[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugStepperEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugStepperEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugStepperEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugStepperEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugStepperEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugStepperEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugStepperEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugStepperEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugStepperEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugStepperEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugStepper *steppers[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugStepperEnumVtbl; @@ -17767,36 +17774,36 @@ EXTERN_C const IID IID_ICorDebugStepperEnum; CONST_VTBL struct ICorDebugStepperEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugStepperEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugStepperEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugStepperEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugStepperEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugStepperEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugStepperEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugStepperEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugStepperEnum_Next(This,celt,steppers,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,steppers,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,steppers,pceltFetched) ) #endif /* COBJMACROS */ @@ -17813,72 +17820,72 @@ EXTERN_C const IID IID_ICorDebugStepperEnum; #define __ICorDebugProcessEnum_INTERFACE_DEFINED__ /* interface ICorDebugProcessEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugProcessEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB05-8A68-11d2-983C-0000F808342D") ICorDebugProcessEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugProcess *processes[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugProcessEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugProcessEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugProcessEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugProcessEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugProcessEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugProcessEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugProcessEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugProcessEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugProcessEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugProcessEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugProcess *processes[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugProcessEnumVtbl; @@ -17887,36 +17894,36 @@ EXTERN_C const IID IID_ICorDebugProcessEnum; CONST_VTBL struct ICorDebugProcessEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugProcessEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugProcessEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugProcessEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugProcessEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugProcessEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugProcessEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugProcessEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugProcessEnum_Next(This,celt,processes,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,processes,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,processes,pceltFetched) ) #endif /* COBJMACROS */ @@ -17933,72 +17940,72 @@ EXTERN_C const IID IID_ICorDebugProcessEnum; #define __ICorDebugThreadEnum_INTERFACE_DEFINED__ /* interface ICorDebugThreadEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugThreadEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB06-8A68-11d2-983C-0000F808342D") ICorDebugThreadEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugThread *threads[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugThreadEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugThreadEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugThreadEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugThreadEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugThreadEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugThreadEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugThreadEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugThreadEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugThreadEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugThreadEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugThread *threads[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugThreadEnumVtbl; @@ -18007,36 +18014,36 @@ EXTERN_C const IID IID_ICorDebugThreadEnum; CONST_VTBL struct ICorDebugThreadEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugThreadEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugThreadEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugThreadEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugThreadEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugThreadEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugThreadEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugThreadEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugThreadEnum_Next(This,celt,threads,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,threads,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,threads,pceltFetched) ) #endif /* COBJMACROS */ @@ -18053,72 +18060,72 @@ EXTERN_C const IID IID_ICorDebugThreadEnum; #define __ICorDebugFrameEnum_INTERFACE_DEFINED__ /* interface ICorDebugFrameEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugFrameEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB07-8A68-11d2-983C-0000F808342D") ICorDebugFrameEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugFrame *frames[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugFrameEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugFrameEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugFrameEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugFrameEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugFrameEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugFrameEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugFrameEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugFrameEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugFrameEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugFrameEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugFrame *frames[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugFrameEnumVtbl; @@ -18127,36 +18134,36 @@ EXTERN_C const IID IID_ICorDebugFrameEnum; CONST_VTBL struct ICorDebugFrameEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugFrameEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugFrameEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugFrameEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugFrameEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugFrameEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugFrameEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugFrameEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugFrameEnum_Next(This,celt,frames,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,frames,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,frames,pceltFetched) ) #endif /* COBJMACROS */ @@ -18173,72 +18180,72 @@ EXTERN_C const IID IID_ICorDebugFrameEnum; #define __ICorDebugChainEnum_INTERFACE_DEFINED__ /* interface ICorDebugChainEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugChainEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB08-8A68-11d2-983C-0000F808342D") ICorDebugChainEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugChain *chains[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugChainEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugChainEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugChainEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugChainEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugChainEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugChainEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugChainEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugChainEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugChainEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugChainEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugChain *chains[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugChainEnumVtbl; @@ -18247,36 +18254,36 @@ EXTERN_C const IID IID_ICorDebugChainEnum; CONST_VTBL struct ICorDebugChainEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugChainEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugChainEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugChainEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugChainEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugChainEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugChainEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugChainEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugChainEnum_Next(This,celt,chains,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,chains,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,chains,pceltFetched) ) #endif /* COBJMACROS */ @@ -18293,72 +18300,72 @@ EXTERN_C const IID IID_ICorDebugChainEnum; #define __ICorDebugModuleEnum_INTERFACE_DEFINED__ /* interface ICorDebugModuleEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugModuleEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB09-8A68-11d2-983C-0000F808342D") ICorDebugModuleEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugModule *modules[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugModuleEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugModuleEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugModuleEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugModuleEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugModuleEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugModuleEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugModuleEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugModuleEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugModuleEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugModuleEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugModule *modules[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugModuleEnumVtbl; @@ -18367,36 +18374,36 @@ EXTERN_C const IID IID_ICorDebugModuleEnum; CONST_VTBL struct ICorDebugModuleEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugModuleEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugModuleEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugModuleEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugModuleEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugModuleEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugModuleEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugModuleEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugModuleEnum_Next(This,celt,modules,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,modules,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,modules,pceltFetched) ) #endif /* COBJMACROS */ @@ -18413,72 +18420,72 @@ EXTERN_C const IID IID_ICorDebugModuleEnum; #define __ICorDebugValueEnum_INTERFACE_DEFINED__ /* interface ICorDebugValueEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugValueEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC7BCB0A-8A68-11d2-983C-0000F808342D") ICorDebugValueEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugValue *values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugValueEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugValueEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugValueEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugValueEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugValueEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugValueEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugValueEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugValueEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugValueEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugValueEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugValue *values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugValueEnumVtbl; @@ -18487,36 +18494,36 @@ EXTERN_C const IID IID_ICorDebugValueEnum; CONST_VTBL struct ICorDebugValueEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugValueEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugValueEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugValueEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugValueEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugValueEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugValueEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugValueEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugValueEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -18533,72 +18540,72 @@ EXTERN_C const IID IID_ICorDebugValueEnum; #define __ICorDebugVariableHomeEnum_INTERFACE_DEFINED__ /* interface ICorDebugVariableHomeEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugVariableHomeEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("e76b7a57-4f7a-4309-85a7-5d918c3deaf7") ICorDebugVariableHomeEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugVariableHome *homes[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugVariableHomeEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugVariableHomeEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugVariableHomeEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugVariableHomeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugVariableHomeEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugVariableHomeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugVariableHomeEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugVariableHomeEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugVariableHomeEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugVariableHomeEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugVariableHome *homes[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugVariableHomeEnumVtbl; @@ -18607,36 +18614,36 @@ EXTERN_C const IID IID_ICorDebugVariableHomeEnum; CONST_VTBL struct ICorDebugVariableHomeEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugVariableHomeEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugVariableHomeEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugVariableHomeEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugVariableHomeEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugVariableHomeEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugVariableHomeEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugVariableHomeEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugVariableHomeEnum_Next(This,celt,homes,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,homes,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,homes,pceltFetched) ) #endif /* COBJMACROS */ @@ -18653,72 +18660,72 @@ EXTERN_C const IID IID_ICorDebugVariableHomeEnum; #define __ICorDebugCodeEnum_INTERFACE_DEFINED__ /* interface ICorDebugCodeEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugCodeEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("55E96461-9645-45e4-A2FF-0367877ABCDE") ICorDebugCodeEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugCode *values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugCodeEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugCodeEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugCodeEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugCodeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugCodeEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugCodeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugCodeEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugCodeEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugCodeEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugCodeEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugCode *values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugCodeEnumVtbl; @@ -18727,36 +18734,36 @@ EXTERN_C const IID IID_ICorDebugCodeEnum; CONST_VTBL struct ICorDebugCodeEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugCodeEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugCodeEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugCodeEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugCodeEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugCodeEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugCodeEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugCodeEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugCodeEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -18773,72 +18780,72 @@ EXTERN_C const IID IID_ICorDebugCodeEnum; #define __ICorDebugTypeEnum_INTERFACE_DEFINED__ /* interface ICorDebugTypeEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugTypeEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("10F27499-9DF2-43ce-8333-A321D7C99CB4") ICorDebugTypeEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugType *values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugTypeEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugTypeEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugTypeEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugTypeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugTypeEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugTypeEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugTypeEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugTypeEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugTypeEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugTypeEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugType *values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugTypeEnumVtbl; @@ -18847,36 +18854,36 @@ EXTERN_C const IID IID_ICorDebugTypeEnum; CONST_VTBL struct ICorDebugTypeEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugTypeEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugTypeEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugTypeEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugTypeEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugTypeEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugTypeEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugTypeEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugTypeEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -18893,101 +18900,101 @@ EXTERN_C const IID IID_ICorDebugTypeEnum; #define __ICorDebugType_INTERFACE_DEFINED__ /* interface ICorDebugType */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugType; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("D613F0BB-ACE1-4c19-BD72-E4C08D5DA7F5") ICorDebugType : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetType( + virtual HRESULT STDMETHODCALLTYPE GetType( /* [out] */ CorElementType *ty) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetClass( + + virtual HRESULT STDMETHODCALLTYPE GetClass( /* [out] */ ICorDebugClass **ppClass) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumerateTypeParameters( + + virtual HRESULT STDMETHODCALLTYPE EnumerateTypeParameters( /* [out] */ ICorDebugTypeEnum **ppTyParEnum) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFirstTypeParameter( + + virtual HRESULT STDMETHODCALLTYPE GetFirstTypeParameter( /* [out] */ ICorDebugType **value) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetBase( + + virtual HRESULT STDMETHODCALLTYPE GetBase( /* [out] */ ICorDebugType **pBase) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStaticFieldValue( + + virtual HRESULT STDMETHODCALLTYPE GetStaticFieldValue( /* [in] */ mdFieldDef fieldDef, /* [in] */ ICorDebugFrame *pFrame, /* [out] */ ICorDebugValue **ppValue) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRank( + + virtual HRESULT STDMETHODCALLTYPE GetRank( /* [out] */ ULONG32 *pnRank) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugTypeVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugType * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugType * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugType * This); - + DECLSPEC_XFGVIRT(ICorDebugType, GetType) - HRESULT ( STDMETHODCALLTYPE *GetType )( + HRESULT ( STDMETHODCALLTYPE *GetType )( ICorDebugType * This, /* [out] */ CorElementType *ty); - + DECLSPEC_XFGVIRT(ICorDebugType, GetClass) - HRESULT ( STDMETHODCALLTYPE *GetClass )( + HRESULT ( STDMETHODCALLTYPE *GetClass )( ICorDebugType * This, /* [out] */ ICorDebugClass **ppClass); - + DECLSPEC_XFGVIRT(ICorDebugType, EnumerateTypeParameters) - HRESULT ( STDMETHODCALLTYPE *EnumerateTypeParameters )( + HRESULT ( STDMETHODCALLTYPE *EnumerateTypeParameters )( ICorDebugType * This, /* [out] */ ICorDebugTypeEnum **ppTyParEnum); - + DECLSPEC_XFGVIRT(ICorDebugType, GetFirstTypeParameter) - HRESULT ( STDMETHODCALLTYPE *GetFirstTypeParameter )( + HRESULT ( STDMETHODCALLTYPE *GetFirstTypeParameter )( ICorDebugType * This, /* [out] */ ICorDebugType **value); - + DECLSPEC_XFGVIRT(ICorDebugType, GetBase) - HRESULT ( STDMETHODCALLTYPE *GetBase )( + HRESULT ( STDMETHODCALLTYPE *GetBase )( ICorDebugType * This, /* [out] */ ICorDebugType **pBase); - + DECLSPEC_XFGVIRT(ICorDebugType, GetStaticFieldValue) - HRESULT ( STDMETHODCALLTYPE *GetStaticFieldValue )( + HRESULT ( STDMETHODCALLTYPE *GetStaticFieldValue )( ICorDebugType * This, /* [in] */ mdFieldDef fieldDef, /* [in] */ ICorDebugFrame *pFrame, /* [out] */ ICorDebugValue **ppValue); - + DECLSPEC_XFGVIRT(ICorDebugType, GetRank) - HRESULT ( STDMETHODCALLTYPE *GetRank )( + HRESULT ( STDMETHODCALLTYPE *GetRank )( ICorDebugType * This, /* [out] */ ULONG32 *pnRank); - + END_INTERFACE } ICorDebugTypeVtbl; @@ -18996,41 +19003,41 @@ EXTERN_C const IID IID_ICorDebugType; CONST_VTBL struct ICorDebugTypeVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugType_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugType_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugType_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugType_GetType(This,ty) \ - ( (This)->lpVtbl -> GetType(This,ty) ) + ( (This)->lpVtbl -> GetType(This,ty) ) #define ICorDebugType_GetClass(This,ppClass) \ - ( (This)->lpVtbl -> GetClass(This,ppClass) ) + ( (This)->lpVtbl -> GetClass(This,ppClass) ) #define ICorDebugType_EnumerateTypeParameters(This,ppTyParEnum) \ - ( (This)->lpVtbl -> EnumerateTypeParameters(This,ppTyParEnum) ) + ( (This)->lpVtbl -> EnumerateTypeParameters(This,ppTyParEnum) ) #define ICorDebugType_GetFirstTypeParameter(This,value) \ - ( (This)->lpVtbl -> GetFirstTypeParameter(This,value) ) + ( (This)->lpVtbl -> GetFirstTypeParameter(This,value) ) #define ICorDebugType_GetBase(This,pBase) \ - ( (This)->lpVtbl -> GetBase(This,pBase) ) + ( (This)->lpVtbl -> GetBase(This,pBase) ) #define ICorDebugType_GetStaticFieldValue(This,fieldDef,pFrame,ppValue) \ - ( (This)->lpVtbl -> GetStaticFieldValue(This,fieldDef,pFrame,ppValue) ) + ( (This)->lpVtbl -> GetStaticFieldValue(This,fieldDef,pFrame,ppValue) ) #define ICorDebugType_GetRank(This,pnRank) \ - ( (This)->lpVtbl -> GetRank(This,pnRank) ) + ( (This)->lpVtbl -> GetRank(This,pnRank) ) #endif /* COBJMACROS */ @@ -19047,49 +19054,49 @@ EXTERN_C const IID IID_ICorDebugType; #define __ICorDebugType2_INTERFACE_DEFINED__ /* interface ICorDebugType2 */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugType2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("e6e91d79-693d-48bc-b417-8284b4f10fb5") ICorDebugType2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetTypeID( + virtual HRESULT STDMETHODCALLTYPE GetTypeID( /* [out] */ COR_TYPEID *id) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugType2Vtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugType2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugType2 * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugType2 * This); - + DECLSPEC_XFGVIRT(ICorDebugType2, GetTypeID) - HRESULT ( STDMETHODCALLTYPE *GetTypeID )( + HRESULT ( STDMETHODCALLTYPE *GetTypeID )( ICorDebugType2 * This, /* [out] */ COR_TYPEID *id); - + END_INTERFACE } ICorDebugType2Vtbl; @@ -19098,23 +19105,23 @@ EXTERN_C const IID IID_ICorDebugType2; CONST_VTBL struct ICorDebugType2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugType2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugType2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugType2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugType2_GetTypeID(This,id) \ - ( (This)->lpVtbl -> GetTypeID(This,id) ) + ( (This)->lpVtbl -> GetTypeID(This,id) ) #endif /* COBJMACROS */ @@ -19131,72 +19138,72 @@ EXTERN_C const IID IID_ICorDebugType2; #define __ICorDebugErrorInfoEnum_INTERFACE_DEFINED__ /* interface ICorDebugErrorInfoEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugErrorInfoEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("F0E18809-72B5-11d2-976F-00A0C9B4D50C") ICorDebugErrorInfoEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugEditAndContinueErrorInfo *errors[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugErrorInfoEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugErrorInfoEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugErrorInfoEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugErrorInfoEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugErrorInfoEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugErrorInfoEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugErrorInfoEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugErrorInfoEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugErrorInfoEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugErrorInfoEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugEditAndContinueErrorInfo *errors[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugErrorInfoEnumVtbl; @@ -19205,36 +19212,36 @@ EXTERN_C const IID IID_ICorDebugErrorInfoEnum; CONST_VTBL struct ICorDebugErrorInfoEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugErrorInfoEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugErrorInfoEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugErrorInfoEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugErrorInfoEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugErrorInfoEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugErrorInfoEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugErrorInfoEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugErrorInfoEnum_Next(This,celt,errors,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,errors,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,errors,pceltFetched) ) #endif /* COBJMACROS */ @@ -19251,72 +19258,72 @@ EXTERN_C const IID IID_ICorDebugErrorInfoEnum; #define __ICorDebugAppDomainEnum_INTERFACE_DEFINED__ /* interface ICorDebugAppDomainEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAppDomainEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("63ca1b24-4359-4883-bd57-13f815f58744") ICorDebugAppDomainEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugAppDomain *values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAppDomainEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAppDomainEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAppDomainEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAppDomainEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugAppDomainEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugAppDomainEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugAppDomainEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugAppDomainEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugAppDomainEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugAppDomainEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugAppDomain *values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugAppDomainEnumVtbl; @@ -19325,36 +19332,36 @@ EXTERN_C const IID IID_ICorDebugAppDomainEnum; CONST_VTBL struct ICorDebugAppDomainEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAppDomainEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAppDomainEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAppDomainEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAppDomainEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugAppDomainEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugAppDomainEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugAppDomainEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugAppDomainEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -19371,72 +19378,72 @@ EXTERN_C const IID IID_ICorDebugAppDomainEnum; #define __ICorDebugAssemblyEnum_INTERFACE_DEFINED__ /* interface ICorDebugAssemblyEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugAssemblyEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("4a2a1ec9-85ec-4bfb-9f15-a89fdfe0fe83") ICorDebugAssemblyEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugAssembly *values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugAssemblyEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugAssemblyEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugAssemblyEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugAssemblyEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugAssemblyEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugAssemblyEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugAssemblyEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugAssemblyEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugAssemblyEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugAssemblyEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ ICorDebugAssembly *values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugAssemblyEnumVtbl; @@ -19445,36 +19452,36 @@ EXTERN_C const IID IID_ICorDebugAssemblyEnum; CONST_VTBL struct ICorDebugAssemblyEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugAssemblyEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugAssemblyEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugAssemblyEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugAssemblyEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugAssemblyEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugAssemblyEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugAssemblyEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugAssemblyEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -19491,72 +19498,72 @@ EXTERN_C const IID IID_ICorDebugAssemblyEnum; #define __ICorDebugBlockingObjectEnum_INTERFACE_DEFINED__ /* interface ICorDebugBlockingObjectEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("976A6278-134A-4a81-81A3-8F277943F4C3") ICorDebugBlockingObjectEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CorDebugBlockingObject values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugBlockingObjectEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugBlockingObjectEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugBlockingObjectEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugBlockingObjectEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugBlockingObjectEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugBlockingObjectEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugBlockingObjectEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugBlockingObjectEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugBlockingObjectEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugBlockingObjectEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CorDebugBlockingObject values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugBlockingObjectEnumVtbl; @@ -19565,36 +19572,36 @@ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum; CONST_VTBL struct ICorDebugBlockingObjectEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugBlockingObjectEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugBlockingObjectEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugBlockingObjectEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugBlockingObjectEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugBlockingObjectEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugBlockingObjectEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugBlockingObjectEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugBlockingObjectEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -19608,7 +19615,7 @@ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum; /* interface __MIDL_itf_cordebug_0000_0131 */ -/* [local] */ +/* [local] */ #pragma warning(push) #pragma warning(disable:28718) @@ -19621,9 +19628,9 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0131_v0_0_s_ifspec; #define __ICorDebugMDA_INTERFACE_DEFINED__ /* interface ICorDebugMDA */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ -typedef +typedef enum CorDebugMDAFlags { MDA_FLAG_SLIP = 0x2 @@ -19633,87 +19640,87 @@ enum CorDebugMDAFlags EXTERN_C const IID IID_ICorDebugMDA; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("CC726F2F-1DB7-459b-B0EC-05F01D841B42") ICorDebugMDA : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetName( + virtual HRESULT STDMETHODCALLTYPE GetName( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetDescription( + + virtual HRESULT STDMETHODCALLTYPE GetDescription( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetXML( + + virtual HRESULT STDMETHODCALLTYPE GetXML( /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFlags( + + virtual HRESULT STDMETHODCALLTYPE GetFlags( /* [in] */ CorDebugMDAFlags *pFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetOSThreadId( + + virtual HRESULT STDMETHODCALLTYPE GetOSThreadId( /* [out] */ DWORD *pOsTid) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugMDAVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugMDA * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugMDA * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugMDA * This); - + DECLSPEC_XFGVIRT(ICorDebugMDA, GetName) - HRESULT ( STDMETHODCALLTYPE *GetName )( + HRESULT ( STDMETHODCALLTYPE *GetName )( ICorDebugMDA * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugMDA, GetDescription) - HRESULT ( STDMETHODCALLTYPE *GetDescription )( + HRESULT ( STDMETHODCALLTYPE *GetDescription )( ICorDebugMDA * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugMDA, GetXML) - HRESULT ( STDMETHODCALLTYPE *GetXML )( + HRESULT ( STDMETHODCALLTYPE *GetXML )( ICorDebugMDA * This, /* [in] */ ULONG32 cchName, /* [out] */ ULONG32 *pcchName, /* [length_is][size_is][out] */ WCHAR szName[ ]); - + DECLSPEC_XFGVIRT(ICorDebugMDA, GetFlags) - HRESULT ( STDMETHODCALLTYPE *GetFlags )( + HRESULT ( STDMETHODCALLTYPE *GetFlags )( ICorDebugMDA * This, /* [in] */ CorDebugMDAFlags *pFlags); - + DECLSPEC_XFGVIRT(ICorDebugMDA, GetOSThreadId) - HRESULT ( STDMETHODCALLTYPE *GetOSThreadId )( + HRESULT ( STDMETHODCALLTYPE *GetOSThreadId )( ICorDebugMDA * This, /* [out] */ DWORD *pOsTid); - + END_INTERFACE } ICorDebugMDAVtbl; @@ -19722,35 +19729,35 @@ EXTERN_C const IID IID_ICorDebugMDA; CONST_VTBL struct ICorDebugMDAVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugMDA_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugMDA_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugMDA_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugMDA_GetName(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetName(This,cchName,pcchName,szName) ) #define ICorDebugMDA_GetDescription(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetDescription(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetDescription(This,cchName,pcchName,szName) ) #define ICorDebugMDA_GetXML(This,cchName,pcchName,szName) \ - ( (This)->lpVtbl -> GetXML(This,cchName,pcchName,szName) ) + ( (This)->lpVtbl -> GetXML(This,cchName,pcchName,szName) ) #define ICorDebugMDA_GetFlags(This,pFlags) \ - ( (This)->lpVtbl -> GetFlags(This,pFlags) ) + ( (This)->lpVtbl -> GetFlags(This,pFlags) ) #define ICorDebugMDA_GetOSThreadId(This,pOsTid) \ - ( (This)->lpVtbl -> GetOSThreadId(This,pOsTid) ) + ( (This)->lpVtbl -> GetOSThreadId(This,pOsTid) ) #endif /* COBJMACROS */ @@ -19764,11 +19771,11 @@ EXTERN_C const IID IID_ICorDebugMDA; /* interface __MIDL_itf_cordebug_0000_0132 */ -/* [local] */ +/* [local] */ #pragma warning(pop) #pragma warning(push) -#pragma warning(disable:28718) +#pragma warning(disable:28718) extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0132_v0_0_c_ifspec; @@ -19778,77 +19785,77 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0132_v0_0_s_ifspec; #define __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ /* interface ICorDebugEditAndContinueErrorInfo */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("8D600D41-F4F6-4cb3-B7EC-7BD164944036") ICorDebugEditAndContinueErrorInfo : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetModule( + virtual HRESULT STDMETHODCALLTYPE GetModule( /* [out] */ ICorDebugModule **ppModule) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetToken( + + virtual HRESULT STDMETHODCALLTYPE GetToken( /* [out] */ mdToken *pToken) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetErrorCode( + + virtual HRESULT STDMETHODCALLTYPE GetErrorCode( /* [out] */ HRESULT *pHr) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetString( + + virtual HRESULT STDMETHODCALLTYPE GetString( /* [in] */ ULONG32 cchString, /* [out] */ ULONG32 *pcchString, /* [length_is][size_is][out] */ WCHAR szString[ ]) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugEditAndContinueErrorInfoVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugEditAndContinueErrorInfo * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugEditAndContinueErrorInfo * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugEditAndContinueErrorInfo * This); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueErrorInfo, GetModule) - HRESULT ( STDMETHODCALLTYPE *GetModule )( + HRESULT ( STDMETHODCALLTYPE *GetModule )( ICorDebugEditAndContinueErrorInfo * This, /* [out] */ ICorDebugModule **ppModule); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueErrorInfo, GetToken) - HRESULT ( STDMETHODCALLTYPE *GetToken )( + HRESULT ( STDMETHODCALLTYPE *GetToken )( ICorDebugEditAndContinueErrorInfo * This, /* [out] */ mdToken *pToken); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueErrorInfo, GetErrorCode) - HRESULT ( STDMETHODCALLTYPE *GetErrorCode )( + HRESULT ( STDMETHODCALLTYPE *GetErrorCode )( ICorDebugEditAndContinueErrorInfo * This, /* [out] */ HRESULT *pHr); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueErrorInfo, GetString) - HRESULT ( STDMETHODCALLTYPE *GetString )( + HRESULT ( STDMETHODCALLTYPE *GetString )( ICorDebugEditAndContinueErrorInfo * This, /* [in] */ ULONG32 cchString, /* [out] */ ULONG32 *pcchString, /* [length_is][size_is][out] */ WCHAR szString[ ]); - + END_INTERFACE } ICorDebugEditAndContinueErrorInfoVtbl; @@ -19857,32 +19864,32 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo; CONST_VTBL struct ICorDebugEditAndContinueErrorInfoVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugEditAndContinueErrorInfo_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugEditAndContinueErrorInfo_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugEditAndContinueErrorInfo_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugEditAndContinueErrorInfo_GetModule(This,ppModule) \ - ( (This)->lpVtbl -> GetModule(This,ppModule) ) + ( (This)->lpVtbl -> GetModule(This,ppModule) ) #define ICorDebugEditAndContinueErrorInfo_GetToken(This,pToken) \ - ( (This)->lpVtbl -> GetToken(This,pToken) ) + ( (This)->lpVtbl -> GetToken(This,pToken) ) #define ICorDebugEditAndContinueErrorInfo_GetErrorCode(This,pHr) \ - ( (This)->lpVtbl -> GetErrorCode(This,pHr) ) + ( (This)->lpVtbl -> GetErrorCode(This,pHr) ) #define ICorDebugEditAndContinueErrorInfo_GetString(This,cchString,pcchString,szString) \ - ( (This)->lpVtbl -> GetString(This,cchString,pcchString,szString) ) + ( (This)->lpVtbl -> GetString(This,cchString,pcchString,szString) ) #endif /* COBJMACROS */ @@ -19896,7 +19903,7 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo; /* interface __MIDL_itf_cordebug_0000_0133 */ -/* [local] */ +/* [local] */ #pragma warning(pop) @@ -19908,103 +19915,103 @@ extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0133_v0_0_s_ifspec; #define __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__ /* interface ICorDebugEditAndContinueSnapshot */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugEditAndContinueSnapshot; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("6DC3FA01-D7CB-11d2-8A95-0080C792E5D8") ICorDebugEditAndContinueSnapshot : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE CopyMetaData( + virtual HRESULT STDMETHODCALLTYPE CopyMetaData( /* [in] */ IStream *pIStream, /* [out] */ GUID *pMvid) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetMvid( + + virtual HRESULT STDMETHODCALLTYPE GetMvid( /* [out] */ GUID *pMvid) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRoDataRVA( + + virtual HRESULT STDMETHODCALLTYPE GetRoDataRVA( /* [out] */ ULONG32 *pRoDataRVA) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRwDataRVA( + + virtual HRESULT STDMETHODCALLTYPE GetRwDataRVA( /* [out] */ ULONG32 *pRwDataRVA) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetPEBytes( + + virtual HRESULT STDMETHODCALLTYPE SetPEBytes( /* [in] */ IStream *pIStream) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetILMap( + + virtual HRESULT STDMETHODCALLTYPE SetILMap( /* [in] */ mdToken mdFunction, /* [in] */ ULONG cMapSize, /* [size_is][in] */ COR_IL_MAP map[ ]) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetPESymbolBytes( + + virtual HRESULT STDMETHODCALLTYPE SetPESymbolBytes( /* [in] */ IStream *pIStream) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugEditAndContinueSnapshotVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugEditAndContinueSnapshot * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugEditAndContinueSnapshot * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugEditAndContinueSnapshot * This); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueSnapshot, CopyMetaData) - HRESULT ( STDMETHODCALLTYPE *CopyMetaData )( + HRESULT ( STDMETHODCALLTYPE *CopyMetaData )( ICorDebugEditAndContinueSnapshot * This, /* [in] */ IStream *pIStream, /* [out] */ GUID *pMvid); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueSnapshot, GetMvid) - HRESULT ( STDMETHODCALLTYPE *GetMvid )( + HRESULT ( STDMETHODCALLTYPE *GetMvid )( ICorDebugEditAndContinueSnapshot * This, /* [out] */ GUID *pMvid); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueSnapshot, GetRoDataRVA) - HRESULT ( STDMETHODCALLTYPE *GetRoDataRVA )( + HRESULT ( STDMETHODCALLTYPE *GetRoDataRVA )( ICorDebugEditAndContinueSnapshot * This, /* [out] */ ULONG32 *pRoDataRVA); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueSnapshot, GetRwDataRVA) - HRESULT ( STDMETHODCALLTYPE *GetRwDataRVA )( + HRESULT ( STDMETHODCALLTYPE *GetRwDataRVA )( ICorDebugEditAndContinueSnapshot * This, /* [out] */ ULONG32 *pRwDataRVA); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueSnapshot, SetPEBytes) - HRESULT ( STDMETHODCALLTYPE *SetPEBytes )( + HRESULT ( STDMETHODCALLTYPE *SetPEBytes )( ICorDebugEditAndContinueSnapshot * This, /* [in] */ IStream *pIStream); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueSnapshot, SetILMap) - HRESULT ( STDMETHODCALLTYPE *SetILMap )( + HRESULT ( STDMETHODCALLTYPE *SetILMap )( ICorDebugEditAndContinueSnapshot * This, /* [in] */ mdToken mdFunction, /* [in] */ ULONG cMapSize, /* [size_is][in] */ COR_IL_MAP map[ ]); - + DECLSPEC_XFGVIRT(ICorDebugEditAndContinueSnapshot, SetPESymbolBytes) - HRESULT ( STDMETHODCALLTYPE *SetPESymbolBytes )( + HRESULT ( STDMETHODCALLTYPE *SetPESymbolBytes )( ICorDebugEditAndContinueSnapshot * This, /* [in] */ IStream *pIStream); - + END_INTERFACE } ICorDebugEditAndContinueSnapshotVtbl; @@ -20013,41 +20020,41 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueSnapshot; CONST_VTBL struct ICorDebugEditAndContinueSnapshotVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugEditAndContinueSnapshot_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugEditAndContinueSnapshot_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugEditAndContinueSnapshot_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugEditAndContinueSnapshot_CopyMetaData(This,pIStream,pMvid) \ - ( (This)->lpVtbl -> CopyMetaData(This,pIStream,pMvid) ) + ( (This)->lpVtbl -> CopyMetaData(This,pIStream,pMvid) ) #define ICorDebugEditAndContinueSnapshot_GetMvid(This,pMvid) \ - ( (This)->lpVtbl -> GetMvid(This,pMvid) ) + ( (This)->lpVtbl -> GetMvid(This,pMvid) ) #define ICorDebugEditAndContinueSnapshot_GetRoDataRVA(This,pRoDataRVA) \ - ( (This)->lpVtbl -> GetRoDataRVA(This,pRoDataRVA) ) + ( (This)->lpVtbl -> GetRoDataRVA(This,pRoDataRVA) ) #define ICorDebugEditAndContinueSnapshot_GetRwDataRVA(This,pRwDataRVA) \ - ( (This)->lpVtbl -> GetRwDataRVA(This,pRwDataRVA) ) + ( (This)->lpVtbl -> GetRwDataRVA(This,pRwDataRVA) ) #define ICorDebugEditAndContinueSnapshot_SetPEBytes(This,pIStream) \ - ( (This)->lpVtbl -> SetPEBytes(This,pIStream) ) + ( (This)->lpVtbl -> SetPEBytes(This,pIStream) ) #define ICorDebugEditAndContinueSnapshot_SetILMap(This,mdFunction,cMapSize,map) \ - ( (This)->lpVtbl -> SetILMap(This,mdFunction,cMapSize,map) ) + ( (This)->lpVtbl -> SetILMap(This,mdFunction,cMapSize,map) ) #define ICorDebugEditAndContinueSnapshot_SetPESymbolBytes(This,pIStream) \ - ( (This)->lpVtbl -> SetPESymbolBytes(This,pIStream) ) + ( (This)->lpVtbl -> SetPESymbolBytes(This,pIStream) ) #endif /* COBJMACROS */ @@ -20064,72 +20071,72 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueSnapshot; #define __ICorDebugExceptionObjectCallStackEnum_INTERFACE_DEFINED__ /* interface ICorDebugExceptionObjectCallStackEnum */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugExceptionObjectCallStackEnum; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("ED775530-4DC4-41F7-86D0-9E2DEF7DFC66") ICorDebugExceptionObjectCallStackEnum : public ICorDebugEnum { public: - virtual HRESULT STDMETHODCALLTYPE Next( + virtual HRESULT STDMETHODCALLTYPE Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CorDebugExceptionObjectStackFrame values[ ], /* [out] */ ULONG *pceltFetched) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugExceptionObjectCallStackEnumVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugExceptionObjectCallStackEnum * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugExceptionObjectCallStackEnum * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugExceptionObjectCallStackEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Skip) - HRESULT ( STDMETHODCALLTYPE *Skip )( + HRESULT ( STDMETHODCALLTYPE *Skip )( ICorDebugExceptionObjectCallStackEnum * This, /* [in] */ ULONG celt); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Reset) - HRESULT ( STDMETHODCALLTYPE *Reset )( + HRESULT ( STDMETHODCALLTYPE *Reset )( ICorDebugExceptionObjectCallStackEnum * This); - + DECLSPEC_XFGVIRT(ICorDebugEnum, Clone) - HRESULT ( STDMETHODCALLTYPE *Clone )( + HRESULT ( STDMETHODCALLTYPE *Clone )( ICorDebugExceptionObjectCallStackEnum * This, /* [out] */ ICorDebugEnum **ppEnum); - + DECLSPEC_XFGVIRT(ICorDebugEnum, GetCount) - HRESULT ( STDMETHODCALLTYPE *GetCount )( + HRESULT ( STDMETHODCALLTYPE *GetCount )( ICorDebugExceptionObjectCallStackEnum * This, /* [out] */ ULONG *pcelt); - + DECLSPEC_XFGVIRT(ICorDebugExceptionObjectCallStackEnum, Next) - HRESULT ( STDMETHODCALLTYPE *Next )( + HRESULT ( STDMETHODCALLTYPE *Next )( ICorDebugExceptionObjectCallStackEnum * This, /* [in] */ ULONG celt, /* [length_is][size_is][out] */ CorDebugExceptionObjectStackFrame values[ ], /* [out] */ ULONG *pceltFetched); - + END_INTERFACE } ICorDebugExceptionObjectCallStackEnumVtbl; @@ -20138,36 +20145,36 @@ EXTERN_C const IID IID_ICorDebugExceptionObjectCallStackEnum; CONST_VTBL struct ICorDebugExceptionObjectCallStackEnumVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugExceptionObjectCallStackEnum_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugExceptionObjectCallStackEnum_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugExceptionObjectCallStackEnum_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugExceptionObjectCallStackEnum_Skip(This,celt) \ - ( (This)->lpVtbl -> Skip(This,celt) ) + ( (This)->lpVtbl -> Skip(This,celt) ) #define ICorDebugExceptionObjectCallStackEnum_Reset(This) \ - ( (This)->lpVtbl -> Reset(This) ) + ( (This)->lpVtbl -> Reset(This) ) #define ICorDebugExceptionObjectCallStackEnum_Clone(This,ppEnum) \ - ( (This)->lpVtbl -> Clone(This,ppEnum) ) + ( (This)->lpVtbl -> Clone(This,ppEnum) ) #define ICorDebugExceptionObjectCallStackEnum_GetCount(This,pcelt) \ - ( (This)->lpVtbl -> GetCount(This,pcelt) ) + ( (This)->lpVtbl -> GetCount(This,pcelt) ) #define ICorDebugExceptionObjectCallStackEnum_Next(This,celt,values,pceltFetched) \ - ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) + ( (This)->lpVtbl -> Next(This,celt,values,pceltFetched) ) #endif /* COBJMACROS */ @@ -20184,49 +20191,49 @@ EXTERN_C const IID IID_ICorDebugExceptionObjectCallStackEnum; #define __ICorDebugExceptionObjectValue_INTERFACE_DEFINED__ /* interface ICorDebugExceptionObjectValue */ -/* [unique][uuid][local][object] */ +/* [unique][uuid][local][object] */ EXTERN_C const IID IID_ICorDebugExceptionObjectValue; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("AE4CA65D-59DD-42A2-83A5-57E8A08D8719") ICorDebugExceptionObjectValue : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE EnumerateExceptionCallStack( + virtual HRESULT STDMETHODCALLTYPE EnumerateExceptionCallStack( /* [out] */ ICorDebugExceptionObjectCallStackEnum **ppCallStackEnum) = 0; - + }; - - + + #else /* C style interface */ typedef struct ICorDebugExceptionObjectValueVtbl { BEGIN_INTERFACE - + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( ICorDebugExceptionObjectValue * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ + /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); - + DECLSPEC_XFGVIRT(IUnknown, AddRef) - ULONG ( STDMETHODCALLTYPE *AddRef )( + ULONG ( STDMETHODCALLTYPE *AddRef )( ICorDebugExceptionObjectValue * This); - + DECLSPEC_XFGVIRT(IUnknown, Release) - ULONG ( STDMETHODCALLTYPE *Release )( + ULONG ( STDMETHODCALLTYPE *Release )( ICorDebugExceptionObjectValue * This); - + DECLSPEC_XFGVIRT(ICorDebugExceptionObjectValue, EnumerateExceptionCallStack) - HRESULT ( STDMETHODCALLTYPE *EnumerateExceptionCallStack )( + HRESULT ( STDMETHODCALLTYPE *EnumerateExceptionCallStack )( ICorDebugExceptionObjectValue * This, /* [out] */ ICorDebugExceptionObjectCallStackEnum **ppCallStackEnum); - + END_INTERFACE } ICorDebugExceptionObjectValueVtbl; @@ -20235,23 +20242,23 @@ EXTERN_C const IID IID_ICorDebugExceptionObjectValue; CONST_VTBL struct ICorDebugExceptionObjectValueVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define ICorDebugExceptionObjectValue_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define ICorDebugExceptionObjectValue_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define ICorDebugExceptionObjectValue_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define ICorDebugExceptionObjectValue_EnumerateExceptionCallStack(This,ppCallStackEnum) \ - ( (This)->lpVtbl -> EnumerateExceptionCallStack(This,ppCallStackEnum) ) + ( (This)->lpVtbl -> EnumerateExceptionCallStack(This,ppCallStackEnum) ) #endif /* COBJMACROS */ @@ -20264,12 +20271,96 @@ EXTERN_C const IID IID_ICorDebugExceptionObjectValue; #endif /* __ICorDebugExceptionObjectValue_INTERFACE_DEFINED__ */ +#ifndef __ICorDebugExceptionObjectValue2_INTERFACE_DEFINED__ +#define __ICorDebugExceptionObjectValue2_INTERFACE_DEFINED__ + +/* interface ICorDebugExceptionObjectValue2 */ +/* [unique][uuid][local][object] */ + + +EXTERN_C const IID IID_ICorDebugExceptionObjectValue2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("e3b2f332-cc46-4f1e-ab4e-5400e332195e") + ICorDebugExceptionObjectValue2 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ForceCatchHandlerFoundEvents( + /* [in] */ BOOL enableEvents) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ICorDebugExceptionObjectValue2Vtbl + { + BEGIN_INTERFACE + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ICorDebugExceptionObjectValue2 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( + ICorDebugExceptionObjectValue2 * This); + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( + ICorDebugExceptionObjectValue2 * This); + + DECLSPEC_XFGVIRT(ICorDebugExceptionObjectValue2, ForceCatchHandlerFoundEvents) + HRESULT ( STDMETHODCALLTYPE *ForceCatchHandlerFoundEvents )( + ICorDebugExceptionObjectValue2 * This, + /* [in] */ BOOL enableEvents); + + END_INTERFACE + } ICorDebugExceptionObjectValue2Vtbl; + + interface ICorDebugExceptionObjectValue2 + { + CONST_VTBL struct ICorDebugExceptionObjectValue2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ICorDebugExceptionObjectValue2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ICorDebugExceptionObjectValue2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ICorDebugExceptionObjectValue2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ICorDebugExceptionObjectValue2_ForceCatchHandlerFoundEvents(This,enableEvents) \ + ( (This)->lpVtbl -> ForceCatchHandlerFoundEvents(This,enableEvents) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ICorDebugExceptionObjectValue2_INTERFACE_DEFINED__ */ + + #ifndef __CORDBLib_LIBRARY_DEFINED__ #define __CORDBLib_LIBRARY_DEFINED__ /* library CORDBLib */ -/* [helpstring][version][uuid] */ +/* [helpstring][version][uuid] */ diff --git a/src/coreclr/pal/src/arch/arm/context2.S b/src/coreclr/pal/src/arch/arm/context2.S index e292ca26fe2adc..bb41b0ff589b40 100644 --- a/src/coreclr/pal/src/arch/arm/context2.S +++ b/src/coreclr/pal/src/arch/arm/context2.S @@ -160,25 +160,28 @@ LOCAL_LABEL(Restore_CONTEXT_FLOATING_POINT): ldr R2, [r0, #(CONTEXT_Cpsr)] msr APSR, r2 - // Ideally, we would like to use `ldmia r0, {r0-r12, sp, lr, pc}` here, - // but clang 3.6 and later, as per ARM recommendation, disallows using - // Sp in the register list, and Pc and Lr simultaneously. - // So we are going to use the IPC register r12 to copy Sp, Lr and Pc - // which should be ok -- TODO: Is this really ok? + ldr r1, [r0, #(CONTEXT_Sp)] + ldr r2, [r0, #(CONTEXT_Pc)] + str r2, [r1, #-4] + ldr r2, [r0, #(CONTEXT_R12)] + str r2, [r1, #-8] add r12, r0, CONTEXT_R0 ldm r12, {r0-r11} - ldr sp, [r12, #(CONTEXT_Sp - (CONTEXT_R0))] ldr lr, [r12, #(CONTEXT_Lr - (CONTEXT_R0))] - ldr pc, [r12, #(CONTEXT_Pc - (CONTEXT_R0))] + ldr r12, [r12, #(CONTEXT_Sp - (CONTEXT_R0))] + sub r12, r12, #8 + mov sp, r12 + pop {r12, pc} LOCAL_LABEL(No_Restore_CONTEXT_INTEGER): ldr r2, [r0, #(CONTEXT_Cpsr)] msr APSR, r2 - ldr sp, [r0, #(CONTEXT_Sp)] ldr lr, [r0, #(CONTEXT_Lr)] - ldr pc, [r0, #(CONTEXT_Pc)] + ldr r2, [r0, #(CONTEXT_Pc)] + ldr sp, [r0, #(CONTEXT_Sp)] + bx r2 LOCAL_LABEL(No_Restore_CONTEXT_CONTROL): ldr r2, [r0, #(CONTEXT_ContextFlags)] diff --git a/src/coreclr/pal/src/arch/i386/context2.S b/src/coreclr/pal/src/arch/i386/context2.S index cf5b464c27d0ce..35768ea6232af2 100644 --- a/src/coreclr/pal/src/arch/i386/context2.S +++ b/src/coreclr/pal/src/arch/i386/context2.S @@ -115,11 +115,12 @@ LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT): movdqu xmm7, [eax + CONTEXT_Xmm7] LOCAL_LABEL(Done_Restore_CONTEXT_EXTENDED_REGISTERS): - // Restore Stack - mov esp, [eax + CONTEXT_Esp] - // Create a minimal frame - push DWORD PTR [eax + CONTEXT_Eip] + mov ebx, [eax + CONTEXT_Esp] + mov ecx, [eax + CONTEXT_Eip] + mov edx, [eax + CONTEXT_Eax] + mov [ebx - 4], ecx + mov [ebx - 8], edx // Restore register(s) mov ebp, [eax + CONTEXT_Ebp] @@ -128,7 +129,13 @@ LOCAL_LABEL(Done_Restore_CONTEXT_EXTENDED_REGISTERS): mov edx, [eax + CONTEXT_Edx] mov ecx, [eax + CONTEXT_Ecx] mov ebx, [eax + CONTEXT_Ebx] - mov eax, [eax + CONTEXT_Eax] + + // Restore Stack + mov eax, [eax + CONTEXT_Esp] + sub eax, 8 + mov esp, eax + + pop eax // Resume ret diff --git a/src/coreclr/runtime-prereqs.proj b/src/coreclr/runtime-prereqs.proj index 6bbe50f7d550a9..91e3f46d59d5fe 100644 --- a/src/coreclr/runtime-prereqs.proj +++ b/src/coreclr/runtime-prereqs.proj @@ -15,6 +15,7 @@ + diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index 773b0290d523f9..814d4dba29f707 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -50,6 +50,8 @@ <_CoreClrBuildArg Condition="'$(HostCrossOS)' != ''" Include="-hostos $(HostCrossOS)" /> <_CoreClrBuildArg Include="-outputrid $(OutputRID)" /> <_CoreClrBuildArg Condition="'$(BuildSubdirectory)' != ''" Include="-subdir $(BuildSubdirectory)" /> + <_CoreClrBuildArg Include="-cmakeargs "-DCLR_DOTNET_HOST_PATH=$(DOTNET_HOST_PATH)"" /> + <_CoreClrBuildArg Include="-cmakeargs "-DCDAC_BUILD_TOOL_BINARY_PATH=$(RuntimeBinDir)cdac-build-tool\cdac-build-tool.dll"" /> diff --git a/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs b/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs index 3e282dfc76dcf9..cfb4bb12902958 100644 --- a/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs +++ b/src/coreclr/tools/Common/Compiler/Dataflow/MethodProxy.cs @@ -66,6 +66,8 @@ internal partial ImmutableArray GetGenericParameters() return builder.ToImmutableArray(); } + internal partial bool IsConstructor() => Method.IsConstructor; + internal partial bool IsStatic() => Method.Signature.IsStatic; internal partial bool HasImplicitThis() => !Method.Signature.IsStatic; diff --git a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs index a1725f3db9d928..f6c34091bc0fe9 100644 --- a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs +++ b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs @@ -97,6 +97,10 @@ public static string GetHardwareIntrinsicId(TargetArchitecture architecture, Typ if (potentialType.Namespace != "System.Runtime.Intrinsics.Arm") return ""; } + else if (architecture == TargetArchitecture.LoongArch64) + { + return ""; + } else if (architecture == TargetArchitecture.RiscV64) { return ""; diff --git a/src/coreclr/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs b/src/coreclr/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs index bb0a5bc71a626c..1f3722ab019bcc 100644 --- a/src/coreclr/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs +++ b/src/coreclr/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs @@ -58,6 +58,11 @@ public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defTyp // 16-byte alignment for __m256. alignment = new LayoutInt(16); } + else if (defType.Context.Target.Architecture == TargetArchitecture.LoongArch64) + { + // TODO-LoongArch64: Update alignment to proper value when implement LoongArch64 intrinsic. + alignment = new LayoutInt(16); + } else if (defType.Context.Target.Architecture == TargetArchitecture.RiscV64) { // TODO-RISCV64: Update alignment to proper value when we implement RISC-V intrinsic. @@ -86,6 +91,11 @@ public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defTyp // 16-byte alignment for __m256. alignment = new LayoutInt(16); } + else if (defType.Context.Target.Architecture == TargetArchitecture.LoongArch64) + { + // TODO-LoongArch64: Update alignment to proper value when implement LoongArch64 intrinsic. + alignment = new LayoutInt(16); + } else if (defType.Context.Target.Architecture == TargetArchitecture.RiscV64) { // TODO-RISCV64: Update alignment to proper value when we implement RISC-V intrinsic. diff --git a/src/coreclr/tools/Common/InstructionSetHelpers.cs b/src/coreclr/tools/Common/InstructionSetHelpers.cs index 718053f13d0c33..8a7303f15f3711 100644 --- a/src/coreclr/tools/Common/InstructionSetHelpers.cs +++ b/src/coreclr/tools/Common/InstructionSetHelpers.cs @@ -122,7 +122,7 @@ public static InstructionSetSupport ConfigureInstructionSetSupport(string instru string[] instructionSetParamsInput = instructionSet.Split(','); for (int i = 0; i < instructionSetParamsInput.Length; i++) { - instructionSet = instructionSetParamsInput[i]; + instructionSet = instructionSetParamsInput[i].Trim(); if (string.IsNullOrEmpty(instructionSet)) throw new CommandLineException(string.Format(mustNotBeMessage, "")); diff --git a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs index 6fc5d9542e1609..8420c9a4803b28 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs @@ -16,7 +16,7 @@ internal struct ReadyToRunHeaderConstants public const uint Signature = 0x00525452; // 'RTR' public const ushort CurrentMajorVersion = 9; - public const ushort CurrentMinorVersion = 2; + public const ushort CurrentMinorVersion = 3; } #if READYTORUN #pragma warning disable 0169 diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs index 0ca8b74c85229b..af86b107e5b31e 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs @@ -233,6 +233,7 @@ public enum ReadyToRunHelper WriteBarrier = 0x30, CheckedWriteBarrier = 0x31, ByRefWriteBarrier = 0x32, + BulkWriteBarrier = 0x33, // Array helpers Stelem_Ref = 0x38, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs index 5346806c1aff60..14bf90a9aaaed4 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs @@ -138,7 +138,7 @@ which is the right helper to use to allocate an object of a given type. */ CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP, // Do the store, and ensure that the target was not in the heap. CORINFO_HELP_ASSIGN_BYREF, - CORINFO_HELP_ASSIGN_STRUCT, + CORINFO_HELP_BULK_WRITEBARRIER, /* Accessing fields */ diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 7719b39aa7e852..31a5dd68927bd1 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -415,9 +415,10 @@ private CompilationResult CompileMethodInternal(IMethodNode methodCodeNodeNeedin if (codeSize < _code.Length) { if (_compilation.TypeSystemContext.Target.Architecture != TargetArchitecture.ARM64 + && _compilation.TypeSystemContext.Target.Architecture != TargetArchitecture.LoongArch64 && _compilation.TypeSystemContext.Target.Architecture != TargetArchitecture.RiscV64) { - // For xarch/arm32/RiscV64, the generated code is sometimes smaller than the memory allocated. + // For xarch/arm32/LoongArch64/RiscV64, the generated code is sometimes smaller than the memory allocated. // In that case, trim the codeBlock to the actual value. // // For arm64, the allocation request of `hotCodeSize` also includes the roData size @@ -4260,7 +4261,7 @@ public static void ComputeJitPgoInstrumentationSchema(Func objec } private HRESULT getPgoInstrumentationResults(CORINFO_METHOD_STRUCT_* ftnHnd, ref PgoInstrumentationSchema* pSchema, ref uint countSchemaItems, byte** pInstrumentationData, - ref PgoSource pPgoSource) + ref PgoSource pPgoSource, ref bool pDynamicPgo) { MethodDesc methodDesc = HandleToObject(ftnHnd); @@ -4307,6 +4308,7 @@ private HRESULT getPgoInstrumentationResults(CORINFO_METHOD_STRUCT_* ftnHnd, ref countSchemaItems = pgoResults.countSchemaItems; *pInstrumentationData = pgoResults.pInstrumentationData; pPgoSource = PgoSource.Static; + pDynamicPgo = false; return pgoResults.hr; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 481c22864356c1..e4ef2264da2556 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -2489,12 +2489,12 @@ private static void _reportFatalError(IntPtr thisHandle, IntPtr* ppException, Co } [UnmanagedCallersOnly] - private static HRESULT _getPgoInstrumentationResults(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftnHnd, PgoInstrumentationSchema** pSchema, uint* pCountSchemaItems, byte** pInstrumentationData, PgoSource* pgoSource) + private static HRESULT _getPgoInstrumentationResults(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftnHnd, PgoInstrumentationSchema** pSchema, uint* pCountSchemaItems, byte** pInstrumentationData, PgoSource* pPgoSource, bool* pDynamicPgo) { var _this = GetThis(thisHandle); try { - return _this.getPgoInstrumentationResults(ftnHnd, ref *pSchema, ref *pCountSchemaItems, pInstrumentationData, ref *pgoSource); + return _this.getPgoInstrumentationResults(ftnHnd, ref *pSchema, ref *pCountSchemaItems, pInstrumentationData, ref *pPgoSource, ref *pDynamicPgo); } catch (Exception ex) { @@ -2764,7 +2764,7 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[165] = (delegate* unmanaged)&_logMsg; callbacks[166] = (delegate* unmanaged)&_doAssert; callbacks[167] = (delegate* unmanaged)&_reportFatalError; - callbacks[168] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[168] = (delegate* unmanaged)&_getPgoInstrumentationResults; callbacks[169] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; callbacks[170] = (delegate* unmanaged)&_recordCallSite; callbacks[171] = (delegate* unmanaged)&_recordRelocation; diff --git a/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs b/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs index b0c193d0950071..856b9905a1fb43 100644 --- a/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs +++ b/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs @@ -29,12 +29,6 @@ public static uint GetLoongArch64PassStructInRegisterFlags(TypeDesc typeDesc) return (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; } - //// The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers - if (typeDesc.IsIntrinsic) - { - throw new NotImplementedException("For LoongArch64, SIMD would be implemented later"); - } - MetadataType mdType = typeDesc as MetadataType; Debug.Assert(mdType != null); diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 86674ab2b59244..2b78b23547432c 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -331,7 +331,7 @@ FUNCTIONS bool logMsg(unsigned level, const char* fmt, va_list args) int doAssert(const char* szFile, int iLine, const char* szExpr) void reportFatalError(CorJitResult result) - JITINTERFACE_HRESULT getPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t**pInstrumentationData, ICorJitInfo::PgoSource* pgoSource) + JITINTERFACE_HRESULT getPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t**pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, bool* pDynamicPgo) JITINTERFACE_HRESULT allocPgoInstrumentationBySchema(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, uint32_t countSchemaItems, uint8_t** pInstrumentationData) void recordCallSite(uint32_t instrOffset, CORINFO_SIG_INFO* callSig, CORINFO_METHOD_HANDLE methodHandle) void recordRelocation(void* location, void* locationRW, void* target, uint16_t fRelocType, int32_t addlDelta) diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs index a52a68f0028a48..33a86023ced277 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/CustomAttributeTypeNameParser.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Collections.Generic; -using System.Text; +using System.Reflection.Metadata; using Internal.TypeSystem; @@ -30,6 +29,8 @@ namespace System.Reflection { internal partial struct TypeNameParser { + private static readonly TypeNameParseOptions s_typeNameParseOptions = new() { MaxNodes = int.MaxValue }; + private ModuleDesc _module; private bool _throwIfNotFound; private Func _canonResolver; @@ -37,12 +38,17 @@ internal partial struct TypeNameParser public static TypeDesc ResolveType(ModuleDesc module, string name, bool throwIfNotFound, Func canonResolver) { - return new TypeNameParser(name.AsSpan()) + if (!TypeName.TryParse(name.AsSpan(), out TypeName parsed, s_typeNameParseOptions)) + { + ThrowHelper.ThrowTypeLoadException(name, module); + } + + return new TypeNameParser() { _module = module, _throwIfNotFound = throwIfNotFound, _canonResolver = canonResolver - }.Parse()?.Value; + }.Resolve(parsed)?.Value; } private sealed class Type @@ -64,12 +70,10 @@ public Type MakeGenericType(Type[] typeArguments) } } - private static bool CheckTopLevelAssemblyQualifiedName() => true; - - private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, string assemblyNameIfAny) + private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, TypeName parsedName) { - ModuleDesc module = (assemblyNameIfAny == null) ? _module : - _module.Context.ResolveAssembly(new AssemblyName(assemblyNameIfAny), throwIfNotFound: _throwIfNotFound); + ModuleDesc module = (parsedName.AssemblyName == null) ? _module : + _module.Context.ResolveAssembly(parsedName.AssemblyName.ToAssemblyName(), throwIfNotFound: _throwIfNotFound); if (_canonResolver != null && nestedTypeNames.IsEmpty) { @@ -86,7 +90,7 @@ private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, stri } // If it didn't resolve and wasn't assembly-qualified, we also try core library - if (assemblyNameIfAny == null) + if (parsedName.AssemblyName == null) { Type type = GetTypeCore(module.Context.SystemModule, typeName, nestedTypeNames); if (type != null) @@ -94,7 +98,7 @@ private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, stri } if (_throwIfNotFound) - ThrowHelper.ThrowTypeLoadException(EscapeTypeName(typeName, nestedTypeNames), module); + ThrowHelper.ThrowTypeLoadException(parsedName.FullName, module); return null; } @@ -115,10 +119,5 @@ private static Type GetTypeCore(ModuleDesc module, string typeName, ReadOnlySpan return new Type(type); } - - private void ParseError() - { - ThrowHelper.ThrowTypeLoadException(_input.ToString(), _module); - } } } diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs index 613ec30fa01d2e..1b772684dc1c13 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/Utilities/LockFreeReaderHashtable.cs @@ -367,7 +367,7 @@ public TValue AddOrGetExisting(TValue value) private TValue AddOrGetExistingInner(TValue value, out bool addedValue) { -#if NET5_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(value); #else if (value == null) @@ -596,7 +596,7 @@ public bool Contains(TKey key) /// Value from the hashtable if found, otherwise null. public TValue GetValueIfExists(TValue value) { -#if NET5_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(value); #else if (value == null) diff --git a/src/coreclr/tools/ILVerification/ILVerification.projitems b/src/coreclr/tools/ILVerification/ILVerification.projitems index 81ce9f65d1139a..c0f3644b1ab343 100644 --- a/src/coreclr/tools/ILVerification/ILVerification.projitems +++ b/src/coreclr/tools/ILVerification/ILVerification.projitems @@ -66,12 +66,21 @@ Utilities\CustomAttributeTypeNameParser.cs - - Utilities\TypeNameParser.cs + + System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs + + + System\Diagnostics\CodeAnalysis\NullableAttributes.cs + + + Utilities\CustomAttributeTypeNameParser.Helpers Utilities\ValueStringBuilder.cs + + Utilities\ValueStringBuilder.AppendSpanFormattable.cs + Utilities\LockFreeReaderHashtable.cs diff --git a/src/coreclr/tools/ILVerify/ILVerify.csproj b/src/coreclr/tools/ILVerify/ILVerify.csproj index e1915c65d6f2dd..804f32ddc7bc38 100644 --- a/src/coreclr/tools/ILVerify/ILVerify.csproj +++ b/src/coreclr/tools/ILVerify/ILVerify.csproj @@ -17,6 +17,7 @@ + diff --git a/src/coreclr/tools/aot/AotCompilerCommon.props b/src/coreclr/tools/aot/AotCompilerCommon.props index 09d3cfdc92edce..90e63a4bff9831 100644 --- a/src/coreclr/tools/aot/AotCompilerCommon.props +++ b/src/coreclr/tools/aot/AotCompilerCommon.props @@ -4,6 +4,7 @@ false true Speed + Guard diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.InterfaceThunks.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.InterfaceThunks.cs index 92a5be3fed38c4..51bf6a6888e2ff 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.InterfaceThunks.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerTypeSystemContext.InterfaceThunks.cs @@ -313,7 +313,7 @@ public override MethodSignature Signature } else { - parameters[0] = Context.GetWellKnownType(WellKnownType.IntPtr); + parameters[0] = Context.GetWellKnownType(WellKnownType.Void).MakePointerType(); for (int i = 0; i < _methodRepresented.Signature.Length; i++) parameters[i + 1] = _methodRepresented.Signature[i]; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs index 730330a31a9bc6..fd8094bc702831 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs @@ -951,12 +951,12 @@ internal partial bool MethodRequiresDataFlowAnalysis(MethodProxy method) => RequiresDataflowAnalysisDueToSignature(method.Method); #pragma warning disable CA1822 // Other partial implementations are not in the ilc project - internal partial MethodReturnValue GetMethodReturnValue(MethodProxy method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) + internal partial MethodReturnValue GetMethodReturnValue(MethodProxy method, bool isNewObj, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) #pragma warning restore CA1822 // Mark members as static - => new MethodReturnValue(method.Method, dynamicallyAccessedMemberTypes); + => new MethodReturnValue(method.Method, isNewObj, dynamicallyAccessedMemberTypes); - internal partial MethodReturnValue GetMethodReturnValue(MethodProxy method) - => GetMethodReturnValue(method, GetReturnParameterAnnotation(method.Method)); + internal partial MethodReturnValue GetMethodReturnValue(MethodProxy method, bool isNewObj) + => GetMethodReturnValue(method, isNewObj, GetReturnParameterAnnotation(method.Method)); internal partial GenericParameterValue GetGenericParameterValue(GenericParameterProxy genericParameter) => new GenericParameterValue(genericParameter.GenericParameter, GetGenericParameterAnnotation(genericParameter.GenericParameter)); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs index f09a76221ef37b..7207efb6d03f59 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/HandleCallAction.cs @@ -2,12 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; using System.Reflection; using ILCompiler; using ILCompiler.Dataflow; +using ILCompiler.DependencyAnalysis; +using ILCompiler.DependencyAnalysisFramework; using ILLink.Shared.TypeSystemProxy; using Internal.TypeSystem; +using Internal.IL; +using DependencyList = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.DependencyList; +using MultiValue = ILLink.Shared.DataFlow.ValueSet; using WellKnownType = ILLink.Shared.TypeSystemProxy.WellKnownType; #nullable enable @@ -19,17 +25,21 @@ internal partial struct HandleCallAction #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods private readonly ReflectionMarker _reflectionMarker; + private ILOpcode _operation; private readonly MethodDesc _callingMethod; private readonly string _reason; public HandleCallAction( FlowAnnotations annotations, + ILOpcode operation, ReflectionMarker reflectionMarker, in DiagnosticContext diagnosticContext, MethodDesc callingMethod, string reason) { _reflectionMarker = reflectionMarker; + _operation = operation; + _isNewObj = operation == ILOpcode.newobj; _diagnosticContext = diagnosticContext; _callingMethod = callingMethod; _annotations = annotations; @@ -37,6 +47,518 @@ public HandleCallAction( _requireDynamicallyAccessedMembersAction = new(reflectionMarker, diagnosticContext, reason); } + private partial bool TryHandleIntrinsic ( + MethodProxy calledMethod, + MultiValue instanceValue, + IReadOnlyList argumentValues, + IntrinsicId intrinsicId, + out MultiValue? methodReturnValue) + { + MultiValue? maybeMethodReturnValue = methodReturnValue = null; + + switch (intrinsicId) + { + case IntrinsicId.Type_MakeGenericType: + { + bool triggersWarning = false; + + if (!instanceValue.IsEmpty() && !argumentValues[0].IsEmpty()) + { + foreach (var value in instanceValue.AsEnumerable()) + { + if (value is SystemTypeValue typeValue) + { + TypeDesc typeInstantiated = typeValue.RepresentedType.Type; + if (!typeInstantiated.IsGenericDefinition) + { + // Nothing to do, will fail at runtime + } + else if (TryGetMakeGenericInstantiation(_callingMethod, argumentValues[0], out Instantiation inst, out bool isExact)) + { + if (inst.Length == typeInstantiated.Instantiation.Length) + { + typeInstantiated = ((MetadataType)typeInstantiated).MakeInstantiatedType(inst); + + if (isExact) + { + _reflectionMarker.MarkType(_diagnosticContext.Origin, typeInstantiated, "MakeGenericType"); + } + else + { + _reflectionMarker.RuntimeDeterminedDependencies.Add(new MakeGenericTypeSite(typeInstantiated)); + } + } + } + else + { + triggersWarning = true; + } + + } + else if (value == NullValue.Instance) + { + // Nothing to do + } + else + { + // We don't know what type the `MakeGenericType` was called on + triggersWarning = true; + } + } + } + + if (triggersWarning) + { + ReflectionMethodBodyScanner.CheckAndReportRequires(_diagnosticContext, calledMethod.Method, DiagnosticUtilities.RequiresDynamicCodeAttribute); + } + + // This intrinsic is relevant to both trimming and AOT - call into trimming logic as well. + return TryHandleSharedIntrinsic(calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); + } + + case IntrinsicId.MethodInfo_MakeGenericMethod: + { + bool triggersWarning = false; + + if (!instanceValue.IsEmpty()) + { + foreach (var methodValue in instanceValue.AsEnumerable()) + { + if (methodValue is SystemReflectionMethodBaseValue methodBaseValue) + { + MethodDesc methodInstantiated = methodBaseValue.RepresentedMethod.Method; + if (!methodInstantiated.IsGenericMethodDefinition) + { + // Nothing to do, will fail at runtime + } + else if (!methodInstantiated.OwningType.IsGenericDefinition + && TryGetMakeGenericInstantiation(_callingMethod, argumentValues[0], out Instantiation inst, out bool isExact)) + { + if (inst.Length == methodInstantiated.Instantiation.Length) + { + methodInstantiated = methodInstantiated.MakeInstantiatedMethod(inst); + + if (isExact) + { + _reflectionMarker.MarkMethod(_diagnosticContext.Origin, methodInstantiated, "MakeGenericMethod"); + } + else + { + _reflectionMarker.RuntimeDeterminedDependencies.Add(new MakeGenericMethodSite(methodInstantiated)); + } + } + } + else + { + // If the owning type is a generic definition, we can't help much. + triggersWarning = true; + } + } + else if (methodValue == NullValue.Instance) + { + // Nothing to do + } + else + { + // We don't know what method the `MakeGenericMethod` was called on + triggersWarning = true; + } + } + } + + if (triggersWarning) + { + ReflectionMethodBodyScanner.CheckAndReportRequires(_diagnosticContext, calledMethod.Method, DiagnosticUtilities.RequiresDynamicCodeAttribute); + } + + // This intrinsic is relevant to both trimming and AOT - call into trimming logic as well. + return TryHandleSharedIntrinsic(calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); + } + + case IntrinsicId.None: + { + if (ReflectionMethodBodyScanner.IsPInvokeDangerous(calledMethod.Method, out bool comDangerousMethod, out bool aotUnsafeDelegate)) + { + if (aotUnsafeDelegate) + { + _diagnosticContext.AddDiagnostic(DiagnosticId.CorrectnessOfAbstractDelegatesCannotBeGuaranteed, calledMethod.GetDisplayName()); + } + + if (comDangerousMethod) + { + _diagnosticContext.AddDiagnostic(DiagnosticId.CorrectnessOfCOMCannotBeGuaranteed, calledMethod.GetDisplayName()); + } + } + + ReflectionMethodBodyScanner.CheckAndReportAllRequires(_diagnosticContext, calledMethod.Method); + + return TryHandleSharedIntrinsic(calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); + } + + case IntrinsicId.TypeDelegator_Ctor: + { + // This is an identity function for analysis purposes + if (_operation == ILOpcode.newobj) + AddReturnValue(argumentValues[0]); + } + break; + + case IntrinsicId.Array_Empty: + { + AddReturnValue(ArrayValue.Create(0, calledMethod.Method.Instantiation[0])); + } + break; + + // + // System.Array + // + // CreateInstance (Type, Int32) + // + case IntrinsicId.Array_CreateInstance: + { + // We could try to analyze if the type is known, but for now making sure this works for canonical arrays is enough. + TypeDesc canonArrayType = _reflectionMarker.Factory.TypeSystemContext.CanonType.MakeArrayType(); + _reflectionMarker.MarkType(_diagnosticContext.Origin, canonArrayType, "Array.CreateInstance was called"); + } + break; + + // + // System.Enum + // + // static GetValues (Type) + // + case IntrinsicId.Enum_GetValues: + { + // Enum.GetValues returns System.Array, but it's the array of the enum type under the hood + // and people depend on this undocumented detail (could have returned enum of the underlying + // type instead). + // + // At least until we have shared enum code, this needs extra handling to get it right. + foreach (var value in argumentValues[0].AsEnumerable ()) + { + if (value is SystemTypeValue systemTypeValue + && !systemTypeValue.RepresentedType.Type.IsGenericDefinition + && !systemTypeValue.RepresentedType.Type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) + { + if (systemTypeValue.RepresentedType.Type.IsEnum) + { + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ReflectedType(systemTypeValue.RepresentedType.Type.MakeArrayType()), "Enum.GetValues"); + } + } + else + ReflectionMethodBodyScanner.CheckAndReportRequires(_diagnosticContext, calledMethod.Method, DiagnosticUtilities.RequiresDynamicCodeAttribute); + } + } + break; + + // + // System.Runtime.InteropServices.Marshal + // + // static SizeOf (Type) + // static PtrToStructure (IntPtr, Type) + // static DestroyStructure (IntPtr, Type) + // static OffsetOf (Type, string) + // + case IntrinsicId.Marshal_SizeOf: + case IntrinsicId.Marshal_PtrToStructure: + case IntrinsicId.Marshal_DestroyStructure: + case IntrinsicId.Marshal_OffsetOf: + { + int paramIndex = intrinsicId == IntrinsicId.Marshal_SizeOf + || intrinsicId == IntrinsicId.Marshal_OffsetOf + ? 0 : 1; + + // We need the data to do struct marshalling. + foreach (var value in argumentValues[paramIndex].AsEnumerable ()) + { + if (value is SystemTypeValue systemTypeValue + && !systemTypeValue.RepresentedType.Type.IsGenericDefinition + && !systemTypeValue.RepresentedType.Type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) + { + if (systemTypeValue.RepresentedType.Type.IsDefType) + { + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.StructMarshallingData((DefType)systemTypeValue.RepresentedType.Type), "Marshal API"); + if (intrinsicId == IntrinsicId.Marshal_PtrToStructure + && systemTypeValue.RepresentedType.Type.GetParameterlessConstructor() is MethodDesc ctorMethod + && !_reflectionMarker.Factory.MetadataManager.IsReflectionBlocked(ctorMethod)) + { + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ReflectedMethod(ctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)), "Marshal API"); + } + } + } + else + ReflectionMethodBodyScanner.CheckAndReportRequires(_diagnosticContext, calledMethod.Method, DiagnosticUtilities.RequiresDynamicCodeAttribute); + } + } + break; + + // + // System.Runtime.InteropServices.Marshal + // + // static GetDelegateForFunctionPointer (IntPtr, Type) + // + case IntrinsicId.Marshal_GetDelegateForFunctionPointer: + { + // We need the data to do delegate marshalling. + foreach (var value in argumentValues[1].AsEnumerable ()) + { + if (value is SystemTypeValue systemTypeValue + && !systemTypeValue.RepresentedType.Type.IsGenericDefinition + && !systemTypeValue.RepresentedType.Type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) + { + if (systemTypeValue.RepresentedType.Type.IsDelegate) + { + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.DelegateMarshallingData((DefType)systemTypeValue.RepresentedType.Type), "Marshal API"); + } + } + else + ReflectionMethodBodyScanner.CheckAndReportRequires(_diagnosticContext, calledMethod.Method, DiagnosticUtilities.RequiresDynamicCodeAttribute); + } + } + break; + + // + // System.Delegate + // + // get_Method () + // + // System.Reflection.RuntimeReflectionExtensions + // + // GetMethodInfo (System.Delegate) + // + case IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo: + case IntrinsicId.Delegate_get_Method: + { + // Find the parameter: first is an instance method, second is an extension method. + MultiValue param = intrinsicId == IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo + ? argumentValues[0] : instanceValue; + + // If this is Delegate.Method accessed from RuntimeReflectionExtensions.GetMethodInfo, ignore + // because we handle the callsites to that one here as well. + if (Intrinsics.GetIntrinsicIdForMethod(_callingMethod) == IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo) + break; + + foreach (var valueNode in param.AsEnumerable()) + { + TypeDesc? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; + if (staticType is null || !staticType.IsDelegate) + { + // The static type is unknown or something useless like Delegate or MulticastDelegate. + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ReflectedDelegate(null), "Delegate.Method access on unknown delegate type"); + } + else + { + if (staticType.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ReflectedDelegate(staticType.GetTypeDefinition()), "Delegate.Method access (on inexact type)"); + else + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ReflectedDelegate(staticType.ConvertToCanonForm(CanonicalFormKind.Specific)), "Delegate.Method access"); + } + } + } + break; + + // + // System.Object + // + // GetType() + // + case IntrinsicId.Object_GetType: + { + foreach (var valueNode in instanceValue.AsEnumerable ()) + { + // Note that valueNode can be statically typed in IL as some generic argument type. + // For example: + // void Method(T instance) { instance.GetType().... } + // Currently this case will end up with null StaticType - since there's no typedef for the generic argument type. + // But it could be that T is annotated with for example PublicMethods: + // void Method<[DAM(PublicMethods)] T>(T instance) { instance.GetType().GetMethod("Test"); } + // In this case it's in theory possible to handle it, by treating the T basically as a base class + // for the actual type of "instance". But the analysis for this would be pretty complicated (as the marking + // has to happen on the callsite, which doesn't know that GetType() will be used...). + // For now we're intentionally ignoring this case - it will produce a warning. + // The counter example is: + // Method(new Derived); + // In this case to get correct results, trimmer would have to mark all public methods on Derived. Which + // currently it won't do. + + TypeDesc? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; + if (staticType is null || (!staticType.IsDefType && !staticType.IsArray)) + { + // We don't know anything about the type GetType was called on. Track this as a usual "result of a method call without any annotations" + AddReturnValue(_reflectionMarker.Annotations.GetMethodReturnValue(calledMethod, _isNewObj)); + } + else if (staticType.IsSealed() || staticType.IsTypeOf("System", "Delegate")) + { + // We can treat this one the same as if it was a typeof() expression + + // We can allow Object.GetType to be modeled as System.Delegate because we keep all methods + // on delegates anyway so reflection on something this approximation would miss is actually safe. + + // We ignore the fact that the type can be annotated (see below for handling of annotated types) + // This means the annotations (if any) won't be applied - instead we rely on the exact knowledge + // of the type. So for example even if the type is annotated with PublicMethods + // but the code calls GetProperties on it - it will work - mark properties, don't mark methods + // since we ignored the fact that it's annotated. + // This can be seen a little bit as a violation of the annotation, but we already have similar cases + // where a parameter is annotated and if something in the method sets a specific known type to it + // we will also make it just work, even if the annotation doesn't match the usage. + AddReturnValue(new SystemTypeValue(staticType)); + } + else + { + Debug.Assert(staticType is MetadataType || staticType.IsArray); + MetadataType closestMetadataType = staticType is MetadataType mdType ? + mdType : (MetadataType)_reflectionMarker.Factory.TypeSystemContext.GetWellKnownType(Internal.TypeSystem.WellKnownType.Array); + + var annotation = _reflectionMarker.Annotations.GetTypeAnnotation(staticType); + + if (annotation != default) + { + _reflectionMarker.Dependencies.Add(_reflectionMarker.Factory.ObjectGetTypeFlowDependencies(closestMetadataType), "GetType called on this type"); + } + + // Return a value which is "unknown type" with annotation. For now we'll use the return value node + // for the method, which means we're loosing the information about which staticType this + // started with. For now we don't need it, but we can add it later on. + AddReturnValue(_reflectionMarker.Annotations.GetMethodReturnValue(calledMethod, _isNewObj, annotation)); + } + } + } + break; + + // + // string System.Reflection.Assembly.Location getter + // string System.Reflection.AssemblyName.CodeBase getter + // string System.Reflection.AssemblyName.EscapedCodeBase getter + // + case IntrinsicId.Assembly_get_Location: + case IntrinsicId.AssemblyName_get_CodeBase: + case IntrinsicId.AssemblyName_get_EscapedCodeBase: + _diagnosticContext.AddDiagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile, calledMethod.GetDisplayName()); + break; + + // + // string System.Reflection.Assembly.GetFile(string) + // string System.Reflection.Assembly.GetFiles() + // string System.Reflection.Assembly.GetFiles(bool) + // + case IntrinsicId.Assembly_GetFile: + case IntrinsicId.Assembly_GetFiles: + _diagnosticContext.AddDiagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile, calledMethod.GetDisplayName()); + break; + + default: + return false; + } + + methodReturnValue = maybeMethodReturnValue; + return true; + + void AddReturnValue(MultiValue value) + { + maybeMethodReturnValue = (maybeMethodReturnValue is null) ? value : MultiValueLattice.Meet((MultiValue)maybeMethodReturnValue, value); + } + } + + private static bool TryGetMakeGenericInstantiation( + MethodDesc contextMethod, + in MultiValue genericParametersArray, + out Instantiation inst, + out bool isExact) + { + // We support calling MakeGeneric APIs with a very concrete instantiation array. + // Only the form of `new Type[] { typeof(Foo), typeof(T), typeof(Foo) }` is supported. + + inst = default; + isExact = true; + Debug.Assert(contextMethod.GetTypicalMethodDefinition() == contextMethod); + + var typesValue = genericParametersArray.AsSingleValue(); + if (typesValue is NullValue) + { + // This will fail at runtime but no warning needed + inst = Instantiation.Empty; + return true; + } + + // Is this an array we model? + if (typesValue is not ArrayValue array) + { + return false; + } + + int? size = array.Size.AsConstInt(); + if (size == null) + { + return false; + } + + TypeDesc[]? sigInst = null; + TypeDesc[]? defInst = null; + + ArrayBuilder result = default; + for (int i = 0; i < size.Value; i++) + { + // Go over each element of the array. If the value is unknown, bail. + if (!array.TryGetValueByIndex(i, out MultiValue value)) + { + return false; + } + + var singleValue = value.AsSingleValue(); + + TypeDesc? type = singleValue switch + { + SystemTypeValue systemType => systemType.RepresentedType.Type, + GenericParameterValue genericParamType => genericParamType.GenericParameter.GenericParameter, + NullableSystemTypeValue nullableSystemType => nullableSystemType.NullableType.Type, + _ => null + }; + + if (type is null) + { + return false; + } + + // type is now some type. + // Because dataflow analysis oddly operates on method bodies instantiated over + // generic parameters (as opposed to instantiated over signature variables) + // We need to swap generic parameters (T, U,...) for signature variables (!0, !!1,...). + // We need to do this for both generic parameters of the owning type, and generic + // parameters of the owning method. + if (type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) + { + if (sigInst == null) + { + TypeDesc contextType = contextMethod.OwningType; + sigInst = new TypeDesc[contextType.Instantiation.Length + contextMethod.Instantiation.Length]; + defInst = new TypeDesc[contextType.Instantiation.Length + contextMethod.Instantiation.Length]; + TypeSystemContext context = type.Context; + for (int j = 0; j < contextType.Instantiation.Length; j++) + { + sigInst[j] = context.GetSignatureVariable(j, method: false); + defInst[j] = contextType.Instantiation[j]; + } + for (int j = 0; j < contextMethod.Instantiation.Length; j++) + { + sigInst[j + contextType.Instantiation.Length] = context.GetSignatureVariable(j, method: true); + defInst[j + contextType.Instantiation.Length] = contextMethod.Instantiation[j]; + } + } + + isExact = false; + + // defInst is [T, U, V], sigInst is `[!0, !!0, !!1]`. + type = type.ReplaceTypesInConstructionOfType(defInst, sigInst); + } + + result.Add(type); + } + + inst = new Instantiation(result.ToArray()); + return true; + } + private partial bool MethodIsTypeConstructor(MethodProxy method) { if (!method.Method.IsConstructor) @@ -124,5 +646,34 @@ private partial bool MarkAssociatedProperty(MethodProxy method) } private partial string GetContainingSymbolDisplayName() => _callingMethod.GetDisplayName(); + + private sealed class MakeGenericMethodSite : INodeWithRuntimeDeterminedDependencies + { + private readonly MethodDesc _method; + + public MakeGenericMethodSite(MethodDesc method) => _method = method; + + public IEnumerable.DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation) + { + var list = new DependencyList(); + RootingHelpers.TryGetDependenciesForReflectedMethod(ref list, factory, _method.InstantiateSignature(typeInstantiation, methodInstantiation), "MakeGenericMethod"); + return list; + } + } + + private sealed class MakeGenericTypeSite : INodeWithRuntimeDeterminedDependencies + { + private readonly TypeDesc _type; + + public MakeGenericTypeSite(TypeDesc type) => _type = type; + + public IEnumerable.DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation) + { + var list = new DependencyList(); + RootingHelpers.TryGetDependenciesForReflectedType(ref list, factory, _type.InstantiateSignature(typeInstantiation, methodInstantiation), "MakeGenericType"); + return list; + } + } + } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs index 87764b54a3d738..76da7a29ab8c98 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodBodyScanner.cs @@ -1156,11 +1156,8 @@ private ValueNodeList PopCallArguments( Stack currentStack, MethodDesc methodCalled, MethodIL containingMethodBody, - bool isNewObj, int ilOffset, - out SingleValue? newObjValue) + bool isNewObj, int ilOffset) { - newObjValue = null; - int countToPop = 0; if (!isNewObj && !methodCalled.Signature.IsStatic) countToPop++; @@ -1175,8 +1172,7 @@ private ValueNodeList PopCallArguments( if (isNewObj) { - newObjValue = UnknownValue.Instance; - methodParams.Add(newObjValue); + methodParams.Add(UnknownValue.Instance); } methodParams.Reverse(); return methodParams; @@ -1275,9 +1271,7 @@ private void HandleCall( { bool isNewObj = opcode == ILOpcode.newobj; - SingleValue? newObjValue; - ValueNodeList methodArguments = PopCallArguments(currentStack, calledMethod, callingMethodBody, isNewObj, - offset, out newObjValue); + ValueNodeList methodArguments = PopCallArguments(currentStack, calledMethod, callingMethodBody, isNewObj, offset); // Multi-dimensional array access is represented as a call to a special Get method on the array (runtime provided method) // We don't track multi-dimensional arrays in any way, so return unknown value. @@ -1290,33 +1284,12 @@ private void HandleCall( var dereferencedMethodParams = new List(); foreach (var argument in methodArguments) dereferencedMethodParams.Add(DereferenceValue(callingMethodBody, offset, argument, locals, ref interproceduralState)); - MultiValue methodReturnValue; - bool handledFunction = HandleCall( + MultiValue methodReturnValue = HandleCall( callingMethodBody, calledMethod, opcode, offset, - new ValueNodeList(dereferencedMethodParams), - out methodReturnValue); - - // Handle the return value or newobj result - if (!handledFunction) - { - if (isNewObj) - { - if (newObjValue == null) - methodReturnValue = UnknownValue.Instance; - else - methodReturnValue = newObjValue; - } - else - { - if (!calledMethod.Signature.ReturnType.IsVoid) - { - methodReturnValue = UnknownValue.Instance; - } - } - } + new ValueNodeList(dereferencedMethodParams)); if (isNewObj || !calledMethod.Signature.ReturnType.IsVoid) currentStack.Push(new StackSlot(methodReturnValue)); @@ -1335,13 +1308,12 @@ private void HandleCall( } } - public abstract bool HandleCall( + public abstract MultiValue HandleCall( MethodIL callingMethodBody, MethodDesc calledMethod, ILOpcode operation, int offset, - ValueNodeList methodParams, - out MultiValue methodReturnValue); + ValueNodeList methodParams); // Limit tracking array values to 32 values for performance reasons. There are many arrays much longer than 32 elements in .NET, but the interesting ones for trimming are nearly always less than 32 elements. private const int MaxTrackedArrayValues = 32; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodReturnValue.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodReturnValue.cs index 7bb244d8d2bf07..7b90ffe6404599 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodReturnValue.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/MethodReturnValue.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using ILCompiler.Dataflow; using ILLink.Shared.DataFlow; @@ -16,9 +17,10 @@ namespace ILLink.Shared.TrimAnalysis /// internal partial record MethodReturnValue { - public MethodReturnValue(MethodDesc method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) + public MethodReturnValue(MethodDesc method, bool isNewObj, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) { - StaticType = method.Signature.ReturnType; + Debug.Assert(!isNewObj || method.IsConstructor, "isNewObj can only be true for constructors"); + StaticType = isNewObj ? method.OwningType : method.Signature.ReturnType; Method = method; DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs index ad84c511393d69..6a00b2df965762 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -118,7 +118,7 @@ protected override void Scan(MethodIL methodBody, ref InterproceduralState inter if (!methodBody.OwningMethod.Signature.ReturnType.IsVoid) { var method = methodBody.OwningMethod; - var methodReturnValue = _annotations.GetMethodReturnValue(method); + var methodReturnValue = _annotations.GetMethodReturnValue(method, isNewObj: false); if (methodReturnValue.DynamicallyAccessedMemberTypes != 0) HandleAssignmentPattern(_origin, ReturnValue, methodReturnValue, method.GetDisplayName()); } @@ -261,7 +261,7 @@ protected override void HandleFieldTokenAccess(MethodIL methodBody, int offset, ProcessGenericArgumentDataFlow(accessedField); } - public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMethod, ILOpcode operation, int offset, ValueNodeList methodParams, out MultiValue methodReturnValue) + public override MultiValue HandleCall(MethodIL callingMethodBody, MethodDesc calledMethod, ILOpcode operation, int offset, ValueNodeList methodParams) { Debug.Assert(callingMethodBody.OwningMethod == _origin.MemberDefinition); @@ -300,616 +300,32 @@ public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMet instanceValue, arguments, diagnosticContext, - _reflectionMarker, - out methodReturnValue); + _reflectionMarker); } - public static bool HandleCall( + public static MultiValue HandleCall( MethodIL callingMethodBody, MethodDesc calledMethod, ILOpcode operation, MultiValue instanceValue, ImmutableArray argumentValues, DiagnosticContext diagnosticContext, - ReflectionMarker reflectionMarker, - out MultiValue methodReturnValue) + ReflectionMarker reflectionMarker) { var callingMethodDefinition = callingMethodBody.OwningMethod; Debug.Assert(callingMethodDefinition == diagnosticContext.Origin.MemberDefinition); - var annotatedMethodReturnValue = reflectionMarker.Annotations.GetMethodReturnValue(calledMethod); + bool isNewObj = operation == ILOpcode.newobj; + var annotatedMethodReturnValue = reflectionMarker.Annotations.GetMethodReturnValue(calledMethod, isNewObj); Debug.Assert( RequiresReflectionMethodBodyScannerForCallSite(reflectionMarker.Annotations, calledMethod) || annotatedMethodReturnValue.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.None); - MultiValue? maybeMethodReturnValue = null; - - var handleCallAction = new HandleCallAction(reflectionMarker.Annotations, reflectionMarker, diagnosticContext, callingMethodDefinition, calledMethod.GetDisplayName()); - + var handleCallAction = new HandleCallAction(reflectionMarker.Annotations, operation, reflectionMarker, diagnosticContext, callingMethodDefinition, calledMethod.GetDisplayName()); var intrinsicId = Intrinsics.GetIntrinsicIdForMethod(calledMethod); - switch (intrinsicId) - { - case IntrinsicId.IntrospectionExtensions_GetTypeInfo: - case IntrinsicId.TypeInfo_AsType: - case IntrinsicId.Type_get_UnderlyingSystemType: - case IntrinsicId.Type_GetTypeFromHandle: - case IntrinsicId.Type_get_TypeHandle: - case IntrinsicId.Type_GetInterface: - case IntrinsicId.Type_get_AssemblyQualifiedName: - case IntrinsicId.RuntimeHelpers_RunClassConstructor: - case IntrinsicId.Type_GetConstructors__BindingFlags: - case IntrinsicId.Type_GetMethods__BindingFlags: - case IntrinsicId.Type_GetFields__BindingFlags: - case IntrinsicId.Type_GetProperties__BindingFlags: - case IntrinsicId.Type_GetEvents__BindingFlags: - case IntrinsicId.Type_GetNestedTypes__BindingFlags: - case IntrinsicId.Type_GetMembers__BindingFlags: - case IntrinsicId.Type_GetField: - case IntrinsicId.Type_GetProperty: - case IntrinsicId.Type_GetEvent: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeEvent: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeField: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeMethod: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeProperty: - case IntrinsicId.Type_GetMember: - case IntrinsicId.Type_GetMethod: - case IntrinsicId.Type_GetNestedType: - case IntrinsicId.Nullable_GetUnderlyingType: - case IntrinsicId.Expression_Property: - case IntrinsicId.Expression_Field: - case IntrinsicId.Type_get_BaseType: - case IntrinsicId.Type_GetConstructor: - case IntrinsicId.MethodBase_GetMethodFromHandle: - case IntrinsicId.MethodBase_get_MethodHandle: - case IntrinsicId.Expression_Call: - case IntrinsicId.Expression_New: - case IntrinsicId.Type_GetType: - case IntrinsicId.Activator_CreateInstance__Type: - case IntrinsicId.Activator_CreateInstance__AssemblyName_TypeName: - case IntrinsicId.Activator_CreateInstanceFrom: - case IntrinsicId.AppDomain_CreateInstance: - case IntrinsicId.AppDomain_CreateInstanceAndUnwrap: - case IntrinsicId.AppDomain_CreateInstanceFrom: - case IntrinsicId.AppDomain_CreateInstanceFromAndUnwrap: - case IntrinsicId.Assembly_CreateInstance: - { - return handleCallAction.Invoke(calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); - } - - case IntrinsicId.Type_MakeGenericType: - { - bool triggersWarning = false; - - if (!instanceValue.IsEmpty() && !argumentValues[0].IsEmpty()) - { - foreach (var value in instanceValue.AsEnumerable()) - { - if (value is SystemTypeValue typeValue) - { - TypeDesc typeInstantiated = typeValue.RepresentedType.Type; - if (!typeInstantiated.IsGenericDefinition) - { - // Nothing to do, will fail at runtime - } - else if (TryGetMakeGenericInstantiation(callingMethodDefinition, argumentValues[0], out Instantiation inst, out bool isExact)) - { - if (inst.Length == typeInstantiated.Instantiation.Length) - { - typeInstantiated = ((MetadataType)typeInstantiated).MakeInstantiatedType(inst); - - if (isExact) - { - reflectionMarker.MarkType(diagnosticContext.Origin, typeInstantiated, "MakeGenericType"); - } - else - { - reflectionMarker.RuntimeDeterminedDependencies.Add(new MakeGenericTypeSite(typeInstantiated)); - } - } - } - else - { - triggersWarning = true; - } - - } - else if (value == NullValue.Instance) - { - // Nothing to do - } - else - { - // We don't know what type the `MakeGenericType` was called on - triggersWarning = true; - } - } - } - - if (triggersWarning) - { - CheckAndReportRequires(diagnosticContext, calledMethod, DiagnosticUtilities.RequiresDynamicCodeAttribute); - } - - // This intrinsic is relevant to both trimming and AOT - call into trimming logic as well. - return handleCallAction.Invoke(calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); - } - - case IntrinsicId.MethodInfo_MakeGenericMethod: - { - bool triggersWarning = false; - - if (!instanceValue.IsEmpty()) - { - foreach (var methodValue in instanceValue.AsEnumerable()) - { - if (methodValue is SystemReflectionMethodBaseValue methodBaseValue) - { - MethodDesc methodInstantiated = methodBaseValue.RepresentedMethod.Method; - if (!methodInstantiated.IsGenericMethodDefinition) - { - // Nothing to do, will fail at runtime - } - else if (!methodInstantiated.OwningType.IsGenericDefinition - && TryGetMakeGenericInstantiation(callingMethodDefinition, argumentValues[0], out Instantiation inst, out bool isExact)) - { - if (inst.Length == methodInstantiated.Instantiation.Length) - { - methodInstantiated = methodInstantiated.MakeInstantiatedMethod(inst); - - if (isExact) - { - reflectionMarker.MarkMethod(diagnosticContext.Origin, methodInstantiated, "MakeGenericMethod"); - } - else - { - reflectionMarker.RuntimeDeterminedDependencies.Add(new MakeGenericMethodSite(methodInstantiated)); - } - } - } - else - { - // If the owning type is a generic definition, we can't help much. - triggersWarning = true; - } - } - else if (methodValue == NullValue.Instance) - { - // Nothing to do - } - else - { - // We don't know what method the `MakeGenericMethod` was called on - triggersWarning = true; - } - } - } - - if (triggersWarning) - { - CheckAndReportRequires(diagnosticContext, calledMethod, DiagnosticUtilities.RequiresDynamicCodeAttribute); - } - - // This intrinsic is relevant to both trimming and AOT - call into trimming logic as well. - return handleCallAction.Invoke(calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); - } - - case IntrinsicId.None: - { - if (IsPInvokeDangerous(calledMethod, out bool comDangerousMethod, out bool aotUnsafeDelegate)) - { - if (aotUnsafeDelegate) - { - diagnosticContext.AddDiagnostic(DiagnosticId.CorrectnessOfAbstractDelegatesCannotBeGuaranteed, calledMethod.GetDisplayName()); - } - - if (comDangerousMethod) - { - diagnosticContext.AddDiagnostic(DiagnosticId.CorrectnessOfCOMCannotBeGuaranteed, calledMethod.GetDisplayName()); - } - } - - CheckAndReportAllRequires(diagnosticContext, calledMethod); - - return handleCallAction.Invoke(calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); - } - - case IntrinsicId.TypeDelegator_Ctor: - { - // This is an identity function for analysis purposes - if (operation == ILOpcode.newobj) - AddReturnValue(argumentValues[0]); - } - break; - - case IntrinsicId.Array_Empty: - { - AddReturnValue(ArrayValue.Create(0, calledMethod.Instantiation[0])); - } - break; - - // - // System.Array - // - // CreateInstance (Type, Int32) - // - case IntrinsicId.Array_CreateInstance: - { - // We could try to analyze if the type is known, but for now making sure this works for canonical arrays is enough. - TypeDesc canonArrayType = reflectionMarker.Factory.TypeSystemContext.CanonType.MakeArrayType(); - reflectionMarker.MarkType(diagnosticContext.Origin, canonArrayType, "Array.CreateInstance was called"); - goto case IntrinsicId.None; - } - - // - // System.Enum - // - // static GetValues (Type) - // - case IntrinsicId.Enum_GetValues: - { - // Enum.GetValues returns System.Array, but it's the array of the enum type under the hood - // and people depend on this undocumented detail (could have returned enum of the underlying - // type instead). - // - // At least until we have shared enum code, this needs extra handling to get it right. - foreach (var value in argumentValues[0].AsEnumerable ()) - { - if (value is SystemTypeValue systemTypeValue - && !systemTypeValue.RepresentedType.Type.IsGenericDefinition - && !systemTypeValue.RepresentedType.Type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) - { - if (systemTypeValue.RepresentedType.Type.IsEnum) - { - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.ReflectedType(systemTypeValue.RepresentedType.Type.MakeArrayType()), "Enum.GetValues"); - } - } - else - CheckAndReportRequires(diagnosticContext, calledMethod, DiagnosticUtilities.RequiresDynamicCodeAttribute); - } - } - break; - - // - // System.Runtime.InteropServices.Marshal - // - // static SizeOf (Type) - // static PtrToStructure (IntPtr, Type) - // static DestroyStructure (IntPtr, Type) - // static OffsetOf (Type, string) - // - case IntrinsicId.Marshal_SizeOf: - case IntrinsicId.Marshal_PtrToStructure: - case IntrinsicId.Marshal_DestroyStructure: - case IntrinsicId.Marshal_OffsetOf: - { - int paramIndex = intrinsicId == IntrinsicId.Marshal_SizeOf - || intrinsicId == IntrinsicId.Marshal_OffsetOf - ? 0 : 1; - - // We need the data to do struct marshalling. - foreach (var value in argumentValues[paramIndex].AsEnumerable ()) - { - if (value is SystemTypeValue systemTypeValue - && !systemTypeValue.RepresentedType.Type.IsGenericDefinition - && !systemTypeValue.RepresentedType.Type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) - { - if (systemTypeValue.RepresentedType.Type.IsDefType) - { - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.StructMarshallingData((DefType)systemTypeValue.RepresentedType.Type), "Marshal API"); - if (intrinsicId == IntrinsicId.Marshal_PtrToStructure - && systemTypeValue.RepresentedType.Type.GetParameterlessConstructor() is MethodDesc ctorMethod - && !reflectionMarker.Factory.MetadataManager.IsReflectionBlocked(ctorMethod)) - { - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.ReflectedMethod(ctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)), "Marshal API"); - } - } - } - else - CheckAndReportRequires(diagnosticContext, calledMethod, DiagnosticUtilities.RequiresDynamicCodeAttribute); - } - } - break; - - // - // System.Runtime.InteropServices.Marshal - // - // static GetDelegateForFunctionPointer (IntPtr, Type) - // - case IntrinsicId.Marshal_GetDelegateForFunctionPointer: - { - // We need the data to do delegate marshalling. - foreach (var value in argumentValues[1].AsEnumerable ()) - { - if (value is SystemTypeValue systemTypeValue - && !systemTypeValue.RepresentedType.Type.IsGenericDefinition - && !systemTypeValue.RepresentedType.Type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) - { - if (systemTypeValue.RepresentedType.Type.IsDelegate) - { - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.DelegateMarshallingData((DefType)systemTypeValue.RepresentedType.Type), "Marshal API"); - } - } - else - CheckAndReportRequires(diagnosticContext, calledMethod, DiagnosticUtilities.RequiresDynamicCodeAttribute); - } - } - break; - - // - // System.Delegate - // - // get_Method () - // - // System.Reflection.RuntimeReflectionExtensions - // - // GetMethodInfo (System.Delegate) - // - case IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo: - case IntrinsicId.Delegate_get_Method: - { - // Find the parameter: first is an instance method, second is an extension method. - MultiValue param = intrinsicId == IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo - ? argumentValues[0] : instanceValue; - - // If this is Delegate.Method accessed from RuntimeReflectionExtensions.GetMethodInfo, ignore - // because we handle the callsites to that one here as well. - if (Intrinsics.GetIntrinsicIdForMethod(callingMethodDefinition) == IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo) - break; - - if (param.IsEmpty()) - { - // The static value is unknown and the below `foreach` won't execute - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.ReflectedDelegate(null), "Delegate.Method access on unknown delegate type"); - } - - foreach (var valueNode in param.AsEnumerable()) - { - TypeDesc? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; - if (staticType is null || !staticType.IsDelegate) - { - // The static type is unknown or something useless like Delegate or MulticastDelegate. - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.ReflectedDelegate(null), "Delegate.Method access on unknown delegate type"); - } - else - { - if (staticType.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.ReflectedDelegate(staticType.GetTypeDefinition()), "Delegate.Method access (on inexact type)"); - else - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.ReflectedDelegate(staticType.ConvertToCanonForm(CanonicalFormKind.Specific)), "Delegate.Method access"); - } - } - } - break; - - // - // System.Object - // - // GetType() - // - case IntrinsicId.Object_GetType: - { - foreach (var valueNode in instanceValue.AsEnumerable ()) - { - // Note that valueNode can be statically typed in IL as some generic argument type. - // For example: - // void Method(T instance) { instance.GetType().... } - // Currently this case will end up with null StaticType - since there's no typedef for the generic argument type. - // But it could be that T is annotated with for example PublicMethods: - // void Method<[DAM(PublicMethods)] T>(T instance) { instance.GetType().GetMethod("Test"); } - // In this case it's in theory possible to handle it, by treating the T basically as a base class - // for the actual type of "instance". But the analysis for this would be pretty complicated (as the marking - // has to happen on the callsite, which doesn't know that GetType() will be used...). - // For now we're intentionally ignoring this case - it will produce a warning. - // The counter example is: - // Method(new Derived); - // In this case to get correct results, trimmer would have to mark all public methods on Derived. Which - // currently it won't do. - - TypeDesc? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; - if (staticType is null || (!staticType.IsDefType && !staticType.IsArray)) - { - // We don't know anything about the type GetType was called on. Track this as a usual "result of a method call without any annotations" - AddReturnValue(reflectionMarker.Annotations.GetMethodReturnValue(calledMethod)); - } - else if (staticType.IsSealed() || staticType.IsTypeOf("System", "Delegate")) - { - // We can treat this one the same as if it was a typeof() expression - - // We can allow Object.GetType to be modeled as System.Delegate because we keep all methods - // on delegates anyway so reflection on something this approximation would miss is actually safe. - - // We ignore the fact that the type can be annotated (see below for handling of annotated types) - // This means the annotations (if any) won't be applied - instead we rely on the exact knowledge - // of the type. So for example even if the type is annotated with PublicMethods - // but the code calls GetProperties on it - it will work - mark properties, don't mark methods - // since we ignored the fact that it's annotated. - // This can be seen a little bit as a violation of the annotation, but we already have similar cases - // where a parameter is annotated and if something in the method sets a specific known type to it - // we will also make it just work, even if the annotation doesn't match the usage. - AddReturnValue(new SystemTypeValue(staticType)); - } - else - { - Debug.Assert(staticType is MetadataType || staticType.IsArray); - MetadataType closestMetadataType = staticType is MetadataType mdType ? - mdType : (MetadataType)reflectionMarker.Factory.TypeSystemContext.GetWellKnownType(Internal.TypeSystem.WellKnownType.Array); - - var annotation = reflectionMarker.Annotations.GetTypeAnnotation(staticType); - - if (annotation != default) - { - reflectionMarker.Dependencies.Add(reflectionMarker.Factory.ObjectGetTypeFlowDependencies(closestMetadataType), "GetType called on this type"); - } - - // Return a value which is "unknown type" with annotation. For now we'll use the return value node - // for the method, which means we're loosing the information about which staticType this - // started with. For now we don't need it, but we can add it later on. - AddReturnValue(reflectionMarker.Annotations.GetMethodReturnValue(calledMethod, annotation)); - } - } - } - break; - - // - // string System.Reflection.Assembly.Location getter - // string System.Reflection.AssemblyName.CodeBase getter - // string System.Reflection.AssemblyName.EscapedCodeBase getter - // - case IntrinsicId.Assembly_get_Location: - case IntrinsicId.AssemblyName_get_CodeBase: - case IntrinsicId.AssemblyName_get_EscapedCodeBase: - diagnosticContext.AddDiagnostic(DiagnosticId.AvoidAssemblyLocationInSingleFile, calledMethod.GetDisplayName()); - break; - - // - // string System.Reflection.Assembly.GetFile(string) - // string System.Reflection.Assembly.GetFiles() - // string System.Reflection.Assembly.GetFiles(bool) - // - case IntrinsicId.Assembly_GetFile: - case IntrinsicId.Assembly_GetFiles: - diagnosticContext.AddDiagnostic(DiagnosticId.AvoidAssemblyGetFilesInSingleFile, calledMethod.GetDisplayName()); - break; - - default: - throw new NotImplementedException("Unhandled intrinsic"); - } - - // If we get here, we handled this as an intrinsic. As a convenience, if the code above - // didn't set the return value (and the method has a return value), we will set it to be an - // unknown value with the return type of the method. - bool returnsVoid = calledMethod.Signature.ReturnType.IsVoid; - methodReturnValue = maybeMethodReturnValue ?? (returnsVoid ? - MultiValueLattice.Top : - annotatedMethodReturnValue); - - // Validate that the return value has the correct annotations as per the method return value annotations - if (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes != 0) - { - foreach (var uniqueValue in methodReturnValue.AsEnumerable ()) - { - if (uniqueValue is ValueWithDynamicallyAccessedMembers methodReturnValueWithMemberTypes) - { - if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag(annotatedMethodReturnValue.DynamicallyAccessedMemberTypes)) - throw new InvalidOperationException($"Internal trimming error: processing of call from {callingMethodDefinition.GetDisplayName()} to {calledMethod.GetDisplayName()} returned value which is not correctly annotated with the expected dynamic member access kinds."); - } - else if (uniqueValue is SystemTypeValue) - { - // SystemTypeValue can fulfill any requirement, so it's always valid - // The requirements will be applied at the point where it's consumed (passed as a method parameter, set as field value, returned from the method) - } - else - { - throw new InvalidOperationException($"Internal trimming error: processing of call from {callingMethodDefinition.GetDisplayName()} to {calledMethod.GetDisplayName()} returned value which is not correctly annotated with the expected dynamic member access kinds."); - } - } - } - - return true; - - void AddReturnValue(MultiValue value) - { - maybeMethodReturnValue = (maybeMethodReturnValue is null) ? value : MultiValueLattice.Meet((MultiValue)maybeMethodReturnValue, value); - } - } - - private static bool TryGetMakeGenericInstantiation( - MethodDesc contextMethod, - in MultiValue genericParametersArray, - out Instantiation inst, - out bool isExact) - { - // We support calling MakeGeneric APIs with a very concrete instantiation array. - // Only the form of `new Type[] { typeof(Foo), typeof(T), typeof(Foo) }` is supported. - - inst = default; - isExact = true; - Debug.Assert(contextMethod.GetTypicalMethodDefinition() == contextMethod); - - var typesValue = genericParametersArray.AsSingleValue(); - if (typesValue is NullValue) - { - // This will fail at runtime but no warning needed - inst = Instantiation.Empty; - return true; - } - - // Is this an array we model? - if (typesValue is not ArrayValue array) - { - return false; - } - - int? size = array.Size.AsConstInt(); - if (size == null) - { - return false; - } - - TypeDesc[]? sigInst = null; - TypeDesc[]? defInst = null; - - ArrayBuilder result = default; - for (int i = 0; i < size.Value; i++) - { - // Go over each element of the array. If the value is unknown, bail. - if (!array.TryGetValueByIndex(i, out MultiValue value)) - { - return false; - } - - var singleValue = value.AsSingleValue(); - - TypeDesc? type = singleValue switch - { - SystemTypeValue systemType => systemType.RepresentedType.Type, - GenericParameterValue genericParamType => genericParamType.GenericParameter.GenericParameter, - NullableSystemTypeValue nullableSystemType => nullableSystemType.NullableType.Type, - _ => null - }; - - if (type is null) - { - return false; - } - - // type is now some type. - // Because dataflow analysis oddly operates on method bodies instantiated over - // generic parameters (as opposed to instantiated over signature variables) - // We need to swap generic parameters (T, U,...) for signature variables (!0, !!1,...). - // We need to do this for both generic parameters of the owning type, and generic - // parameters of the owning method. - if (type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) - { - if (sigInst == null) - { - TypeDesc contextType = contextMethod.OwningType; - sigInst = new TypeDesc[contextType.Instantiation.Length + contextMethod.Instantiation.Length]; - defInst = new TypeDesc[contextType.Instantiation.Length + contextMethod.Instantiation.Length]; - TypeSystemContext context = type.Context; - for (int j = 0; j < contextType.Instantiation.Length; j++) - { - sigInst[j] = context.GetSignatureVariable(j, method: false); - defInst[j] = contextType.Instantiation[j]; - } - for (int j = 0; j < contextMethod.Instantiation.Length; j++) - { - sigInst[j + contextType.Instantiation.Length] = context.GetSignatureVariable(j, method: true); - defInst[j + contextType.Instantiation.Length] = contextMethod.Instantiation[j]; - } - } - - isExact = false; - - // defInst is [T, U, V], sigInst is `[!0, !!0, !!1]`. - type = type.ReplaceTypesInConstructionOfType(defInst, sigInst); - } - - result.Add(type); - } - - inst = new Instantiation(result.ToArray()); - return true; + if (!handleCallAction.Invoke(calledMethod, instanceValue, argumentValues, intrinsicId, out MultiValue methodReturnValue)) + throw new NotImplementedException($"Unhandled intrinsic {intrinsicId}"); + return methodReturnValue; } private static bool IsAotUnsafeDelegate(TypeDesc parameterType) @@ -1042,7 +458,7 @@ private void ProcessGenericArgumentDataFlow(TypeDesc type) } } - private static bool IsPInvokeDangerous(MethodDesc calledMethod, out bool comDangerousMethod, out bool aotUnsafeDelegate) + internal static bool IsPInvokeDangerous(MethodDesc calledMethod, out bool comDangerousMethod, out bool aotUnsafeDelegate) { if (!calledMethod.IsPInvoke) { @@ -1072,33 +488,5 @@ private static bool IsPInvokeDangerous(MethodDesc calledMethod, out bool comDang return aotUnsafeDelegate || comDangerousMethod; } - - private sealed class MakeGenericMethodSite : INodeWithRuntimeDeterminedDependencies - { - private readonly MethodDesc _method; - - public MakeGenericMethodSite(MethodDesc method) => _method = method; - - public IEnumerable.DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation) - { - var list = new DependencyList(); - RootingHelpers.TryGetDependenciesForReflectedMethod(ref list, factory, _method.InstantiateSignature(typeInstantiation, methodInstantiation), "MakeGenericMethod"); - return list; - } - } - - private sealed class MakeGenericTypeSite : INodeWithRuntimeDeterminedDependencies - { - private readonly TypeDesc _type; - - public MakeGenericTypeSite(TypeDesc type) => _type = type; - - public IEnumerable.DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation) - { - var list = new DependencyList(); - RootingHelpers.TryGetDependenciesForReflectedType(ref list, factory, _type.InstantiateSignature(typeInstantiation, methodInstantiation), "MakeGenericType"); - return list; - } - } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisMethodCallPattern.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisMethodCallPattern.cs index 9f2caf292999b4..48b0bbf5aff643 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisMethodCallPattern.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TrimAnalysisMethodCallPattern.cs @@ -86,8 +86,7 @@ public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker, Logger logger); ReflectionMethodBodyScanner.HandleCall(MethodBody, CalledMethod, Operation, Instance, Arguments, diagnosticContext, - reflectionMarker, - out MultiValue _); + reflectionMarker); } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TypeNameParser.Dataflow.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TypeNameParser.Dataflow.cs index 90b63f39c9f026..278b6c4735afcc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TypeNameParser.Dataflow.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/TypeNameParser.Dataflow.cs @@ -2,16 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Reflection; - +using System.Reflection.Metadata; using Internal.TypeSystem; namespace System.Reflection { internal partial struct TypeNameParser { + private static readonly TypeNameParseOptions s_typeNameParseOptions = new() { MaxNodes = int.MaxValue }; + private TypeSystemContext _context; private ModuleDesc _callingModule; private List _referencedModules; @@ -20,14 +19,20 @@ internal partial struct TypeNameParser public static TypeDesc ResolveType(string name, ModuleDesc callingModule, TypeSystemContext context, List referencedModules, out bool typeWasNotFoundInAssemblyNorBaseLibrary) { - var parser = new TypeNameParser(name) + if (!TypeName.TryParse(name, out TypeName parsed, s_typeNameParseOptions)) + { + typeWasNotFoundInAssemblyNorBaseLibrary = false; + return null; + } + + var parser = new TypeNameParser() { _context = context, _callingModule = callingModule, _referencedModules = referencedModules }; - TypeDesc result = parser.Parse()?.Value; + TypeDesc result = parser.Resolve(parsed)?.Value; typeWasNotFoundInAssemblyNorBaseLibrary = parser._typeWasNotFoundInAssemblyNorBaseLibrary; return result; @@ -52,16 +57,13 @@ public Type MakeGenericType(Type[] typeArguments) } } - private static bool CheckTopLevelAssemblyQualifiedName() => true; - - private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, string assemblyNameIfAny) + private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, TypeName parsedName) { ModuleDesc module; - if (assemblyNameIfAny != null) + if (parsedName.AssemblyName != null) { - module = (TryParseAssemblyName(assemblyNameIfAny) is AssemblyName an) ? - _context.ResolveAssembly(an, throwIfNotFound: false) : null; + module = _context.ResolveAssembly(parsedName.AssemblyName.ToAssemblyName(), throwIfNotFound: false); } else { @@ -79,7 +81,7 @@ private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, stri } // If it didn't resolve and wasn't assembly-qualified, we also try core library - if (assemblyNameIfAny == null) + if (parsedName.AssemblyName == null) { Type type = GetTypeCore(_context.SystemModule, typeName, nestedTypeNames); if (type != null) @@ -94,22 +96,6 @@ private Type GetType(string typeName, ReadOnlySpan nestedTypeNames, stri return null; } - private static AssemblyName TryParseAssemblyName(string assemblyName) - { - try - { - return new AssemblyName(assemblyName); - } - catch (FileLoadException) - { - return null; - } - catch (ArgumentException) - { - return null; - } - } - private static Type GetTypeCore(ModuleDesc module, string typeName, ReadOnlySpan nestedTypeNames) { (string typeNamespace, string name) = SplitFullTypeName(typeName); @@ -127,9 +113,5 @@ private static Type GetTypeCore(ModuleDesc module, string typeName, ReadOnlySpan return new Type(type); } - - private static void ParseError() - { - } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs index 8faf4cf3fcfe7c..67cfd6cbe4f7a8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs @@ -67,6 +67,9 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, case ReadyToRunHelper.CheckedWriteBarrier: mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpCheckedAssignRefArm64" : "RhpCheckedAssignRef"; break; + case ReadyToRunHelper.BulkWriteBarrier: + mangledName = "RhBuffer_BulkMoveWithWriteBarrier"; + break; case ReadyToRunHelper.ByRefWriteBarrier: mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpByRefAssignRefArm64" : "RhpByRefAssignRef"; break; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.cs index 86ac433262f990..e65f7c889dd19a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.cs @@ -244,16 +244,12 @@ private protected override void EmitObjectFile(string objectFilePath) { case TargetOS.OSX: buildVersion.Platform = PLATFORM_MACOS; - buildVersion.MinimumPlatformVersion = 0x0A_0C_00; // 10.12.0 + buildVersion.MinimumPlatformVersion = 0x0C_00_00; // 12.0.0 break; case TargetOS.MacCatalyst: buildVersion.Platform = PLATFORM_MACCATALYST; - buildVersion.MinimumPlatformVersion = _cpuType switch - { - CPU_TYPE_X86_64 => 0x0D_05_00u, // 13.5.0 - _ => 0x0E_02_00u, // 14.2.0 - }; + buildVersion.MinimumPlatformVersion = 0x0F_02_00; // 15.0.0 break; case TargetOS.iOS: @@ -268,7 +264,7 @@ private protected override void EmitObjectFile(string objectFilePath) TargetOS.tvOSSimulator => PLATFORM_TVOSSIMULATOR, _ => 0, }; - buildVersion.MinimumPlatformVersion = 0x0B_00_00; // 11.0.0 + buildVersion.MinimumPlatformVersion = 0x0C_02_00; // 12.2.0 break; } buildVersion.Write(outputFileStream); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs index 19d8ee6efd959b..37a7d0de344893 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs @@ -533,8 +533,14 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack - - Compiler\Dataflow\TypeNameParser.cs + + Compiler\Dataflow\TypeNameParser.Helpers.cs Utilities\ValueStringBuilder.cs diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs index 98941b37c185e4..16f82023ad0b57 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs @@ -136,6 +136,7 @@ private static PerfmapTokensForTarget TranslateTargetDetailsToPerfmapConstants(T TargetArchitecture.X64 => PerfMapArchitectureToken.X64, TargetArchitecture.X86 => PerfMapArchitectureToken.X86, TargetArchitecture.RiscV64 => PerfMapArchitectureToken.RiscV64, + TargetArchitecture.LoongArch64 => PerfMapArchitectureToken.LoongArch64, _ => throw new NotImplementedException(details.Architecture.ToString()) }; diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs index 395b26f151ee83..281349be80e52e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ReadyToRunDiagnosticsConstants.cs @@ -20,6 +20,7 @@ public enum PerfMapArchitectureToken : uint X64 = 3, X86 = 4, RiscV64 = 5, + LoongArch64 = 6, } public enum PerfMapOSToken : uint diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index e1b1b359c0878a..7f702fd6b764aa 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1000,6 +1000,9 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_BYREF: id = ReadyToRunHelper.ByRefWriteBarrier; break; + case CorInfoHelpFunc.CORINFO_HELP_BULK_WRITEBARRIER: + id = ReadyToRunHelper.BulkWriteBarrier; + break; case CorInfoHelpFunc.CORINFO_HELP_ARRADDR_ST: id = ReadyToRunHelper.Stelem_Ref; diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index 0eae2f10cb8f00..329b95f5d3c4e2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -1672,6 +1672,10 @@ private void ParseHelper(StringBuilder builder) builder.Append("BYREF_WRITE_BARRIER"); break; + case ReadyToRunHelper.BulkWriteBarrier: + builder.Append("BULK_WRITE_BARRIER"); + break; + // Array helpers case ReadyToRunHelper.Stelem_Ref: builder.Append("STELEM_REF"); diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 2dfa5d9d88f67d..d344dd431fb557 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -497,6 +497,9 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum) case CorInfoHelpFunc.CORINFO_HELP_CHECKED_ASSIGN_REF: id = ReadyToRunHelper.CheckedWriteBarrier; break; + case CorInfoHelpFunc.CORINFO_HELP_BULK_WRITEBARRIER: + id = ReadyToRunHelper.BulkWriteBarrier; + break; case CorInfoHelpFunc.CORINFO_HELP_ASSIGN_BYREF: id = ReadyToRunHelper.ByRefWriteBarrier; break; diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs index e95197b669c94f..80a48c2da1695e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ILInputCompiler.cs @@ -45,7 +45,7 @@ protected virtual void SetupProcess (Process process, CompilerOptions options) private static string BuildArguments (CompilerOptions options) { var args = new StringBuilder (); -#if NETCOREAPP +#if NET args.Append (options.OutputPath.ExtensionWithDot == ".dll" ? "-dll" : "-exe"); args.Append ($" -out:{options.OutputPath.InQuotes ()}"); #else @@ -58,7 +58,7 @@ private static string BuildArguments (CompilerOptions options) protected virtual NPath LocateIlasm () { -#if NETCOREAPP +#if NET var extension = RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? ".exe" : ""; var toolsDir = (string) AppContext.GetData ("Mono.Linker.Tests.ILToolsDir")!; diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs index 770bc1e97dfa2b..a6eb6007661f62 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/ResultChecker.cs @@ -159,6 +159,8 @@ protected virtual void AdditionalChecking (TrimmedTestCaseResult linkResult, Ass private static bool IsProducedByNativeAOT (CustomAttribute attr) { + if (attr.ConstructorArguments.Count > 2 && attr.ConstructorArguments[^2].Type.Name == "Tool") + return ((Tool)attr.ConstructorArguments[^2].Value).HasFlag(Tool.NativeAot); var producedBy = attr.GetPropertyValue ("ProducedBy"); return producedBy is null ? true : ((Tool) producedBy).HasFlag (Tool.NativeAot); } @@ -227,12 +229,29 @@ private void VerifyLoggedMessages (AssemblyDefinition original, TrimmingTestLogg } break; - case nameof (ExpectedWarningAttribute): { + case nameof (ExpectedWarningAttribute) or nameof(UnexpectedWarningAttribute): { var expectedWarningCode = (string) attr.GetConstructorArgumentValue (0); if (!expectedWarningCode.StartsWith ("IL")) { - Assert.Fail ($"The warning code specified in {nameof (ExpectedWarningAttribute)} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'."); + Assert.Fail ($"The warning code specified in {attr.AttributeType.Name} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'."); } - var expectedMessageContains = ((CustomAttributeArgument[]) attr.GetConstructorArgumentValue (1)).Select (a => (string) a.Value).ToArray (); + IEnumerable expectedMessageContains = attr.Constructor.Parameters switch + { + // ExpectedWarningAttribute(string warningCode, params string[] expectedMessages) + // ExpectedWarningAttribute(string warningCode, string[] expectedMessages, Tool producedBy, string issueLink) + [_, { ParameterType.IsArray: true }, ..] + => ((CustomAttributeArgument[])attr.ConstructorArguments[1].Value) + .Select(caa => (string)caa.Value), + // ExpectedWarningAttribute(string warningCode, string expectedMessage1, string expectedMessage2, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "String" }, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] + => [(string)attr.GetConstructorArgumentValue(1), (string)attr.GetConstructorArgumentValue(2)], + // ExpectedWarningAttribute(string warningCode, string expectedMessage, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] + => [(string)attr.GetConstructorArgumentValue(1)], + // ExpectedWarningAttribute(string warningCode, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "Tool" }, _] + => [], + _ => throw new UnreachableException(), + }; string fileName = (string) attr.GetPropertyValue ("FileName")!; int? sourceLine = (int?) attr.GetPropertyValue ("SourceLine"); int? sourceColumn = (int?) attr.GetPropertyValue ("SourceColumn"); diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs index 4ff90c22300d4c..825663ac8bdae1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs @@ -77,7 +77,7 @@ public virtual IEnumerable GetDefines () yield return "WIN32"; if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) - yield return "NETCOREAPP"; + yield return "NET"; if (Characteristics.HasFlag (TestRunCharacteristics.SupportsDefaultInterfaceMethods)) yield return "SUPPORTS_DEFAULT_INTERFACE_METHODS"; diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs index d2b637de124e6f..b20c16631302c2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TestCaseCompiler.cs @@ -9,7 +9,7 @@ using System.Text; using Mono.Linker.Tests.Extensions; using Xunit; -#if NETCOREAPP +#if NET using System.Runtime.InteropServices; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Emit; @@ -190,7 +190,7 @@ protected static NPath MakeSupportingAssemblyReferencePathAbsolute (NPath output if (Path.IsPathRooted (referenceFileName)) return referenceFileName.ToNPath (); -#if NETCOREAPP +#if NET if (referenceFileName.StartsWith ("System.", StringComparison.Ordinal) || referenceFileName.StartsWith ("Mono.", StringComparison.Ordinal) || referenceFileName.StartsWith ("Microsoft.", StringComparison.Ordinal) || @@ -224,14 +224,14 @@ protected NPath CompileAssembly (CompilerOptions options) protected virtual NPath CompileCSharpAssemblyWithDefaultCompiler (CompilerOptions options) { -#if NETCOREAPP +#if NET return CompileCSharpAssemblyWithRoslyn (options); #else return CompileCSharpAssemblyWithCsc (options); #endif } -#if NETCOREAPP +#if NET protected virtual NPath CompileCSharpAssemblyWithRoslyn (CompilerOptions options) { var languageVersion = LanguageVersion.Default; @@ -331,7 +331,7 @@ protected virtual NPath CompileCSharpAssemblyWithRoslyn (CompilerOptions options protected virtual NPath CompileCSharpAssemblyWithCsc (CompilerOptions options) { -#if NETCOREAPP +#if NET return CompileCSharpAssemblyWithRoslyn (options); #else return CompileCSharpAssemblyWithExternalCompiler (LocateCscExecutable (), options, "/shared "); diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs index 1d075aeffeb354..ebcad66b5e0c48 100644 --- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs @@ -217,7 +217,7 @@ public virtual void ProcessOptions (TestCaseLinkerOptions options) IgnoreLinkAttributes (options.IgnoreLinkAttributes); -#if !NETCOREAPP +#if !NET if (!string.IsNullOrEmpty (options.Il8n)) AddIl8n (options.Il8n); #endif diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem/ILCompiler.TypeSystem.csproj b/src/coreclr/tools/aot/ILCompiler.TypeSystem/ILCompiler.TypeSystem.csproj index c46d5fecbfb76c..1a5db3b44445da 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem/ILCompiler.TypeSystem.csproj +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem/ILCompiler.TypeSystem.csproj @@ -198,8 +198,8 @@ Utilities\CustomAttributeTypeNameParser.cs - - Utilities\TypeNameParser.cs + + Utilities\CustomAttributeTypeNameParser.Helpers Utilities\ValueStringBuilder.cs @@ -714,6 +714,10 @@ + + + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index db1d0a721d1f15..905ddd41d82b5e 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -179,7 +179,7 @@ struct JitInterfaceCallbacks bool (* logMsg)(void * thisHandle, CorInfoExceptionClass** ppException, unsigned level, const char* fmt, va_list args); int (* doAssert)(void * thisHandle, CorInfoExceptionClass** ppException, const char* szFile, int iLine, const char* szExpr); void (* reportFatalError)(void * thisHandle, CorInfoExceptionClass** ppException, CorJitResult result); - JITINTERFACE_HRESULT (* getPgoInstrumentationResults)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t** pInstrumentationData, ICorJitInfo::PgoSource* pgoSource); + JITINTERFACE_HRESULT (* getPgoInstrumentationResults)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, bool* pDynamicPgo); JITINTERFACE_HRESULT (* allocPgoInstrumentationBySchema)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, uint32_t countSchemaItems, uint8_t** pInstrumentationData); void (* recordCallSite)(void * thisHandle, CorInfoExceptionClass** ppException, uint32_t instrOffset, CORINFO_SIG_INFO* callSig, CORINFO_METHOD_HANDLE methodHandle); void (* recordRelocation)(void * thisHandle, CorInfoExceptionClass** ppException, void* location, void* locationRW, void* target, uint16_t fRelocType, int32_t addlDelta); @@ -1843,10 +1843,11 @@ class JitInterfaceWrapper : public ICorJitInfo ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t** pInstrumentationData, - ICorJitInfo::PgoSource* pgoSource) + ICorJitInfo::PgoSource* pPgoSource, + bool* pDynamicPgo) { CorInfoExceptionClass* pException = nullptr; - JITINTERFACE_HRESULT temp = _callbacks->getPgoInstrumentationResults(_thisHandle, &pException, ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pgoSource); + JITINTERFACE_HRESULT temp = _callbacks->getPgoInstrumentationResults(_thisHandle, &pException, ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, pDynamicPgo); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/tools/cdac-build-tool/ComposeCommand.cs b/src/coreclr/tools/cdac-build-tool/ComposeCommand.cs new file mode 100644 index 00000000000000..226244a88872ab --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/ComposeCommand.cs @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.CommandLine; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +internal sealed class ComposeCommand : CliCommand +{ + private readonly CliArgument inputFiles = new("INPUT [INPUTS...]") { Arity = ArgumentArity.OneOrMore, Description = "One or more input files" }; + private readonly CliOption outputFile = new("-o") { Arity = ArgumentArity.ExactlyOne, HelpName = "OUTPUT", Required = true, Description = "Output file" }; + private readonly CliOption contractFile = new("-c") { Arity = ArgumentArity.ZeroOrMore, HelpName = "CONTRACT", Description = "Contract file (may be specified multiple times)" }; + private readonly CliOption _verboseOption; + public ComposeCommand(CliOption verboseOption) : base("compose") + { + _verboseOption = verboseOption; + Add(inputFiles); + Add(outputFile); + Add(contractFile); + SetAction(Run); + } + + private async Task Run(ParseResult parse, CancellationToken token = default) + { + var inputs = parse.GetValue(inputFiles); + if (inputs == null || inputs.Length == 0) + { + Console.Error.WriteLine("No input files specified"); + return 1; + } + var output = parse.GetValue(outputFile); + if (output == null) + { + Console.Error.WriteLine("No output file specified"); + return 1; + } + var contracts = parse.GetValue(contractFile); + var verbose = parse.GetValue(_verboseOption); + var builder = new DataDescriptorModel.Builder(); + var scraper = new ObjectFileScraper(verbose, builder); + foreach (var input in inputs) + { + token.ThrowIfCancellationRequested(); + if (!await scraper.ScrapeInput(input, token).ConfigureAwait(false)) + { + Console.Error.WriteLine($"could not scrape payload in {input}"); + return 1; + } + } + if (contracts != null) + { + var contractReader = new ContractReader(builder); + foreach (var contract in contracts) + { + if (!await contractReader.ParseContracts(contract, token).ConfigureAwait(false)) + { + Console.Error.WriteLine($"could not parse contracts in {contract}"); + return 1; + } + } + } + + var model = builder.Build(); + if (verbose) + { + model.DumpModel(); + } + EnsureDirectoryExists(output); + using var writer = new System.IO.StreamWriter(output); + var emitter = new ContractDescriptorSourceFileEmitter(); + emitter.SetPlatformFlags(model.PlatformFlags); + emitter.SetPointerDataCount(model.PointerDataCount); + emitter.SetJsonDescriptor(model.ToJson()); + emitter.Emit(writer); + await writer.FlushAsync(token).ConfigureAwait(false); + return 0; + } + + private static void EnsureDirectoryExists(string outputPath) + { + var directory = System.IO.Path.GetDirectoryName(outputPath); + if (directory == null) + { + return; + } + System.IO.Directory.CreateDirectory(directory); + } +} diff --git a/src/coreclr/tools/cdac-build-tool/ContractDescriptorSourceFileEmitter.cs b/src/coreclr/tools/cdac-build-tool/ContractDescriptorSourceFileEmitter.cs new file mode 100644 index 00000000000000..dde27a6858c6d0 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/ContractDescriptorSourceFileEmitter.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; + +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"; + + + [GeneratedRegex("%%([a-zA-Z0-9_]+)%%", RegexOptions.CultureInvariant)] + private static partial Regex FindTemplatePlaceholderRegex(); + + internal static Stream GetTemplateStream() + { + return typeof(ContractDescriptorSourceFileEmitter).Assembly.GetManifestResourceStream(TemplateResourceName)!; + } + + internal static string GetTemplateString() + { + using var reader = new StreamReader(GetTemplateStream(), System.Text.Encoding.UTF8); + return reader.ReadToEnd(); + } + + public void SetPointerDataCount(int count) + { + Elements[PointerDataCount] = count.ToString(); + } + + public void SetPlatformFlags(uint platformFlags) + { + Elements[PlatformFlags] = $"0x{platformFlags:x8}"; + } + + /// The jsonDescriptor should not be C escaped + public void SetJsonDescriptor(string jsonDescriptor) + { + var count = jsonDescriptor.Length; // return the length before escaping + var escaped = CStringEscape().Replace(jsonDescriptor, "\\$1"); + Elements[JsonDescriptorKey] = escaped; + Elements[JsonDescriptorSizeKey] = count.ToString(); + } + + [GeneratedRegex("(\")", RegexOptions.CultureInvariant)] + private static partial Regex CStringEscape(); + + public Dictionary Elements { get; } = new(); + + public void Emit(TextWriter dest) + { + var template = GetTemplateString(); + var matches = FindTemplatePlaceholderRegex().Matches(template); + var prevPos = 0; + foreach (Match match in matches) + { + // copy everything from the end of the last match (prevPos) to just before the current match to the output + dest.Write(template.AsSpan(prevPos, match.Index - prevPos)); + + // lookup the capture key and write it out + + var key = match.Groups[1].Captures[0].Value; + if (!Elements.TryGetValue(key, out string? result)) + { + throw new InvalidOperationException ($"no replacement for {key}"); + } + dest.Write(result); + prevPos = match.Index + match.Length; + } + // write everything from the prevPos to the end of the template + dest.Write(template.AsSpan(prevPos)); + } +} diff --git a/src/coreclr/tools/cdac-build-tool/ContractReader.cs b/src/coreclr/tools/cdac-build-tool/ContractReader.cs new file mode 100644 index 00000000000000..3bd8ec0c77e7f5 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/ContractReader.cs @@ -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; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +public class ContractReader +{ + private readonly DataDescriptorModel.Builder _builder; + + private static readonly JsonSerializerOptions s_jsonSerializerOptions = new() { PropertyNameCaseInsensitive = false, ReadCommentHandling = JsonCommentHandling.Skip }; + + public ContractReader(DataDescriptorModel.Builder builder) + { + _builder = builder; + } + + public async Task ParseContracts(string contractFilePath, CancellationToken token = default) + { + string? contents = await File.ReadAllTextAsync(contractFilePath, token).ConfigureAwait(false); + var contracts = JsonSerializer.Deserialize>(contents, s_jsonSerializerOptions); + if (contracts is null) + return false; + _builder.AddOrupdateContracts(contracts); + return true; + } +} diff --git a/src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs b/src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs new file mode 100644 index 00000000000000..3abeb5c56e83ce --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/DataDescriptorModel.cs @@ -0,0 +1,389 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.DotNet.Diagnostics.DataContract.JsonConverter; + +namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +public class DataDescriptorModel +{ + public int Version => 0; + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string Baseline { get; } + public IReadOnlyDictionary Types { get; } + public IReadOnlyDictionary Globals { get; } + public IReadOnlyDictionary Contracts { get; } + [JsonIgnore] + public uint PlatformFlags { get; } + // The number of indirect globals plus 1 for the placeholder at index 0 + [JsonIgnore] + public int PointerDataCount => 1 + Globals.Values.Count(g => g.Value.Indirect); + + private DataDescriptorModel(string baseline, IReadOnlyDictionary types, IReadOnlyDictionary globals, IReadOnlyDictionary contracts, uint platformFlags) + { + Baseline = baseline; + Types = types; + Globals = globals; + Contracts = contracts; + PlatformFlags = platformFlags; + } + + public const string PointerTypeName = "pointer"; + + internal void DumpModel() + { + Console.WriteLine("\nData Descriptor Model:"); + Console.WriteLine($"Platform Flags: 0x{PlatformFlags:x8}"); + Console.WriteLine($"Baseline: {Baseline}"); + foreach (var (typeName, type) in Types) + { + Console.WriteLine($"Type: {typeName}"); + if (type.Size != null) + { + Console.WriteLine($" Size: 0x{type.Size:x8}"); + } + foreach (var (fieldName, field) in type.Fields) + { + Console.WriteLine($" Field: {fieldName}"); + Console.WriteLine($" Type: {field.Type}"); + Console.WriteLine($" Offset: 0x{field.Offset:x8}"); + } + } + foreach (var (globalName, global) in Globals) + { + Console.WriteLine($"Global: {globalName}"); + Console.WriteLine($" Type: {global.Type}"); + Console.WriteLine($" Value: {global.Value}"); + } + foreach (var (contractName, contract) in Contracts) + { + Console.WriteLine($"Contract: {contractName}"); + Console.WriteLine($" Version: {contract}"); + } + } + + private static JsonSerializerOptions s_jsonSerializerOptions = new JsonSerializerOptions + { + WriteIndented = false, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DictionaryKeyPolicy = null, // leave unchanged + }; + public string ToJson() + { + // always writes the "compact" format, see data_descriptor.md + return JsonSerializer.Serialize(this, s_jsonSerializerOptions); + } + + public class Builder + { + private string _baseline; + private bool _baselineParsed; + private readonly Dictionary _types = new(); + private readonly Dictionary _globals = new(); + private readonly Dictionary _contracts = new(); + public Builder() + { + _baseline = string.Empty; + _baselineParsed = false; + } + + public uint PlatformFlags {get; set;} + + public TypeModelBuilder AddOrUpdateType(string name, int? size) + { + if (!_baselineParsed) + { + throw new InvalidOperationException("Baseline must be set before adding types"); + } + if (!_types.TryGetValue(name, out var type)) + { + type = new TypeModelBuilder(); + _types[name] = type; + } + type.Size = size; + return type; + } + + public GlobalBuilder AddOrUpdateGlobal(string name, string type, GlobalValue? value) + { + if (!_baselineParsed) + { + throw new InvalidOperationException("Baseline must be set before adding globals"); + } + if (!_globals.TryGetValue(name, out var global)) + { + global = new GlobalBuilder(); + _globals[name] = global; + } + global.Type = type; + global.Value = value; + return global; + } + + public void AddOrUpdateContract(string name, int version) + { + if (!_contracts.TryGetValue(name, out var contract)) + { + contract = new ContractBuilder(); + _contracts[name] = contract; + } + contract.Version = version; + } + + public void AddOrupdateContracts(IEnumerable> contracts) + { + foreach (var (name, version) in contracts) + { + AddOrUpdateContract(name, version); + } + } + + public void SetBaseline(string baseline) + { + if (_baseline != string.Empty && _baseline != baseline) + { + throw new InvalidOperationException($"Baseline already set to {_baseline} cannot set to {baseline}"); + } + if (EmbeddedBaselines.BaselineNames.Contains(baseline)) + { + _baseline = baseline; + } + else + { + throw new InvalidOperationException($"Baseline '{baseline}' not known"); + } + _baseline = baseline; + if (!_baselineParsed) + { + _baselineParsed = true; // kind of a hack - set it before parsing the baseline, so we can call AddOrUpdateType + ParseBaseline(); + } + } + + private void ParseBaseline() + { + if (_baseline != "empty") + { + throw new InvalidOperationException("TODO: [cdac] - implement baseline parsing"); + } + } + + public DataDescriptorModel Build() + { + var types = new Dictionary(); + foreach (var (typeName, typeBuilder) in _types) + { + types[typeName] = typeBuilder.Build(typeName); + } + var globals = new Dictionary(); + foreach (var (globalName, globalBuilder) in _globals) + { + if (globalBuilder.Type == string.Empty) + { + throw new InvalidOperationException($"Type must be set for global {globalName}"); + } + GlobalValue? v = globalBuilder.Value; + if (v == null) + { + throw new InvalidOperationException($"Value must be set for global {globalName}"); + } + globals[globalName] = new GlobalModel { Type = globalBuilder.Type, Value = v.Value }; + } + var contracts = new Dictionary(); + foreach (var (contractName, contractBuilder) in _contracts) + { + contracts[contractName] = contractBuilder.Build(); + } + return new DataDescriptorModel(_baseline, types, globals, contracts, PlatformFlags); + } + } + + public class TypeModelBuilder + { + private readonly Dictionary _fields = new(); + private int? _size; + public TypeModelBuilder() { } + + public int? Size + { + get => _size; + set + { + if (_size != null && (value == null || _size != (int)value)) + { + throw new InvalidOperationException($"Size already set to {_size} cannot set to {value}"); + } + _size = value; + } + } + + public void AddOrUpdateField(string name, string type, int? offset) + { + if (!_fields.TryGetValue(name, out var field)) + { + field = new FieldBuilder(); + _fields[name] = field; + } + field.Type = type; + field.Offset = offset; + } + + public TypeModel Build(string typeName) + { + var fields = new Dictionary(); + foreach (var (fieldName, fieldBuilder) in _fields) + { + fields.Add(fieldName, fieldBuilder.Build(typeName, fieldName)); + } + return new TypeModel { Size = _size, Fields = fields }; + } + } + + public class GlobalBuilder + { + private string _type = string.Empty; + private GlobalValue? _value; + public string Type + { + get => _type; + set + { + if (_type != string.Empty && _type != value) + { + throw new InvalidOperationException($"Type already set to {_type} cannot set to {value}"); + } + _type = value; + } + } + public GlobalValue? Value + { + get => _value; + set + { + if (_value != null && _value != value) + { + throw new InvalidOperationException($"Value already set to {_value} cannot set to {value}"); + } + _value = value; + } + } + } + internal sealed class FieldBuilder + { + private string _type = string.Empty; + private int? _offset; + public string Type + { + get => _type; + set + { + if (_type != string.Empty && _type != value) + { + throw new InvalidOperationException($"Type already set to {_type} cannot set to {value}"); + } + _type = value; + } + } + + public int? Offset + { + get => _offset; + set + { + if (_offset != null && (value == null || _offset != (int)value)) + { + throw new InvalidOperationException($"Offset already set to {_offset} cannot set to {value}"); + } + _offset = value; + } + } + + public FieldModel Build(string typeName, string fieldName) + { + if (_offset == null) + { + throw new InvalidOperationException($"Offset must be set for {typeName}.{fieldName}"); + } + return new FieldModel { Type = _type, Offset = (int)_offset }; + } + } + + [JsonConverter(typeof(FieldModelJsonConverter))] + public readonly struct FieldModel + { + public string Type { get; init; } + public int Offset { get; init; } + } + + [JsonConverter(typeof(TypeModelJsonConverter))] + public readonly struct TypeModel + { + public int? Size { get; init; } + public IReadOnlyDictionary Fields { get; init; } + } + + [JsonConverter(typeof(GlobalValueJsonConverter))] + public readonly struct GlobalValue : IEquatable + { + public bool Indirect { get; private init; } + public ulong Value { get; } + public static GlobalValue MakeDirect(ulong value) => new GlobalValue(value); + public static GlobalValue MakeIndirect(uint auxDataIdx) => new GlobalValue((ulong)auxDataIdx) { Indirect = true }; + private GlobalValue(ulong value) { Value = value; } + + public static bool operator ==(GlobalValue left, GlobalValue right) => left.Value == right.Value && left.Indirect == right.Indirect; + public static bool operator !=(GlobalValue left, GlobalValue right) => !(left == right); + + public bool Equals(GlobalValue other) => this == other; + public override bool Equals(object? obj) => obj is GlobalValue value && this == value; + public override int GetHashCode() => HashCode.Combine(Value, Indirect); + public override string ToString() => Indirect ? $"Indirect({Value})" : $"0x{Value:x}"; + } + + [JsonConverter(typeof(GlobalModelJsonConverter))] + public readonly struct GlobalModel + { + public string Type { get; init; } + public GlobalValue Value { get; init; } + } + + public class ContractBuilder + { + private int? _version; + public ContractBuilder() + { + } + + public int? Version + { + get => _version; + set + { + if (_version != null && _version != value) + { + throw new InvalidOperationException($"Version already set to {_version} cannot set to {value}"); + } + _version = value; + } + } + + // There is no ContractModel right now because the only info we keep is the version. + // As a result it is convenient to use a Dictionary for the contracts since + // the JSON serialization coincides with what we want. + public int Build() + { + if (_version == null) + { + throw new InvalidOperationException("Version must be set for contract"); + } + return _version.Value; + } + } +} diff --git a/src/coreclr/tools/cdac-build-tool/Directory.Build.props b/src/coreclr/tools/cdac-build-tool/Directory.Build.props new file mode 100644 index 00000000000000..465a55954dfea4 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/Directory.Build.props @@ -0,0 +1,7 @@ + + + + <_RequiresLiveILLink>false + + + diff --git a/src/coreclr/tools/cdac-build-tool/EmbeddedBaselines.cs b/src/coreclr/tools/cdac-build-tool/EmbeddedBaselines.cs new file mode 100644 index 00000000000000..ac9cea8b6615ea --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/EmbeddedBaselines.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; + +namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +public partial class EmbeddedBaselines +{ + public const string TemplateResourceNamePrefix = "Microsoft.DotNet.Diagnostics.DataContract.Baseline:"; + public const string TemplateResourceNameEscapePrefix = @"Microsoft\.DotNet\.Diagnostics\.DataContract\.Baseline:"; + public const string TemplateResourceNameExt = ".jsonc"; + public const string TemplateResourceNameEscapeExt = @"\.jsonc"; + + [GeneratedRegex("^" + TemplateResourceNameEscapePrefix + "(.+)" + TemplateResourceNameEscapeExt + "$", RegexOptions.CultureInvariant)] + private static partial Regex BaselineRegex(); + + private static string[] GetBaselineNames() + { + var assembly = typeof(EmbeddedBaselines).Assembly; + var resources = assembly.GetManifestResourceNames(); + var baselineNames = new List(); + foreach (var resource in resources) + { + var match = BaselineRegex().Match(resource); + if (match.Success) + { + baselineNames.Add(match.Groups[1].Value); + } + } + return baselineNames.ToArray(); + } + + private static readonly Lazy> _baselineNames = new(GetBaselineNames); + public static IReadOnlyList BaselineNames => _baselineNames.Value; + + public static string GetBaselineContent(string name) + { + var assembly = typeof(EmbeddedBaselines).Assembly; + var resourceName = TemplateResourceNamePrefix + name + TemplateResourceNameExt; + using var stream = assembly.GetManifestResourceStream(resourceName); + if (stream == null) + { + throw new InvalidOperationException($"Baseline '{name}' not found"); + } + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } +} diff --git a/src/coreclr/tools/cdac-build-tool/JsonConverter/FieldModelJsonConverter.cs b/src/coreclr/tools/cdac-build-tool/JsonConverter/FieldModelJsonConverter.cs new file mode 100644 index 00000000000000..5b6631af52a0eb --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/JsonConverter/FieldModelJsonConverter.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +namespace Microsoft.DotNet.Diagnostics.DataContract.JsonConverter; + +/// +/// Writes a FieldModel in the compact form of [offset, type] or just offset if type is null. +/// . +/// +public class FieldModelJsonConverter : JsonConverter +{ + public override DataDescriptorModel.FieldModel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, DataDescriptorModel.FieldModel value, JsonSerializerOptions options) + { + if (value.Type is null) + { + writer.WriteNumberValue(value.Offset); + } + else + { + writer.WriteStartArray(); + writer.WriteNumberValue(value.Offset); + writer.WriteStringValue(value.Type); + writer.WriteEndArray(); + } + } +} diff --git a/src/coreclr/tools/cdac-build-tool/JsonConverter/GlobalModelJsonConverter.cs b/src/coreclr/tools/cdac-build-tool/JsonConverter/GlobalModelJsonConverter.cs new file mode 100644 index 00000000000000..cae54edb6ff104 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/JsonConverter/GlobalModelJsonConverter.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +namespace Microsoft.DotNet.Diagnostics.DataContract.JsonConverter; +public class GlobalModelJsonConverter : JsonConverter +{ + public override DataDescriptorModel.GlobalModel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, DataDescriptorModel.GlobalModel value, JsonSerializerOptions options) + { + if (value.Type is null) + { + // no type: just write 'value' or '[value]' + JsonSerializer.Serialize(writer, value.Value, options); + } + else + { + // there's a type. Write: [value, type] or [[value], type] + writer.WriteStartArray(); + JsonSerializer.Serialize(writer, value.Value, options); + writer.WriteStringValue(value.Type); + writer.WriteEndArray(); + } + } +} diff --git a/src/coreclr/tools/cdac-build-tool/JsonConverter/GlobalValueJsonConverter.cs b/src/coreclr/tools/cdac-build-tool/JsonConverter/GlobalValueJsonConverter.cs new file mode 100644 index 00000000000000..429f6cc6979284 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/JsonConverter/GlobalValueJsonConverter.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +namespace Microsoft.DotNet.Diagnostics.DataContract.JsonConverter; +public class GlobalValueJsonConverter : JsonConverter +{ + public override DataDescriptorModel.GlobalValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, DataDescriptorModel.GlobalValue value, JsonSerializerOptions options) + { + if (!value.Indirect) + { + // no type: just write value as a number. + // we always write as a string containing a hex number + writer.WriteStringValue($"0x{value.Value:x}"); + } + else + { + // pointer data index. write as a 1-element array containing a decimal number + writer.WriteStartArray(); + writer.WriteNumberValue(value.Value); + writer.WriteEndArray(); + } + } +} diff --git a/src/coreclr/tools/cdac-build-tool/JsonConverter/TypeModelJsonConverter.cs b/src/coreclr/tools/cdac-build-tool/JsonConverter/TypeModelJsonConverter.cs new file mode 100644 index 00000000000000..bf400253d5ddfe --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/JsonConverter/TypeModelJsonConverter.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +namespace Microsoft.DotNet.Diagnostics.DataContract.JsonConverter; +public class TypeModelJsonConverter : JsonConverter +{ + public const string SizePropertyname = "!"; + + public override DataDescriptorModel.TypeModel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, DataDescriptorModel.TypeModel value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + if (value.Size is not null) + { + writer.WriteNumber(SizePropertyname, value.Size.Value); + } + foreach (var (fieldName, field) in value.Fields) + { + writer.WritePropertyName(fieldName); + JsonSerializer.Serialize(writer, field, options); + } + writer.WriteEndObject(); + } +} diff --git a/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs b/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs new file mode 100644 index 00000000000000..42b0b004c8980a --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/ObjectFileScraper.cs @@ -0,0 +1,519 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +public class ObjectFileScraper +{ + public static readonly ReadOnlyMemory MagicLE = new byte[8] { 0x44, 0x41, 0x43, 0x42, 0x4C, 0x4F, 0x42, 0x00 }; // "DACBLOB\0" + public static readonly ReadOnlyMemory MagicBE = new byte[8] { 0x00, 0x42, 0x4F, 0x4C, 0x42, 0x43, 0x41, 0x44 }; + + private readonly DataDescriptorModel.Builder _builder; + + public bool Verbose {get;} + public ObjectFileScraper(bool verbose, DataDescriptorModel.Builder builder) + { + Verbose = verbose; + _builder = builder; + } + + public async Task ScrapeInput(string inputPath, CancellationToken token) + { + var bytes = await File.ReadAllBytesAsync(inputPath, token).ConfigureAwait(false); + if (!ScraperState.CreateScraperState(bytes, out var state)) + { + return false; + } + if (Verbose) + { + Console.WriteLine($"Magic starts at 0x{state.MagicStart:x8} in {inputPath}"); + } + var header = ReadHeader(state); + if (Verbose) + { + DumpHeaderDirectory(header); + } + var content = ReadContent(state, header); + content.AddToModel(_builder); + if (Verbose) + { + Console.WriteLine($"\nFinished scraping content from {inputPath}"); + } + return true; + } + + private sealed class ScraperState + { + public ReadOnlyMemory Data { get; } + public bool LittleEndian { get; } + private long _position; + + // expect MagicLE and MagicBE to have the same length + public long MagicStart => HeaderStart - MagicLE.Length; + public long HeaderStart { get; } + + private ScraperState(ReadOnlyMemory data, bool isLittleEndian, long headerStart) + { + Data = data; + LittleEndian = isLittleEndian; + HeaderStart = headerStart; + _position = headerStart; + } + + public static bool CreateScraperState(ReadOnlyMemory bytes, [NotNullWhen(true)] out ScraperState? scraperState) + { + if (FindMagic(bytes.Span, out int offset, out bool isLittleEndian)) + { + scraperState = new ScraperState(bytes, isLittleEndian, offset + MagicLE.Length); + return true; + } + scraperState = null; + return false; + } + + private static bool FindMagic(ReadOnlySpan buffer, out int offset, out bool isLittleEndian) + { + int start = buffer.IndexOf(MagicLE.Span); + if (start != -1) + { + offset = start; + isLittleEndian = true; + return true; + } + start = buffer.IndexOf(MagicBE.Span); + if (start != -1) + { + offset = start; + isLittleEndian = false; + return true; + } + offset = 0; + isLittleEndian = false; + return false; + } + + public ulong GetUInt64(long offset) => LittleEndian ? BinaryPrimitives.ReadUInt64LittleEndian(Data.Span.Slice((int)offset)) : BinaryPrimitives.ReadUInt64BigEndian(Data.Span.Slice((int)offset)); + public uint GetUInt32(long offset) => LittleEndian ? BinaryPrimitives.ReadUInt32LittleEndian(Data.Span.Slice((int)offset)) : BinaryPrimitives.ReadUInt32BigEndian(Data.Span.Slice((int)offset)); + public ushort GetUInt16(long offset) => LittleEndian ? BinaryPrimitives.ReadUInt16LittleEndian(Data.Span.Slice((int)offset)) : BinaryPrimitives.ReadUInt16BigEndian(Data.Span.Slice((int)offset)); + public byte GetByte(long offset) => Data.Span[(int)offset]; + + public ReadOnlySpan GetBytes(long offset, int length) => Data.Span.Slice((int)offset, length); + + public void ResetPosition(long position) + { + _position = position; + } + + public ulong ReadUInt64() + { + var value = GetUInt64(_position); + _position += sizeof(ulong); + return value; + } + public uint ReadUInt32() + { + var value = GetUInt32(_position); + _position += sizeof(uint); + return value; + } + public ushort ReadUInt16() + { + var value = GetUInt16(_position); + _position += sizeof(ushort); + return value; + } + + public byte ReadByte() + { + var value = GetByte(_position); + _position += sizeof(byte); + return value; + } + public void ReadBytes(Span buffer) + { + GetBytes(_position, buffer.Length).CopyTo(buffer); + _position += buffer.Length; + } + + public void Skip(int count) + { + _position += count; + } + } + + // see typedef Directory in data-descriptor-blob.md + private struct HeaderDirectory + { + public uint FlagsAndBaselineStart; + public uint TypesStart; + + public uint FieldsPoolStart; + public uint GlobalLiteralValuesStart; + + public uint GlobalPointersStart; + public uint NamesStart; + + public uint TypesCount; + public uint FieldsPoolCount; + + public uint GlobalLiteralValuesCount; + public uint GlobalPointerValuesCount; + + public uint NamesPoolCount; + + public byte TypeSpecSize; + public byte FieldSpecSize; + public byte GlobalLiteralSpecSize; + public byte GlobalPointerSpecSize; + }; + + private static void DumpHeaderDirectory(HeaderDirectory headerDirectory) + { + Console.WriteLine($""" + Scaped Header Directory: + + Baseline Start = 0x{headerDirectory.FlagsAndBaselineStart:x8} + Types Start = 0x{headerDirectory.TypesStart:x8} + Fields Pool Start = 0x{headerDirectory.FieldsPoolStart:x8} + Global Literals Start = 0x{headerDirectory.GlobalLiteralValuesStart:x8} + Global Pointers Start = 0x{headerDirectory.GlobalPointersStart:x8} + Names Pool Start = 0x{headerDirectory.NamesStart:x8} + + Types Count = {headerDirectory.TypesCount} + Fields Pool Count = {headerDirectory.FieldsPoolCount} + Global Literal Values Count = {headerDirectory.GlobalLiteralValuesCount} + Global Pointer Values Count = {headerDirectory.GlobalPointerValuesCount} + Names Pool Count = {headerDirectory.NamesPoolCount} + + """); + } + + private static HeaderDirectory ReadHeader(ScraperState state) + { + state.ResetPosition(state.HeaderStart); + var baselineStart = state.ReadUInt32(); + var typesStart = state.ReadUInt32(); + + var fieldPoolStart = state.ReadUInt32(); + var globalLiteralValuesStart = state.ReadUInt32(); + + var globalPointersStart = state.ReadUInt32(); + var namesStart = state.ReadUInt32(); + + var typeCount = state.ReadUInt32(); + var fieldPoolCount = state.ReadUInt32(); + + var globalLiteralValuesCount = state.ReadUInt32(); + var globalPointerValuesCount = state.ReadUInt32(); + + var namesPoolCount = state.ReadUInt32(); + + var typeSpecSize = state.ReadByte(); + var fieldSpecSize = state.ReadByte(); + var globalLiteralSpecSize = state.ReadByte(); + var globalPointerSpecSize = state.ReadByte(); + + return new HeaderDirectory { + FlagsAndBaselineStart = baselineStart, + TypesStart = typesStart, + FieldsPoolStart = fieldPoolStart, + GlobalLiteralValuesStart = globalLiteralValuesStart, + GlobalPointersStart = globalPointersStart, + NamesStart = namesStart, + + TypesCount = typeCount, + FieldsPoolCount = fieldPoolCount, + + GlobalLiteralValuesCount = globalLiteralValuesCount, + GlobalPointerValuesCount = globalPointerValuesCount, + + NamesPoolCount = namesPoolCount, + + TypeSpecSize = typeSpecSize, + FieldSpecSize = fieldSpecSize, + GlobalLiteralSpecSize = globalLiteralSpecSize, + GlobalPointerSpecSize = globalPointerSpecSize, + }; + } + + private struct TypeSpec + { + public uint NameIdx; + public uint FieldsIdx; + public ushort? Size; + } + + private struct FieldSpec + { + public uint NameIdx; + public uint TypeNameIdx; + public ushort FieldOffset; + } + + // Like a FieldSpec but with names resolved + private struct FieldEntry + { + public string Name; + public string Type; + public ushort Offset; + } + + private struct GlobalLiteralSpec + { + public uint NameIdx; + public uint TypeNameIdx; + public ulong Value; + } + + private struct GlobalPointerSpec + { + public uint NameIdx; + public uint AuxDataIdx; + } + + private sealed class Content + { + public required bool Verbose {get; init; } + public required uint PlatformFlags { get; init; } + public required uint Baseline { get; init; } + public required IReadOnlyList TypeSpecs { get; init; } + public required IReadOnlyList FieldSpecs { get; init; } + public required IReadOnlyList GlobaLiteralSpecs { get; init; } + public required IReadOnlyList GlobalPointerSpecs { get; init; } + public required ReadOnlyMemory NamesPool { get; init; } + + internal string GetPoolString(uint stringIdx) + { + var nameStart = NamesPool.Span.Slice((int)stringIdx); + var end = nameStart.IndexOf((byte)0); // find the first nul after index + if (end == -1) + throw new InvalidOperationException("expected a nul-terminated name"); + var nameBytes = nameStart.Slice(0, end); + return System.Text.Encoding.UTF8.GetString(nameBytes); + } + + public void AddToModel(DataDescriptorModel.Builder builder) + { + WriteVerbose("\nAdding scraped content to model"); + builder.PlatformFlags = PlatformFlags; + string baseline = GetPoolString(Baseline); + WriteVerbose($"Baseline Name = {baseline}"); + builder.SetBaseline(baseline); + + + FieldEntry[] fields = FieldSpecs.Select((fieldSpec) => + (fieldSpec.NameIdx != 0) ? + new FieldEntry + { + Name = GetPoolString(fieldSpec.NameIdx), + Type = GetPoolString(fieldSpec.TypeNameIdx), + Offset = fieldSpec.FieldOffset + } : + default + ).ToArray(); + + foreach (var typeSpec in TypeSpecs) + { + string typeName = GetPoolString(typeSpec.NameIdx); + var typeBuilder = builder.AddOrUpdateType(typeName, typeSpec.Size); + uint j = typeSpec.FieldsIdx; // convert byte offset to index; + WriteVerbose($"Type {typeName} has fields starting at index {j}"); + while (j < fields.Length && !string.IsNullOrEmpty(fields[j].Name)) + { + typeBuilder.AddOrUpdateField(fields[j].Name, fields[j].Type, fields[j].Offset); + WriteVerbose($"Type {typeName} has field {fields[j].Name} with offset {fields[j].Offset}"); + j++; + } + if (typeSpec.Size is not null) + { + WriteVerbose($"Type {typeName} has size {typeSpec.Size}"); + } + else + { + WriteVerbose($"Type {typeName} has indeterminate size"); + } + } + + foreach (var globalSpec in GlobaLiteralSpecs) + { + var globalName = GetPoolString(globalSpec.NameIdx); + var globalType = GetPoolString(globalSpec.TypeNameIdx); + var globalValue = DataDescriptorModel.GlobalValue.MakeDirect(globalSpec.Value); + builder.AddOrUpdateGlobal(globalName, globalType, globalValue); + WriteVerbose($"Global {globalName} has type {globalType} with value {globalValue}"); + } + + foreach (var globalPointer in GlobalPointerSpecs) + { + var globalName = GetPoolString(globalPointer.NameIdx); + var auxDataIdx = globalPointer.AuxDataIdx; + var globalValue = DataDescriptorModel.GlobalValue.MakeIndirect(auxDataIdx); + builder.AddOrUpdateGlobal(globalName, DataDescriptorModel.PointerTypeName, globalValue); + WriteVerbose($"Global pointer {globalName} has index {globalValue}"); + } + } + + private void WriteVerbose(string msg) + { + if (Verbose) + Console.WriteLine(msg); + } + } + + private Content ReadContent(ScraperState state, HeaderDirectory header) + { + WriteVerbose("\nReading scraped content"); + state.ResetPosition(state.HeaderStart + header.FlagsAndBaselineStart); + var platformFlags = state.ReadUInt32(); + var baselineNameIdx = state.ReadUInt32(); + WriteVerbose($"flags = 0x{platformFlags:x8}, baseline Name Idx = {baselineNameIdx}"); + + TypeSpec[] typeSpecs = ReadTypeSpecs(state, header); + FieldSpec[] fieldSpecs = ReadFieldSpecs(state, header); + GlobalLiteralSpec[] globalLiteralSpecs = ReadGlobalLiteralSpecs(state, header); + GlobalPointerSpec[] globalPointerSpecs = ReadGlobalPointerSpecs(state, header); + byte[] namesPool = ReadNamesPool(state, header); + + byte[] endMagic = new byte[4]; + state.ReadBytes(endMagic.AsSpan()); + if (!CheckEndMagic(endMagic)) + { + throw new InvalidOperationException($"expected endMagic, got 0x{endMagic[0]:x} 0x{endMagic[1]:x} 0x{endMagic[2]:x} 0x{endMagic[3]:x}"); + } + else + { + WriteVerbose("\nFound correct endMagic at end of content"); + } + return new Content + { + Verbose = Verbose, + PlatformFlags = platformFlags, + Baseline = baselineNameIdx, + TypeSpecs = typeSpecs, + FieldSpecs = fieldSpecs, + GlobaLiteralSpecs = globalLiteralSpecs, + GlobalPointerSpecs = globalPointerSpecs, + NamesPool = namesPool + }; + } + + private TypeSpec[] ReadTypeSpecs(ScraperState state, HeaderDirectory header) + { + TypeSpec[] typeSpecs = new TypeSpec[header.TypesCount]; + + state.ResetPosition(state.HeaderStart + (long)header.TypesStart); + for (int i = 0; i < header.TypesCount; i++) + { + int bytesRead = 0; + typeSpecs[i].NameIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + typeSpecs[i].FieldsIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + ushort size = state.ReadUInt16(); + bytesRead += sizeof(ushort); + if (size != 0) + { + typeSpecs[i].Size = size; + } + WriteVerbose($"TypeSpec[{i}]: NameIdx = {typeSpecs[i].NameIdx}, FieldsIdx = {typeSpecs[i].FieldsIdx}, Size = {typeSpecs[i].Size}"); + // skip padding + if (bytesRead < header.TypeSpecSize) + { + state.Skip(header.TypeSpecSize - bytesRead); + } + } + return typeSpecs; + } + + private static FieldSpec[] ReadFieldSpecs(ScraperState state, HeaderDirectory header) + { + state.ResetPosition(state.HeaderStart + (long)header.FieldsPoolStart); + FieldSpec[] fieldSpecs = new FieldSpec[header.FieldsPoolCount]; + for (int i = 0; i < header.FieldsPoolCount; i++) + { + int bytesRead = 0; + fieldSpecs[i].NameIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + fieldSpecs[i].TypeNameIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + fieldSpecs[i].FieldOffset = state.ReadUInt16(); + bytesRead += sizeof(ushort); + // skip padding + if (bytesRead < header.FieldSpecSize) + { + state.Skip(header.FieldSpecSize - bytesRead); + } + } + return fieldSpecs; + } + + private static GlobalLiteralSpec[] ReadGlobalLiteralSpecs(ScraperState state, HeaderDirectory header) + { + GlobalLiteralSpec[] globalSpecs = new GlobalLiteralSpec[header.GlobalLiteralValuesCount]; + state.ResetPosition(state.HeaderStart + (long)header.GlobalLiteralValuesStart); + for (int i = 0; i < header.GlobalLiteralValuesCount; i++) + { + int bytesRead = 0; + globalSpecs[i].NameIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + globalSpecs[i].TypeNameIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + globalSpecs[i].Value = state.ReadUInt64(); + bytesRead += sizeof(ulong); + // skip padding + if (bytesRead < header.GlobalLiteralSpecSize) + { + state.Skip(header.GlobalLiteralSpecSize - bytesRead); + } + } + return globalSpecs; + } + + private static GlobalPointerSpec[] ReadGlobalPointerSpecs(ScraperState state, HeaderDirectory header) + { + GlobalPointerSpec[] globalSpecs = new GlobalPointerSpec[header.GlobalPointerValuesCount]; + state.ResetPosition(state.HeaderStart + (long)header.GlobalPointersStart); + for (int i = 0; i < header.GlobalPointerValuesCount; i++) + { + int bytesRead = 0; + globalSpecs[i].NameIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + globalSpecs[i].AuxDataIdx = state.ReadUInt32(); + bytesRead += sizeof(uint); + // skip padding + if (bytesRead < header.GlobalPointerSpecSize) + { + state.Skip(header.GlobalPointerSpecSize - bytesRead); + } + } + return globalSpecs; + } + + private static byte[] ReadNamesPool(ScraperState state, HeaderDirectory header) + { + byte[] namesPool = new byte[header.NamesPoolCount]; + state.ResetPosition(state.HeaderStart + (long)header.NamesStart); + state.ReadBytes(namesPool.AsSpan()); + return namesPool; + } + + private static bool CheckEndMagic(ReadOnlySpan bytes) + { + return (bytes[0] == 0x01 && bytes[1] == 0x02 && bytes[2] == 0x03 && bytes[3] == 0x04); + } + + private void WriteVerbose(string msg) + { + if (Verbose) + Console.WriteLine(msg); + } +} diff --git a/src/coreclr/tools/cdac-build-tool/Program.cs b/src/coreclr/tools/cdac-build-tool/Program.cs new file mode 100644 index 00000000000000..132c13d30fa119 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/Program.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.CommandLine; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Diagnostics.DataContract.BuildTool; + +public class Program +{ + public static async Task Main(string[] args) + { + CliRootCommand rootCommand = new (); + var verboseOption = new CliOption("-v", "--verbose") {Recursive = true, Description = "Verbose"}; + rootCommand.Add(verboseOption); + rootCommand.Add(new DiagramDirective()); + rootCommand.Add(new ComposeCommand(verboseOption)); + return await rootCommand.Parse(args).InvokeAsync().ConfigureAwait(true); + } +} diff --git a/src/coreclr/tools/cdac-build-tool/README.md b/src/coreclr/tools/cdac-build-tool/README.md new file mode 100644 index 00000000000000..512026a29860b9 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/README.md @@ -0,0 +1,134 @@ +# cDAC Build Tool + +## Summary + +The purpose of `cdac-build-tool` is to generate a `.c` file that contains a JSON cDAC contract descriptor. + +It works by processing one or more object files containing data descriptors and zero or more text +files that specify contracts. + +## Running + +```console +% cdac-build-tool compose [-v] -o contractdescriptor.c -c contracts.txt datadescriptor.o +``` +## .NET runtime build integration + +`cdac-build-tool` is meant to run as a CMake custom command. +It consumes a target platform object file and emits a C source +file that contains a JSON contract descriptor. The C source +is then included in the normal build and link steps to create the runtime. + +The contract descriptor source file depends on `contractpointerdata.c` which is a source file that contains +the definitions of the "indirect pointer data" that is referenced by the data descriptor. This is typically the addresses of important global variables in the runtime. +Constants and build flags are embedded directly in the JSON payload. + +Multiple data descriptor source files may be specified (for example if they are produced by different components of the runtime, or by different source languages). The final JSON payload will be a composition of all the data descriptors. + +Multiple contracts text files may be specified. This may be useful if some contracts are conditionally included (for example if they are platform-specific). The final JSON payload will be a composition of all the contracts files. + +In the C/C++ data descriptor, we use a single header file `datadescriptor.h` together with the C preprocessor to produce `datadescriptor.c` and `contractpointerdata.c`. +This is an implementation detail. For data structures defined in other languages, other tools can be used to produce the object file and indirect pointer data. + +```mermaid +flowchart TB + headers("runtime headers") + data_header("datadescriptor.h") + data_src("datadescriptor.c") + compile_data["clang"] + data_obj("datadescriptor.o") + contracts("contracts.txt") + globals("contractpointerdata.c") + build[["cdac-build-tool"]] + descriptor_src("contractdescriptor.c") + vm("runtime sources") + compile_runtime["clang"] + runtime_lib(["libcoreclr.so"]) + + headers -.-> data_src + headers ~~~ data_header + data_header -.-> data_src + headers -.-> globals + headers -.-> vm + data_src --> compile_data --> data_obj --> build + contracts ---> build + build --> descriptor_src + descriptor_src --> compile_runtime + data_header -.-> globals ----> compile_runtime + vm ----> compile_runtime --> runtime_lib +``` + + +## Specifying data descriptors + +The sample in the `sample` dir uses the following syntax (see [sample/sample.data.h](sample/sample.data.h)) to specify the data descriptor: + +```c +CDAC_BASELINE("empty") +CDAC_TYPES_BEGIN() + +CDAC_TYPE_BEGIN(ManagedThread) +CDAC_TYPE_INDETERMINATE(ManagedThread) +CDAC_TYPE_FIELD(ManagedThread, GCHandle, GCHandle, offsetof(ManagedThread,m_gcHandle)) +CDAC_TYPE_FIELD(ManagedThread, pointer, Next, offsetof(ManagedThread,m_next)) +CDAC_TYPE_END(ManagedThread) + +CDAC_TYPE_BEGIN(GCHandle) +CDAC_TYPE_SIZE(sizeof(intptr_t)) +CDAC_TYPE_END(GCHandle) + +CDAC_TYPES_END() + +CDAC_GLOBALS_BEGIN() +CDAC_GLOBAL_POINTER(ManagedThreadStore, &g_managedThreadStore) +#if FEATURE_EH_FUNCLETS +CDAC_GLOBAL(FeatureEHFunclets, uint8, 1) +#else +CDAC_GLOBAL(FeatureEHFunclets, uint8, 0) +#endif +CDAC_GLOBAL(SomeMagicNumber, uint32, 42) +CDAC_GLOBALS_END() +``` + +The file is included multiple times with the macros variously defined in order to generate the +data descriptor blob. + +## Implementation Details + +See [data-descriptor-blob.md](./data-descriptor-blob.md) + +## Workflow + +### Porting and extending the data blob scraper + +When porting to a new architecture, or extending the blob contents, it is recommended to +first work with the sample blob, rather than the full CoreCLR descriptor. + +For example, if your target platform has a clang toolchain, something like this will provide a suitable +input for `cdac-build-tool`: + +```console +$ clang -target wasm32-unknown-unknown -c -o /tmp/sample.o src/coreclr/tools/cdac-build-tool/sample/sample.blob.c +``` + +If you are modifying the preprocessor macros, using `-E` to emit the preprocessed output is helpful as well. + +```console +$ clang -target x86_64-unknown-linux-gnu -E -o /tmp/sample.i .src/coreclr/tools/cdac-build-tool/sample/sample.blob.c +``` + +Running the `cdac-build-tool` with the `-v` verbose option will show progress + +```console +$ ./dotnet.sh run --project src/coreclr/tools/cdac-build-tool/cdac-build-tool.csproj -- compose -v -o /tmp/contract.c /tmp/sample.o +``` + +It is also helpful to run the `cdac-build-tool` under a debugger with a breakpoint in `ObjectFileScraper.ScrapeInput` + +**Release runtime builds** When building Release builds of the runtime, the build infrastructure +may turn on whole program optimizations. On some toolchains this may produce object files that +are a serialization of the internal compiler state, rather than a native object format. This may break +assumptions of the `cdac-build-tool` about global symbol initialization, for example constants and string literals might not be stored as binary integers or as byte sequences. In such cases, it may be +necessary to turn off global optimizations when compiling `datadescriptor.cpp`. This is okay to do because `datadescriptor.cpp` is not shipped as part of the runtime build - and in fact it has no executable functions at all. It is just used to gather type layout and size information. + +It is conceivable that some future C/C++ compiler with whole program optimizations turned on may remove unused struct fields. (Such that separately compiling `datadescriptor.cpp` would produce incorrect offsets). In that case, `cdac-build-tool` will need to use another technique to collect offsets for a runtime built with such a compiler. As of 2024, no compilers do this, however. diff --git a/src/coreclr/tools/cdac-build-tool/Resources/contract-descriptor.c.in b/src/coreclr/tools/cdac-build-tool/Resources/contract-descriptor.c.in new file mode 100644 index 00000000000000..c1f0edd7a66f9c --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/Resources/contract-descriptor.c.in @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include + +#ifdef _MSC_VER +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT __attribute__((visibility("default"))) +#endif + +struct DotNetRuntimeContractDescriptor +{ + uint64_t magic; + uint32_t flags; + const uint32_t descriptor_size; + const char *descriptor; + const uint32_t pointer_data_count; + uint32_t pad0; + const uintptr_t *pointer_data; +}; + +extern const uintptr_t contractDescriptorPointerData[]; + +DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor; + +DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor = { + .magic = 0x0043414443434e44ull, // "DNCCDAC\0" + .flags = %%platformFlags%%, + .descriptor_size = %%jsonDescriptorSize%%, + .descriptor = "%%jsonDescriptor%%", + .pointer_data_count = %%pointerDataCount%%, + .pointer_data = &contractDescriptorPointerData[0], +}; diff --git a/src/coreclr/tools/cdac-build-tool/cdac-build-tool.csproj b/src/coreclr/tools/cdac-build-tool/cdac-build-tool.csproj new file mode 100644 index 00000000000000..427a1eb4e9c91d --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/cdac-build-tool.csproj @@ -0,0 +1,32 @@ + + + + cdac-build-tool + Exe + enable + AnyCPU + $(NetCoreAppToolCurrent) + true + $(RuntimeBinDir)/cdac-build-tool + true + false + false + false + .NET runtime data contract build tool + Microsoft.DotNet.Diagnostics.DataContract + + + + + + + + Microsoft.DotNet.Diagnostics.DataContract.Baseline: + + + + + + + + diff --git a/src/coreclr/tools/cdac-build-tool/data-descriptor-blob.md b/src/coreclr/tools/cdac-build-tool/data-descriptor-blob.md new file mode 100644 index 00000000000000..b7321edd12c991 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/data-descriptor-blob.md @@ -0,0 +1,203 @@ +## On-disk target object binary blob descriptor + +### Summary + +This is an internal implemetnation detail allowing tooling to read target architecture structure sizes and offsets without understanding target architecture object formats. + +### Design requirements + +The design of the physical binary blob descriptor is constrained by the following requirements: +* The binary blob should be easy to process by examining an object file on disk - even if the object + file is for a foreign architecture/OS. It should be possible to read the binary blob purely by + looking at the bytes. Tooling should be able to analyze the blob without having to understand + relocation entries, dwarf debug info, symbols etc. +* It should be possible to produce the blob using the native C/C++/NativeAOT compiler for a given + target/architecture. In particular for a runtime written in C, the binary blob should be + constructible using C idioms. If the C compiler needs to pad or align the data, the blob format + should provide a way to iterate the blob contents without having to know anything about the target + platform ABI or C compiler conventions. +* It should be possible to create separate subsets of the physical descriptor (in the target runtime + object format) using separate toolchains (for example: in NativeAOT some of the struct layouts may + be described by the NativeAOT compiler, while some might be described by the C/C++ toolchain) and + to run a build host (not target architecture) tool to read and compose them into a single physical + binary blob before embedding it into the final NativeAOT runtime binary. + +This leads to the following overall strategy for the design: +* The physical blob is "self-contained": indirections are encoded as offsets from the beginning of + the blob (or other base offsets), whereas using pointers would mean that the encoding of the blob + would have relocations applied to it, which would preclude reading the blob out of of an object + file without understanding the object file format. +* The physical blob must be "self-describing": If the C compiler adds padding or alignment, the blob + descriptor must contain information for how to skip the padding/alignment data. +* The physical blob must be constructible using "lowest common denominator" target toolchain + tooling - the C preprocessor. That doesn't mean that tooling _must_ use the C preprocessor to + generate the blob, but the format must not exceed the capabilities of the C preprocessor. + + +### Blob + +Multi-byte values are in the target platform endianness. + +The blob's job is to encode descriptions of the .NET runtime's implementation types and their fields, +as well as globals. + +When encoding strings, we create a "string pool" in the data blob: a massive string literal +that concatentates all the names that we might need, separated by `"\0"` nul characters. To encode a name into another data structure, we write the offset of the name from the beginning of the string pool. We reserve the offset 0 to designate empty or invalid names. + +When encoding the fields of a type, we create a "field pool" in the data blob: a collection of field +descriptors delimited by an "empty field descriptor" (a field descriptor of a name index of 0). All +the fields for a single type are encoded as a contiguous run from a given field pool index until the next empty field descriptor. + +We're interested in encoding the following kinds of information: + +```c +// A type: +// We encode a data contract name and a collection of fields, and the size of the type. +struct TypeSpec +{ + uint32_t Name; + uint32_t Fields; + uint16_t Size; +}; + +// A field: +// We encode the field name, the type (or an empty name) and the offset of the field in the native +// struct. The size of the field is not part of the data descriptor. +struct FieldSpec +{ + uint32_t Name; + uint32_t TypeName; + uint16_t FieldOffset; +}; + +// A literal global value such as a constant, some flags bitmap, or the value of a preprocessor define: +// we record the name, an optional type name, and a value as an unsigned 64-bit value +struct GlobalLiteralSpec +{ + uint32_t Name; + uint32_t TypeName; + uint64_t Value; +}; + +// A global pointer value such as the addrress of some important datastructure: +// We record the name and the index of the global in the auxiliarly "pointer data" global which +// is compiled into the .NET runtime and contains the addresses of all the globals that are referenced +// from the data descriptor. +struct GlobalPointerSpec +{ + uint32_t Name; + uint32_t PointerDataIndex; +}; +``` + +The main data we want to emit to the object file is an instance of the following structure: + +```c +// The main payload of the object file. +struct BinaryBlobDataDescriptor +{ + // A directory giving the offsets of all the other content, + // the number of types, fields, global literals and pointers, and + // the sizes of the "Spec" structs, above, in order to account for any padding added + // by the C/C++ compiler. + struct Directory { + uint32_t FlagsAndBaselineStart; + uint32_t TypesStart; + + uint32_t FieldPoolStart; + uint32_t GlobalLiteralValuesStart; + + uint32_t GlobalPointersStart; + uint32_t NamesStart; + + uint32_t TypeCount; + uint32_t FieldPoolCount; + + uint32_t GlobalLiteralValuesCount; + uint32_t GlobalPointerValuesCount; + + uint32_t NamesPoolCount; + + uint8_t TypeSpecSize; + uint8_t FieldSpecSize; + uint8_t GlobalLiteralSpecSize; + uint8_t GlobalPointerSpecSize; + } Directory; + // Platform flags (primarily pointer size) + uint32_t PlatformFlags; + // a well-known name of the baseline data descriptor. the current descriptor + // records changes from this baseline. + uint32_t BaselineName; + // an array of type specs + struct TypeSpec Types[CDacBlobTypesCount]; + // all of the field specs - contiguous runs are all owned by the same type + struct FieldSpec FieldPool[CDacBlobFieldPoolCount]; + // an array of literal globals + struct GlobalLiteralSpec GlobalLiteralValues[CDacBlobGlobalLiteralsCount]; + // an array of pointer globals + struct GlobalPointerSpec GlobalPointerValues[CDacBlobGlobalPointersCount]; + // all of the names that might be referenced from elsewhere in BinaryBlobDataDescriptor, + // delimited by "\0" + uint8_t NamesPool[sizeof(struct CDacStringPoolSizes)]; + // an end magic value to validate that the name pool is of the expected length + uint8_t EndMagic[4]; // the bytes 0x01 0x02 0x03 0x04 +}; +``` + +Finally, the value that we write to the object file has this form: + +```c +struct MagicAndBlob { + // the magic value that we look for in the object file + // 0x00424F4C42434144ull - in little endian this is "DACBLOB\0" + uint64_t magic; + // the blob payload, described above + struct BinaryBlobDataDescriptor Blob; +}; +``` + +The `BinaryBlobDataDescriptor` begins with a directory that gives the relative offsets of the `PlatformFlags`, `Types`, `FieldPool`, +`GlobalLiteralValues`, `GlobalPointerValues` and `Names` fields of the blob. The number of elements of each of the arrays is +next. This is followed by the sizes of the spec structs. + +Rationale: If a `BinaryBlobDataDescriptor` is created via C macros, we want to embed the `offsetof` +and `sizeof` of the components of the blob into the blob itself without having to account for any +padding that the C compiler may introduce to enforce alignment. Additionally the `Directory` tries +to follow a common C alignment rule (we don't want padding introduced in the directory itself): +N-byte members are aligned to start on N-byte boundaries. + +The baseline is specified as an offset into the names pool. + +The types are given as an array of `TypeSpec` elements. Each one contains an offset into the +`NamesPool` giving the name of the type, An offset into the fields pool indicating the first +specified field of the type, and the size of the type in bytes or 0 if it is indeterminate. + +The fields pool is given as a sequence of `FieldSpec` elements. The fields for each type are given +in a contiguous subsequence and are terminated by a marker `FieldSpec` with a `Name` offset of 0. +(Thus if a type has an empty sequence of fields it just points to a marker field spec directly.) +For each field there is a name that gives an offset in the name pool and an offset indicating the +field's offset. + +The global constants are given as a sequence of `GlobalLiteralSpec` elements. Each global has a +name, type and a value. Globals that are the addresses in target memory, are in `GlobalPointerSpec` +elements. Each pointer element has a name and an index in a separately compiled pointer structure +that is linked into runtime . See +[contract-descriptor.md](/docs/design/datacontracts/contract-descriptor.md) + +The `NamesPool` is a single sequence of utf-8 bytes comprising the concatenation of all the type +field and global names including a terminating nul byte for each name. The same name may occur +multiple times. The names could be referenced by multiple type or multiple fields. (That is, a +clever blob emitter may pool strings). The first name in the name pool is the empty string (with +its nul byte). + +Rationale: we want to reserve the offset 0 as a marker. + +Names are referenced by giving their offset from the beginning of the `NamesPool`. Each name +extends until the first nul byte encountered at or past the beginning of the name. + + +## Example + +An example C header describing some data types is given in [sample.data.h](./sample/sample.data.h). And +example series of C macro preprocessor definitions that produces a constant blob `Blob` is given in +[sample.blob.c](./sample/sample.blob.c) diff --git a/src/coreclr/tools/cdac-build-tool/sample/sample.blob.c b/src/coreclr/tools/cdac-build-tool/sample/sample.blob.c new file mode 100644 index 00000000000000..b90b7eca0e932a --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/sample/sample.blob.c @@ -0,0 +1,553 @@ +#include +#include + +// example structures + +typedef struct ManagedThread ManagedThread; + +struct ManagedThread { + uint32_t garbage0; + uint32_t m_gcHandle; + uint32_t garbage1; + ManagedThread *m_next; +}; + +typedef struct ManagedThreadStore { + ManagedThread *threads; +} ManagedThreadStore; + +static ManagedThreadStore g_managedThreadStore; + +// end example structures + +// begin blob definition + +struct TypeSpec +{ + uint32_t Name; + uint32_t Fields; + uint16_t Size; +}; + +struct FieldSpec +{ + uint32_t Name; + uint32_t TypeName; + uint16_t FieldOffset; +}; + +struct GlobalLiteralSpec +{ + uint32_t Name; + uint32_t TypeName; + uint64_t Value; +}; + +struct GlobalPointerSpec +{ + uint32_t Name; + uint32_t AuxIndex; +}; + +#define CONCAT(token1,token2) token1 ## token2 +#define CONCAT4(token1, token2, token3, token4) token1 ## token2 ## token3 ## token4 + +#define MAKE_TYPELEN_NAME(tyname) CONCAT(cdac_string_pool_typename__, tyname) +#define MAKE_FIELDLEN_NAME(tyname,membername) CONCAT4(cdac_string_pool_membername__, tyname, __, membername) +#define MAKE_FIELDTYPELEN_NAME(tyname,membername) CONCAT4(cdac_string_pool_membertypename__, tyname, __, membername) +#define MAKE_GLOBALLEN_NAME(globalname) CONCAT(cdac_string_pool_globalname__, globalname) +#define MAKE_GLOBALTYPELEN_NAME(globalname) CONCAT(cdac_string_pool_globaltypename__, globalname) + +// define a struct where the size of each field is the length of some string. we will use offsetof to get +// the offset of each struct element, which will be equal to the offset of the beginning of that string in the +// string pool. +struct CDacStringPoolSizes +{ + char cdac_string_pool_nil; // make the first real string start at offset 1 +#define DECL_LEN(membername,len) char membername[(len)]; +#define CDAC_BASELINE(name) DECL_LEN(cdac_string_pool_baseline_, (sizeof(name))) +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) DECL_LEN(MAKE_TYPELEN_NAME(name), sizeof(#name)) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) DECL_LEN(MAKE_FIELDLEN_NAME(tyname,membername), sizeof(#membername)) \ + DECL_LEN(MAKE_FIELDTYPELEN_NAME(tyname,membername), sizeof(#membertyname)) +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) +#define CDAC_GLOBAL(name,tyname,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) \ + DECL_LEN(MAKE_GLOBALTYPELEN_NAME(name), sizeof(#tyname)) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END +}; + +#define GET_TYPE_NAME(name) offsetof(struct CDacStringPoolSizes, MAKE_TYPELEN_NAME(name)) +#define GET_FIELD_NAME(tyname,membername) offsetof(struct CDacStringPoolSizes, MAKE_FIELDLEN_NAME(tyname,membername)) +#define GET_FIELDTYPE_NAME(tyname,membername) offsetof(struct CDacStringPoolSizes, MAKE_FIELDTYPELEN_NAME(tyname,membername)) +#define GET_GLOBAL_NAME(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALLEN_NAME(globalname)) +#define GET_GLOBALTYPE_NAME(globalname) offsetof(struct CDacStringPoolSizes, MAKE_GLOBALTYPELEN_NAME(globalname)) + +// count the types +enum +{ + CDacBlobTypesCount = +#define CDAC_BASELINE(name) 0 +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) + 1 +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + , +}; + +// count the field pool size. +// there's 1 placeholder element at the start, and 1 endmarker after each type +enum +{ + CDacBlobFieldsPoolCount = +#define CDAC_BASELINE(name) 1 +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) + 1 +#define CDAC_TYPE_END(name) + 1 +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + , +}; + +// count the literal globals +enum +{ + CDacBlobGlobalLiteralsCount = +#define CDAC_BASELINE(name) 0 +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) +#define CDAC_GLOBAL(name,tyname,value) + 1 +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + , +}; + +// count the aux vector globals +enum +{ + CDacBlobGlobalPointersCount = +#define CDAC_BASELINE(name) 0 +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) + 1 +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + , +}; + + +#define MAKE_TYPEFIELDS_TYNAME(tyname) CONCAT(CDacFieldsPoolTypeStart__, tyname) + +// index of each run of fields. +// we make a struct containing one 1-byte field for each field in the run, and then take the offset of the +// struct to get the index of the run of fields. +// this looks like +// +// struct CDacFieldsPoolSizes { +// char cdac_field_pool_start_placeholder__; +// struct CDacFieldsPoolTypeStart__MethodTable { +// char cdac_fields_pool_member__MethodTable__GCHandle; +// char cdac_fields_pool_member__MethodTable_endmarker; +// } CDacFieldsPoolTypeStart__MethodTable; +// ... +// }; +// +// so that offsetof(struct CDacFieldsPoolSizes, CDacFieldsPoolTypeStart__MethodTable) will give the offset of the +// method table field descriptors in the run of fields +struct CDacFieldsPoolSizes +{ +#define DECL_LEN(membername) char membername; +#define CDAC_BASELINE(name) DECL_LEN(cdac_fields_pool_start_placeholder__) +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) struct MAKE_TYPEFIELDS_TYNAME(name) { +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, __, membername)) +#define CDAC_TYPE_END(name) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, _, endmarker)) \ + } MAKE_TYPEFIELDS_TYNAME(name); +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END +#undef DECL_LEN +}; + +#define GET_TYPE_FIELDS(tyname) offsetof(struct CDacFieldsPoolSizes, MAKE_TYPEFIELDS_TYNAME(tyname)) + +// index of each global pointer +// +// struct CDacGlobalPointerIndex +// { +// char placeholder; +// char firstGlobalPointerName; +// char secondGlobalPointerName; +// ... +//} +// +// offsetof (CDACGlobalPointerIndex, NAME) returns the index of the global +struct CDacGlobalPointerIndex +{ +#define DECL_LEN(membername) char membername; +#define CDAC_BASELINE(name) DECL_LEN(cdac_global_pointer_index_start_placeholder__) +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(CONCAT(cdac_global_pointer_index__, name)) +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END +}; + +#define GET_GLOBAL_POINTER_INDEX(name) offsetof(struct CDacGlobalPointerIndex, CONCAT(cdac_global_pointer_index__, name)) + +struct BinaryBlobDataDescriptor +{ + // see data-descriptor-blob.md + struct Directory { + uint32_t FlagsAndBaselineStart; + uint32_t TypesStart; + + uint32_t FieldsPoolStart; + uint32_t GlobalLiteralValuesStart; + + uint32_t GlobalPointersStart; + uint32_t NamesPoolStart; + + uint32_t TypeCount; + uint32_t FieldsPoolCount; + + uint32_t GlobalLiteralValuesCount; + uint32_t GlobalPointerValuesCount; + + uint32_t NamesPoolCount; + + uint8_t TypeSpecSize; + uint8_t FieldSpecSize; + uint8_t GlobalLiteralSpecSize; + uint8_t GlobalPointerSpecSize; + } Directory; + uint32_t PlatformFlags; + uint32_t BaselineName; + struct TypeSpec Types[CDacBlobTypesCount]; + struct FieldSpec FieldsPool[CDacBlobFieldsPoolCount]; + struct GlobalLiteralSpec GlobalLiteralValues[CDacBlobGlobalLiteralsCount]; + struct GlobalPointerSpec GlobalPointerValues[CDacBlobGlobalPointersCount]; + uint8_t NamesPool[sizeof(struct CDacStringPoolSizes)]; + uint8_t EndMagic[4]; +}; + +struct MagicAndBlob { + uint64_t magic; + struct BinaryBlobDataDescriptor Blob; +}; + +const struct MagicAndBlob Blob = { + .magic = 0x00424F4C42434144ull,// "DACBLOB", + .Blob = { + .Directory = { + .FlagsAndBaselineStart = offsetof(struct BinaryBlobDataDescriptor, PlatformFlags), + .TypesStart = offsetof(struct BinaryBlobDataDescriptor, Types), + .FieldsPoolStart = offsetof(struct BinaryBlobDataDescriptor, FieldsPool), + .GlobalLiteralValuesStart = offsetof(struct BinaryBlobDataDescriptor, GlobalLiteralValues), + .GlobalPointersStart = offsetof(struct BinaryBlobDataDescriptor, GlobalPointerValues), + .NamesPoolStart = offsetof(struct BinaryBlobDataDescriptor, NamesPool), + .TypeCount = CDacBlobTypesCount, + .FieldsPoolCount = CDacBlobFieldsPoolCount, + .GlobalLiteralValuesCount = CDacBlobGlobalLiteralsCount, + .GlobalPointerValuesCount = CDacBlobGlobalPointersCount, + .NamesPoolCount = sizeof(struct CDacStringPoolSizes), + .TypeSpecSize = sizeof(struct TypeSpec), + .FieldSpecSize = sizeof(struct FieldSpec), + .GlobalLiteralSpecSize = sizeof(struct GlobalLiteralSpec), + .GlobalPointerSpecSize = sizeof(struct GlobalPointerSpec), + }, + .EndMagic = { 0x01, 0x02, 0x03, 0x04 }, + .PlatformFlags = 0x01 | (sizeof(void*) == 4 ? 0x02 : 0), + .BaselineName = offsetof(struct CDacStringPoolSizes, cdac_string_pool_baseline_), + + .NamesPool = ("\0" // starts with a nul +#define CDAC_BASELINE(name) name "\0" +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) #name "\0" +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) #membername "\0" #membertyname "\0" +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) #name "\0" +#define CDAC_GLOBAL(name,tyname,value) #name "\0" #tyname "\0" +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + ), + + .FieldsPool = { +#define CDAC_BASELINE(name) {0,}, +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) { \ + .Name = GET_FIELD_NAME(tyname,membername), \ + .TypeName = GET_FIELDTYPE_NAME(tyname,membername), \ + .FieldOffset = offset, \ +}, +#define CDAC_TYPE_END(name) { 0, }, +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + }, + + .Types = { +#define CDAC_BASELINE(name) +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) { \ + .Name = GET_TYPE_NAME(name), \ + .Fields = GET_TYPE_FIELDS(name), +#define CDAC_TYPE_INDETERMINATE(name) .Size = 0, +#define CDAC_TYPE_SIZE(size) .Size = size, +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) +#define CDAC_TYPE_END(name) }, +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + }, + + .GlobalLiteralValues = { +#define CDAC_BASELINE(name) +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) +#define CDAC_GLOBAL(name,tyname,value) { .Name = GET_GLOBAL_NAME(name), .TypeName = GET_GLOBALTYPE_NAME(name), .Value = value }, +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + }, + + .GlobalPointerValues = { +#define CDAC_BASELINE(name) +#define CDAC_TYPES_BEGIN() +#define CDAC_TYPE_BEGIN(name) +#define CDAC_TYPE_INDETERMINATE(name) +#define CDAC_TYPE_SIZE(size) +#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) +#define CDAC_TYPE_END(name) +#define CDAC_TYPES_END() +#define CDAC_GLOBALS_BEGIN() +#define CDAC_GLOBAL_POINTER(name,value) { .Name = GET_GLOBAL_NAME(name), .AuxIndex = GET_GLOBAL_POINTER_INDEX(name) }, +#define CDAC_GLOBAL(name,tyname,value) +#define CDAC_GLOBALS_END() +#include "sample.data.h" +#undef CDAC_BASELINE +#undef CDAC_TYPES_BEGIN +#undef CDAC_TYPES_END +#undef CDAC_TYPE_BEGIN +#undef CDAC_TYPE_INDETERMINATE +#undef CDAC_TYPE_SIZE +#undef CDAC_TYPE_FIELD +#undef CDAC_TYPE_END +#undef DECL_LEN +#undef CDAC_GLOBALS_BEGIN +#undef CDAC_GLOBAL_POINTER +#undef CDAC_GLOBAL +#undef CDAC_GLOBALS_END + }, + } +}; + +// end blob definition diff --git a/src/coreclr/tools/cdac-build-tool/sample/sample.data.h b/src/coreclr/tools/cdac-build-tool/sample/sample.data.h new file mode 100644 index 00000000000000..e4b8bff98b5e43 --- /dev/null +++ b/src/coreclr/tools/cdac-build-tool/sample/sample.data.h @@ -0,0 +1,24 @@ +CDAC_BASELINE("empty") +CDAC_TYPES_BEGIN() + +CDAC_TYPE_BEGIN(ManagedThread) +CDAC_TYPE_INDETERMINATE(ManagedThread) +CDAC_TYPE_FIELD(ManagedThread, GCHandle, GCHandle, offsetof(ManagedThread,m_gcHandle)) +CDAC_TYPE_FIELD(ManagedThread, pointer, Next, offsetof(ManagedThread,m_next)) +CDAC_TYPE_END(ManagedThread) + +CDAC_TYPE_BEGIN(GCHandle) +CDAC_TYPE_SIZE(sizeof(intptr_t)) +CDAC_TYPE_END(GCHandle) + +CDAC_TYPES_END() + +CDAC_GLOBALS_BEGIN() +CDAC_GLOBAL_POINTER(ManagedThreadStore, &g_managedThreadStore) +#if FEATURE_EH_FUNCLETS +CDAC_GLOBAL(FeatureEHFunclets, uint8, 1) +#else +CDAC_GLOBAL(FeatureEHFunclets, uint8, 0) +#endif +CDAC_GLOBAL(SomeMagicNumber, uint32, 42) +CDAC_GLOBALS_END() diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h index 104a7ae1fabd39..4e34350894ec79 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h @@ -519,6 +519,7 @@ struct Agnostic_GetPgoInstrumentationResults DWORD dataByteCount; DWORD result; DWORD pgoSource; + DWORD dynamicPgo; }; struct Agnostic_GetProfilingHandle diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 05ad1c23a6a2c9..25e3b1c7744150 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -5640,10 +5640,11 @@ HRESULT MethodContext::repAllocPgoInstrumentationBySchema( UINT32 countSchemaItems, BYTE** pInstrumentationData) { - if (repAllocPgoInstrumentationBySchemaRecorded(ftnHnd, pSchema, countSchemaItems, pInstrumentationData)) + HRESULT result; + if (repAllocPgoInstrumentationBySchemaRecorded(ftnHnd, pSchema, countSchemaItems, pInstrumentationData, &result)) { // Matching case: return same layout as recorded EE. - return S_OK; + return result; } // Do our own layout. @@ -5676,7 +5677,8 @@ bool MethodContext::repAllocPgoInstrumentationBySchemaRecorded( CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, - BYTE** pInstrumentationData) + BYTE** pInstrumentationData, + HRESULT* result) { if (AllocPgoInstrumentationBySchema == nullptr) return false; @@ -5716,6 +5718,7 @@ bool MethodContext::repAllocPgoInstrumentationBySchemaRecorded( // We assume JIT does not write or read from this buffer, only generate // code that uses it. *pInstrumentationData = (BYTE*)value.instrumentationDataAddress; + *result = value.result; return true; } @@ -5724,6 +5727,7 @@ void MethodContext::recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, + bool* pDynamicPgo, HRESULT result) { if (GetPgoInstrumentationResults == nullptr) @@ -5754,6 +5758,7 @@ void MethodContext::recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd value.dataByteCount = (unsigned)maxOffset; value.result = (DWORD)result; value.pgoSource = (DWORD)*pPgoSource; + value.dynamicPgo = (DWORD)*pDynamicPgo; DWORDLONG key = CastHandle(ftnHnd); GetPgoInstrumentationResults->Add(key, value); @@ -5761,8 +5766,8 @@ void MethodContext::recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd } void MethodContext::dmpGetPgoInstrumentationResults(DWORDLONG key, const Agnostic_GetPgoInstrumentationResults& value) { - printf("GetPgoInstrumentationResults key ftn-%016" PRIX64 ", value res-%08X schemaCnt-%u profileBufSize-%u source-%u schema{", - key, value.result, value.countSchemaItems, value.dataByteCount, value.pgoSource); + printf("GetPgoInstrumentationResults key ftn-%016" PRIX64 ", value res-%08X schemaCnt-%u profileBufSize-%u source-%u dynamic-%u schema{", + key, value.result, value.countSchemaItems, value.dataByteCount, value.pgoSource, value.dynamicPgo); if (value.countSchemaItems > 0) { @@ -5838,7 +5843,8 @@ HRESULT MethodContext::repGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftn ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, - ICorJitInfo::PgoSource* pPgoSource) + ICorJitInfo::PgoSource* pPgoSource, + bool* pDynamicPgo) { DWORDLONG key = CastHandle(ftnHnd); Agnostic_GetPgoInstrumentationResults tempValue = LookupByKeyOrMiss(GetPgoInstrumentationResults, key, ": key %016" PRIX64 "", key); @@ -5848,6 +5854,7 @@ HRESULT MethodContext::repGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftn *pCountSchemaItems = (UINT32)tempValue.countSchemaItems; *pInstrumentationData = (BYTE*)GetPgoInstrumentationResults->GetBuffer(tempValue.data_index); *pPgoSource = (ICorJitInfo::PgoSource)tempValue.pgoSource; + *pDynamicPgo = (bool)tempValue.dynamicPgo; ICorJitInfo::PgoInstrumentationSchema* pOutSchema = (ICorJitInfo::PgoInstrumentationSchema*)AllocJitTempBuffer(tempValue.countSchemaItems * sizeof(ICorJitInfo::PgoInstrumentationSchema)); @@ -7183,7 +7190,8 @@ int MethodContext::dumpMethodIdentityInfoToBuffer(char* buff, int len, bool igno UINT32 schemaCount = 0; BYTE* schemaData = nullptr; ICorJitInfo::PgoSource pgoSource = ICorJitInfo::PgoSource::Unknown; - HRESULT pgoHR = repGetPgoInstrumentationResults(pInfo->ftn, &schema, &schemaCount, &schemaData, &pgoSource); + bool dynamicPgo = false; + HRESULT pgoHR = repGetPgoInstrumentationResults(pInfo->ftn, &schema, &schemaCount, &schemaData, &pgoSource, &dynamicPgo); size_t minOffset = (size_t) ~0; size_t maxOffset = 0; @@ -7281,7 +7289,8 @@ bool MethodContext::hasPgoData(bool& hasEdgeProfile, bool& hasClassProfile, bool ICorJitInfo::PgoInstrumentationSchema* schema = nullptr; UINT32 schemaCount = 0; BYTE* schemaData = nullptr; - HRESULT pgoHR = repGetPgoInstrumentationResults(info.ftn, &schema, &schemaCount, &schemaData, &pgoSource); + bool dynamicPgo; + HRESULT pgoHR = repGetPgoInstrumentationResults(info.ftn, &schema, &schemaCount, &schemaData, &pgoSource, &dynamicPgo); if (SUCCEEDED(pgoHR)) { diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index a530d2f58385be..2c85988aa32e8e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -709,11 +709,11 @@ class MethodContext void recAllocPgoInstrumentationBySchema(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData, HRESULT result); void dmpAllocPgoInstrumentationBySchema(DWORDLONG key, const Agnostic_AllocPgoInstrumentationBySchema& value); HRESULT repAllocPgoInstrumentationBySchema(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData); - bool repAllocPgoInstrumentationBySchemaRecorded(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData); + bool repAllocPgoInstrumentationBySchemaRecorded(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData, HRESULT* result); - void recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, HRESULT result); + void recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, bool* pDynamicPgo, HRESULT result); void dmpGetPgoInstrumentationResults(DWORDLONG key, const Agnostic_GetPgoInstrumentationResults& value); - HRESULT repGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource); + HRESULT repGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, bool* pDynamicPgo); void recIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result); void dmpIsMoreSpecificType(DLDL key, DWORD value); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp index 14f1d37dde61f7..e15ecabf5f65cd 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp @@ -622,9 +622,13 @@ bool MethodContextReader::IsMethodExcluded(MethodContext* mc) void MethodContextReader::Reset(const int* newIndexes, int newIndexCount) { - Indexes = newIndexes; - IndexCount = newIndexCount; + __int64 pos = 0; + BOOL result = SetFilePointerEx(fileHandle, *(PLARGE_INTEGER)&pos, NULL, FILE_BEGIN); + assert(result); + + Indexes = newIndexes; + IndexCount = newIndexCount; curIndexPos = 0; - curMCIndex = 0; + curMCIndex = 0; curTOCIndex = 0; } diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index d39379089794f5..ac8efbddcfeec5 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1947,11 +1947,12 @@ HRESULT interceptor_ICJI::getPgoInstrumentationResults(CORINFO_METHOD_HANDLE PgoInstrumentationSchema **pSchema, // pointer to the schema table which describes the instrumentation results (pointer will not remain valid after jit completes) uint32_t * pCountSchemaItems, // pointer to the count schema items uint8_t ** pInstrumentationData, // pointer to the actual instrumentation data (pointer will not remain valid after jit completes) - PgoSource* pPgoSource) + PgoSource* pPgoSource, + bool* pDynamicPgo) { mc->cr->AddCall("getPgoInstrumentationResults"); - HRESULT temp = original_ICorJitInfo->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource); - mc->recGetPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, temp); + HRESULT temp = original_ICorJitInfo->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, pDynamicPgo); + mc->recGetPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, pDynamicPgo, temp); return temp; } diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index eebb80ab6b9dfa..a365cdb111e228 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -1374,10 +1374,11 @@ JITINTERFACE_HRESULT interceptor_ICJI::getPgoInstrumentationResults( ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t** pInstrumentationData, - ICorJitInfo::PgoSource* pgoSource) + ICorJitInfo::PgoSource* pPgoSource, + bool* pDynamicPgo) { mcs->AddCall("getPgoInstrumentationResults"); - return original_ICorJitInfo->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pgoSource); + return original_ICorJitInfo->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, pDynamicPgo); } JITINTERFACE_HRESULT interceptor_ICJI::allocPgoInstrumentationBySchema( diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index 6a2ca48d87cd79..0d80993f52b676 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -1206,9 +1206,10 @@ JITINTERFACE_HRESULT interceptor_ICJI::getPgoInstrumentationResults( ICorJitInfo::PgoInstrumentationSchema** pSchema, uint32_t* pCountSchemaItems, uint8_t** pInstrumentationData, - ICorJitInfo::PgoSource* pgoSource) + ICorJitInfo::PgoSource* pPgoSource, + bool* pDynamicPgo) { - return original_ICorJitInfo->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pgoSource); + return original_ICorJitInfo->getPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, pDynamicPgo); } JITINTERFACE_HRESULT interceptor_ICJI::allocPgoInstrumentationBySchema( diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 08814336a74b1f..b263c1cafdebc9 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1806,11 +1806,12 @@ HRESULT MyICJI::getPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, PgoInstrumentationSchema **pSchema, // pointer to the schema table which describes the instrumentation results (pointer will not remain valid after jit completes) uint32_t * pCountSchemaItems, // pointer to the count schema items uint8_t ** pInstrumentationData, // pointer to the actual instrumentation data (pointer will not remain valid after jit completes) - PgoSource* pPgoSource) + PgoSource* pPgoSource, + bool* pDynamicPgo) { jitInstance->mc->cr->AddCall("getPgoInstrumentationResults"); - return jitInstance->mc->repGetPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource); + return jitInstance->mc->repGetPgoInstrumentationResults(ftnHnd, pSchema, pCountSchemaItems, pInstrumentationData, pPgoSource, pDynamicPgo); } // Associates a native call site, identified by its offset in the native code stream, with diff --git a/src/coreclr/utilcode/clrhost_nodependencies.cpp b/src/coreclr/utilcode/clrhost_nodependencies.cpp index 7aceae763c43b8..3cc4badd9e3aa3 100644 --- a/src/coreclr/utilcode/clrhost_nodependencies.cpp +++ b/src/coreclr/utilcode/clrhost_nodependencies.cpp @@ -202,12 +202,8 @@ ClrDebugState *CLRInitDebugState() #endif //defined(_DEBUG_IMPL) && defined(ENABLE_CONTRACTS_IMPL) -const NoThrow nothrow = { 0 }; - -#if defined(HAS_ADDRESS_SANITIZER) || defined(DACCESS_COMPILE) -// use standard heap functions for address sanitizer -#else - +// use standard heap functions for AddressSanitizer and for the DAC build. +#if !defined(HAS_ADDRESS_SANITIZER) && !defined(DACCESS_COMPILE) #ifdef _DEBUG #ifdef TARGET_X86 #define OS_HEAP_ALIGN 8 @@ -221,7 +217,7 @@ const NoThrow nothrow = { 0 }; static HANDLE g_hProcessHeap; #endif -FORCEINLINE void* ClrMalloc(size_t size) +static FORCEINLINE void* ClrMalloc(size_t size) { STATIC_CONTRACT_NOTHROW; @@ -339,14 +335,9 @@ operator new[](size_t n) return result; }; -#endif // HAS_ADDRESS_SANITIZER || DACCESS_COMPILE -void * __cdecl operator new(size_t n, const NoThrow&) NOEXCEPT +void * __cdecl operator new(size_t n, const std::nothrow_t&) noexcept { -#if defined(HAS_ADDRESS_SANITIZER) || defined(DACCESS_COMPILE) - // use standard heap functions for address sanitizer (which doesn't provide for NoThrow) - void * result = operator new(n); -#else STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_FAULT; @@ -355,17 +346,12 @@ void * __cdecl operator new(size_t n, const NoThrow&) NOEXCEPT INCONTRACT(_ASSERTE(!ARE_FAULTS_FORBIDDEN())); void* result = ClrMalloc(n); -#endif // HAS_ADDRESS_SANITIZER || DACCESS_COMPILE TRASH_LASTERROR; return result; } -void * __cdecl operator new[](size_t n, const NoThrow&) NOEXCEPT +void * __cdecl operator new[](size_t n, const std::nothrow_t&) noexcept { -#if defined(HAS_ADDRESS_SANITIZER) || defined(DACCESS_COMPILE) - // use standard heap functions for address sanitizer (which doesn't provide for NoThrow) - void * result = operator new[](n); -#else STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_FAULT; @@ -374,16 +360,12 @@ void * __cdecl operator new[](size_t n, const NoThrow&) NOEXCEPT INCONTRACT(_ASSERTE(!ARE_FAULTS_FORBIDDEN())); void* result = ClrMalloc(n); -#endif // HAS_ADDRESS_SANITIZER || DACCESS_COMPILE TRASH_LASTERROR; return result; } -#if defined(HAS_ADDRESS_SANITIZER) || defined(DACCESS_COMPILE) -// use standard heap functions for address sanitizer -#else void __cdecl -operator delete(void *p) NOEXCEPT +operator delete(void *p) noexcept { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; @@ -395,7 +377,7 @@ operator delete(void *p) NOEXCEPT } void __cdecl -operator delete[](void *p) NOEXCEPT +operator delete[](void *p) noexcept { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; @@ -405,7 +387,7 @@ operator delete[](void *p) NOEXCEPT TRASH_LASTERROR; } -#endif // HAS_ADDRESS_SANITIZER || DACCESS_COMPILE +#endif // !HAS_ADDRESS_SANITIZER && !DACCESS_COMPILE /* ------------------------------------------------------------------------ * * New operator overloading for the executable heap @@ -494,7 +476,7 @@ void * __cdecl operator new[](size_t n, const CExecutable&) return result; } -void * __cdecl operator new(size_t n, const CExecutable&, const NoThrow&) +void * __cdecl operator new(size_t n, const CExecutable&, const std::nothrow_t&) noexcept { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; @@ -511,7 +493,7 @@ void * __cdecl operator new(size_t n, const CExecutable&, const NoThrow&) return result; } -void * __cdecl operator new[](size_t n, const CExecutable&, const NoThrow&) +void * __cdecl operator new[](size_t n, const CExecutable&, const std::nothrow_t&) noexcept { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; diff --git a/src/coreclr/utilcode/executableallocator.cpp b/src/coreclr/utilcode/executableallocator.cpp index 65802615fc6aa8..09a4801d2d5dbc 100644 --- a/src/coreclr/utilcode/executableallocator.cpp +++ b/src/coreclr/utilcode/executableallocator.cpp @@ -3,6 +3,7 @@ #include "pedecoder.h" #include "executableallocator.h" +#include #if USE_LAZY_PREFERRED_RANGE // Preferred region to allocate the code in. @@ -260,7 +261,7 @@ HRESULT ExecutableAllocator::StaticInitialize(FatalErrorHandler fatalErrorHandle #endif g_fatalErrorHandler = fatalErrorHandler; - g_isWXorXEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableWriteXorExecute) != 0; + g_isWXorXEnabled = Configuration::GetKnobBooleanValue(W("System.Runtime.EnableWriteXorExecute"), CLRConfig::EXTERNAL_EnableWriteXorExecute); g_instance = new (nothrow) ExecutableAllocator(); if (g_instance == NULL) { diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp index 37abeb2cb92f4e..443be4ade177bc 100644 --- a/src/coreclr/utilcode/stresslog.cpp +++ b/src/coreclr/utilcode/stresslog.cpp @@ -963,7 +963,7 @@ void* StressLog::AllocMemoryMapped(size_t n) return nullptr; } -void* __cdecl ThreadStressLog::operator new(size_t n, const NoThrow&) NOEXCEPT +void* __cdecl ThreadStressLog::operator new(size_t n, const std::nothrow_t&) noexcept { if (StressLogChunk::s_memoryMapped) return StressLog::AllocMemoryMapped(n); diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt index 345d5ac35f00e9..f60713ef587e1c 100644 --- a/src/coreclr/vm/CMakeLists.txt +++ b/src/coreclr/vm/CMakeLists.txt @@ -103,7 +103,6 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON peassembly.cpp peimage.cpp perfmap.cpp - perfinfo.cpp pgo.cpp precode.cpp prestub.cpp @@ -206,7 +205,6 @@ set(VM_HEADERS_DAC_AND_WKS_COMMON peimagelayout.h peimagelayout.inl perfmap.h - perfinfo.h pgo.h precode.h rejit.h @@ -391,6 +389,7 @@ set(VM_HEADERS_WKS callhelpers.h callsiteinspect.h callconvbuilder.hpp + cdacoffsets.h ceemain.h clrconfignative.h clrex.h diff --git a/src/coreclr/vm/amd64/Context.S b/src/coreclr/vm/amd64/Context.S index 0721c45f56727c..1eda47f0f9dc3f 100644 --- a/src/coreclr/vm/amd64/Context.S +++ b/src/coreclr/vm/amd64/Context.S @@ -51,8 +51,9 @@ NESTED_ENTRY ClrRestoreNonvolatileContextWorker, _TEXT, NoHandler // exception handling, iret and ret can't be used because their shadow stack enforcement would not allow that transition, // and using them would require writing to the shadow stack, which is not preferable. Instead, iret is partially // simulated. + mov rax, [r10 + OFFSETOF__CONTEXT__Rip] mov rsp, [r10 + OFFSETOF__CONTEXT__Rsp] - jmp qword ptr [r10 + OFFSETOF__CONTEXT__Rip] + jmp rax Done_Restore_CONTEXT_CONTROL: // The function was not asked to restore the control registers so we return back to the caller diff --git a/src/coreclr/vm/amd64/Context.asm b/src/coreclr/vm/amd64/Context.asm index a7165983cf4fa1..a2dbbda0b30991 100644 --- a/src/coreclr/vm/amd64/Context.asm +++ b/src/coreclr/vm/amd64/Context.asm @@ -63,8 +63,9 @@ NESTED_ENTRY ClrRestoreNonvolatileContextWorker, _TEXT mov eax, [r10 + OFFSETOF__CONTEXT__EFlags] push rax popfq + mov rax, [r10 + OFFSETOF__CONTEXT__Rip] mov rsp, [r10 + OFFSETOF__CONTEXT__Rsp] - jmp qword ptr [r10 + OFFSETOF__CONTEXT__Rip] + jmp rax Done_Restore_CONTEXT_CONTROL: ; The function was not asked to restore the control registers so we return back to the caller diff --git a/src/coreclr/vm/amd64/asmconstants.h b/src/coreclr/vm/amd64/asmconstants.h index 47cca560d7bb11..46806e49076566 100644 --- a/src/coreclr/vm/amd64/asmconstants.h +++ b/src/coreclr/vm/amd64/asmconstants.h @@ -278,9 +278,6 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__LazyMachState__m_CaptureRip ASMCONSTANTS_C_ASSERT(OFFSETOF__LazyMachState__m_CaptureRsp == offsetof(LazyMachState, m_CaptureRsp)); -#define OFFSETOF__MethodDesc__m_wFlags DBG_FRE(0x2E, 0x06) -ASMCONSTANTS_C_ASSERT(OFFSETOF__MethodDesc__m_wFlags == offsetof(MethodDesc, m_wFlags)); - #define OFFSETOF__VASigCookie__pNDirectILStub 0x8 ASMCONSTANTS_C_ASSERT(OFFSETOF__VASigCookie__pNDirectILStub == offsetof(VASigCookie, pNDirectILStub)); diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index 59a4783648e2a7..54d395c1d2e353 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -1158,6 +1158,13 @@ void SystemDomain::Init() // Finish loading CoreLib now. m_pSystemAssembly->GetDomainAssembly()->EnsureActive(); + + // Set AwareLock's offset of the holding OS thread ID field into ThreadBlockingInfo's static field. That can be used + // when doing managed debugging to get the OS ID of the thread holding the lock. The offset is currently not zero, and + // zero is used in managed code to determine if the static variable has been initialized. + _ASSERTE(AwareLock::GetOffsetOfHoldingOSThreadId() != 0); + CoreLibBinder::GetField(FIELD__THREAD_BLOCKING_INFO__OFFSET_OF_LOCK_OWNER_OS_THREAD_ID) + ->SetStaticValue32(AwareLock::GetOffsetOfHoldingOSThreadId()); } #ifdef _DEBUG diff --git a/src/coreclr/vm/arm/asmconstants.h b/src/coreclr/vm/arm/asmconstants.h index 5c92427008bb45..7d6106104fbfc2 100644 --- a/src/coreclr/vm/arm/asmconstants.h +++ b/src/coreclr/vm/arm/asmconstants.h @@ -114,13 +114,6 @@ ASMCONSTANTS_C_ASSERT(SIZEOF__FloatArgumentRegisters == sizeof(FloatArgumentRegi #define ASM_ENREGISTERED_RETURNTYPE_MAXSIZE 0x20 ASMCONSTANTS_C_ASSERT(ASM_ENREGISTERED_RETURNTYPE_MAXSIZE == ENREGISTERED_RETURNTYPE_MAXSIZE) - -#define MethodDesc__m_wFlags DBG_FRE(0x1A, 0x06) -ASMCONSTANTS_C_ASSERT(MethodDesc__m_wFlags == offsetof(MethodDesc, m_wFlags)) - -#define MethodDesc__mdcClassification 0x7 -ASMCONSTANTS_C_ASSERT(MethodDesc__mdcClassification == mdcClassification) - #ifdef FEATURE_COMINTEROP #define Stub__m_pCode DBG_FRE(0x10, 0x0c) diff --git a/src/coreclr/vm/cdacoffsets.h b/src/coreclr/vm/cdacoffsets.h new file mode 100644 index 00000000000000..317ef41f736037 --- /dev/null +++ b/src/coreclr/vm/cdacoffsets.h @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef CDACOFFSETS_H__ +#define CDACOFFSETS_H__ + +// See data-descriptor.h +// +// If the offset of some field F in class C must be provided to cDAC, but the field is private, the +// class C should declare cdac_offsets as a friend: +// +// friend template struct cdac_offsets; +// +// and provide a specialization cdac_offsets with a constexpr size_t member providing the offset: +// +// template<> struct cdac_offsets { +// static constexpr size_t F_Offset = offsetof(C, F); +// }; +template +struct cdac_offsets +{ +}; + +#endif// CDACOFFSETS_H__ diff --git a/src/coreclr/vm/classcompat.cpp b/src/coreclr/vm/classcompat.cpp index b089dad7fdafb6..ece9384703b2b8 100644 --- a/src/coreclr/vm/classcompat.cpp +++ b/src/coreclr/vm/classcompat.cpp @@ -869,7 +869,7 @@ VOID MethodTableBuilder::BuildInteropVTable_PlaceMembers( bmtMethod->ppMethodDescList[i] = pNewMD; // Make sure that fcalls have a 0 rva. This is assumed by the prejit fixup logic - _ASSERTE(((Classification & ~mdcMethodImpl) != mcFCall) || dwDescrOffset == 0); + _ASSERTE(((Classification & ~mdfMethodImpl) != mcFCall) || dwDescrOffset == 0); // Non-virtual method if (IsMdStatic(dwMemberAttrs) || @@ -938,7 +938,7 @@ VOID MethodTableBuilder::BuildInteropVTable_PlaceMembers( } } - if (Classification & mdcMethodImpl) + if (Classification & mdfMethodImpl) { // If this method serves as the BODY of a MethodImpl specification, then // we should iterate all the MethodImpl's for this class and see just how many // of them this method participates in as the BODY. @@ -2797,7 +2797,7 @@ VOID MethodTableBuilder::EnumerateClassMethods() } // Generic methods should always be mcInstantiated - if (!((numGenericMethodArgs == 0) || ((Classification & mdcClassification) == mcInstantiated))) + if (!((numGenericMethodArgs == 0) || ((Classification & mdfClassification) == mcInstantiated))) { BuildMethodTableThrowException(BFA_GENERIC_METHODS_INST); } @@ -2806,7 +2806,7 @@ VOID MethodTableBuilder::EnumerateClassMethods() // from the overrides. for(DWORD impls = 0; impls < bmtMethodImpl->dwNumberMethodImpls; impls++) { if ((bmtMethodImpl->rgMethodImplTokens[impls].methodBody == tok) && !IsMdStatic(dwMemberAttrs)) { - Classification |= mdcMethodImpl; + Classification |= mdfMethodImpl; break; } } @@ -2830,7 +2830,7 @@ VOID MethodTableBuilder::EnumerateClassMethods() // Set the index into the storage locations BYTE impl; - if (Classification & mdcMethodImpl) + if (Classification & mdfMethodImpl) { impl = METHOD_IMPL; } @@ -2840,25 +2840,25 @@ VOID MethodTableBuilder::EnumerateClassMethods() } BYTE type; - if ((Classification & mdcClassification) == mcNDirect) + if ((Classification & mdfClassification) == mcNDirect) { type = METHOD_TYPE_NDIRECT; } - else if ((Classification & mdcClassification) == mcFCall) + else if ((Classification & mdfClassification) == mcFCall) { type = METHOD_TYPE_FCALL; } - else if ((Classification & mdcClassification) == mcEEImpl) + else if ((Classification & mdfClassification) == mcEEImpl) { type = METHOD_TYPE_EEIMPL; } #ifdef FEATURE_COMINTEROP - else if ((Classification & mdcClassification) == mcComInterop) + else if ((Classification & mdfClassification) == mcComInterop) { type = METHOD_TYPE_INTEROP; } #endif // FEATURE_COMINTEROP - else if ((Classification & mdcClassification) == mcInstantiated) + else if ((Classification & mdfClassification) == mcInstantiated) { type = METHOD_TYPE_INSTANTIATED; } diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index c14fc7a69ecbd8..2f9049aea8d710 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -583,6 +583,10 @@ END_ILLINK_FEATURE_SWITCH() DEFINE_CLASS(MONITOR, Threading, Monitor) DEFINE_METHOD(MONITOR, ENTER, Enter, SM_Obj_RetVoid) +DEFINE_CLASS(THREAD_BLOCKING_INFO, Threading, ThreadBlockingInfo) +DEFINE_FIELD(THREAD_BLOCKING_INFO, OFFSET_OF_LOCK_OWNER_OS_THREAD_ID, s_monitorObjectOffsetOfLockOwnerOSThreadId) +DEFINE_FIELD(THREAD_BLOCKING_INFO, FIRST, t_first) + DEFINE_CLASS(PARAMETER, Reflection, ParameterInfo) DEFINE_CLASS(PARAMETER_MODIFIER, Reflection, ParameterModifier) @@ -604,11 +608,6 @@ DEFINE_METHOD(PROPERTY, GET_GETTER, GetGetMethod, DEFINE_CLASS(PROPERTY_INFO, Reflection, PropertyInfo) - - -DEFINE_CLASS(METADATA_IMPORT, Reflection, MetadataImport) -DEFINE_METHOD(METADATA_IMPORT, THROW_ERROR, ThrowError, SM_Int_RetVoid) - DEFINE_CLASS(RESOLVER, System, Resolver) DEFINE_METHOD(RESOLVER, GET_JIT_CONTEXT, GetJitContext, IM_RefInt_RetRuntimeType) DEFINE_METHOD(RESOLVER, GET_CODE_INFO, GetCodeInfo, IM_RefInt_RefInt_RefInt_RetArrByte) @@ -892,6 +891,7 @@ DEFINE_METHOD(DEBUGGER, BREAK, Break, DEFINE_CLASS(BUFFER, System, Buffer) DEFINE_METHOD(BUFFER, MEMCPY_PTRBYTE_ARRBYTE, Memcpy, SM_PtrByte_Int_ArrByte_Int_Int_RetVoid) DEFINE_METHOD(BUFFER, MEMCPY, Memcpy, SM_PtrByte_PtrByte_Int_RetVoid) +DEFINE_METHOD(BUFFER, MEMCOPYGC, BulkMoveWithWriteBarrier, SM_RefByte_RefByte_UIntPtr_RetVoid) DEFINE_CLASS(STUBHELPERS, StubHelpers, StubHelpers) DEFINE_METHOD(STUBHELPERS, GET_DELEGATE_TARGET, GetDelegateTarget, SM_Delegate_RetIntPtr) diff --git a/src/coreclr/vm/domainassembly.cpp b/src/coreclr/vm/domainassembly.cpp index 0e86d312ae88a3..75995f477a32f3 100644 --- a/src/coreclr/vm/domainassembly.cpp +++ b/src/coreclr/vm/domainassembly.cpp @@ -23,10 +23,6 @@ #include "dllimportcallback.h" #include "peimagelayout.inl" -#ifdef FEATURE_PERFMAP -#include "perfmap.h" -#endif // FEATURE_PERFMAP - #ifndef DACCESS_COMPILE DomainAssembly::DomainAssembly(PEAssembly* pPEAssembly, LoaderAllocator* pLoaderAllocator) : m_pAssembly(NULL), @@ -344,14 +340,14 @@ OBJECTREF DomainAssembly::GetExposedModuleObject() { REFLECTMODULEBASEREF refClass = NULL; - // Will be TRUE only if LoaderAllocator managed object was already collected and therefore we should + // Will be true only if LoaderAllocator managed object was already collected and therefore we should // return NULL - BOOL fIsLoaderAllocatorCollected = FALSE; + bool fIsLoaderAllocatorCollected = false; GCPROTECT_BEGIN(refClass); refClass = (REFLECTMODULEBASEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__MODULE)); - refClass->SetModule(m_pModule); + refClass->SetModule(GetModule()); // Attach the reference to the assembly to keep the LoaderAllocator for this collectible type // alive as long as a reference to the module is kept alive. @@ -360,7 +356,7 @@ OBJECTREF DomainAssembly::GetExposedModuleObject() OBJECTREF refAssembly = GetModule()->GetAssembly()->GetExposedObject(); if ((refAssembly == NULL) && GetModule()->GetAssembly()->IsCollectible()) { - fIsLoaderAllocatorCollected = TRUE; + fIsLoaderAllocatorCollected = true; } refClass->SetAssembly(refAssembly); } @@ -558,11 +554,6 @@ void DomainAssembly::FinishLoad() // Set a bit to indicate that the module has been loaded in some domain, and therefore // typeloads can involve types from this module. (Used for candidate instantiations.) GetModule()->SetIsReadyForTypeLoad(); - -#ifdef FEATURE_PERFMAP - // Notify the perfmap of the IL image load. - PerfMap::LogImageLoad(m_pPEAssembly); -#endif } void DomainAssembly::Activate() diff --git a/src/coreclr/vm/ecall.cpp b/src/coreclr/vm/ecall.cpp index 35a5d36eae4d76..56a28a7a57ddb8 100644 --- a/src/coreclr/vm/ecall.cpp +++ b/src/coreclr/vm/ecall.cpp @@ -157,6 +157,10 @@ void ECall::PopulateManagedHelpers() pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_MEMCPY, pDest); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__BUFFER__MEMCOPYGC)); + pDest = pMD->GetMultiCallableAddrOfCode(); + SetJitHelperFunction(CORINFO_HELP_BULK_WRITEBARRIER, pDest); + pMD = CoreLibBinder::GetMethod((BinderMethodID)(METHOD__MATH__ROUND)); pDest = pMD->GetMultiCallableAddrOfCode(); SetJitHelperFunction(CORINFO_HELP_DBLROUND, pDest); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index dfcfbef6ba5826..98a38b8603419c 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -137,7 +137,6 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetFields", RuntimeTypeHandle::GetFields) FCFuncElement("GetInterfaces", RuntimeTypeHandle::GetInterfaces) FCFuncElement("GetAttributes", RuntimeTypeHandle::GetAttributes) - FCFuncElement("_GetMetadataImport", RuntimeTypeHandle::GetMetadataImport) FCFuncElement("GetNumVirtuals", RuntimeTypeHandle::GetNumVirtuals) FCFuncElement("GetNumVirtualsAndStaticVirtuals", RuntimeTypeHandle::GetNumVirtualsAndStaticVirtuals) FCFuncElement("CanCastTo", RuntimeTypeHandle::CanCastTo) @@ -156,31 +155,31 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncEnd() FCFuncStart(gMetaDataImport) - FCFuncElement("_GetDefaultValue", MetaDataImport::GetDefaultValue) - FCFuncElement("_GetName", MetaDataImport::GetName) - FCFuncElement("_GetUserString", MetaDataImport::GetUserString) - FCFuncElement("_GetScopeProps", MetaDataImport::GetScopeProps) - FCFuncElement("_GetClassLayout", MetaDataImport::GetClassLayout) - FCFuncElement("_GetSignatureFromToken", MetaDataImport::GetSignatureFromToken) - FCFuncElement("_GetNamespace", MetaDataImport::GetNamespace) - FCFuncElement("_GetEventProps", MetaDataImport::GetEventProps) - FCFuncElement("_GetFieldDefProps", MetaDataImport::GetFieldDefProps) - FCFuncElement("_GetPropertyProps", MetaDataImport::GetPropertyProps) - FCFuncElement("_GetParentToken", MetaDataImport::GetParentToken) - FCFuncElement("_GetParamDefProps", MetaDataImport::GetParamDefProps) - FCFuncElement("_GetGenericParamProps", MetaDataImport::GetGenericParamProps) - - FCFuncElement("_Enum", MetaDataImport::Enum) - FCFuncElement("_GetMemberRefProps", MetaDataImport::GetMemberRefProps) - FCFuncElement("_GetCustomAttributeProps", MetaDataImport::GetCustomAttributeProps) - FCFuncElement("_GetFieldOffset", MetaDataImport::GetFieldOffset) - - FCFuncElement("_GetSigOfFieldDef", MetaDataImport::GetSigOfFieldDef) - FCFuncElement("_GetSigOfMethodDef", MetaDataImport::GetSigOfMethodDef) - FCFuncElement("_GetFieldMarshal", MetaDataImport::GetFieldMarshal) - FCFuncElement("_GetPInvokeMap", MetaDataImport::GetPinvokeMap) - FCFuncElement("_IsValidToken", MetaDataImport::IsValidToken) - FCFuncElement("_GetMarshalAs", MetaDataImport::GetMarshalAs) + FCFuncElement("GetMetadataImport", MetaDataImport::GetMetadataImport) + FCFuncElement("GetDefaultValue", MetaDataImport::GetDefaultValue) + FCFuncElement("GetName", MetaDataImport::GetName) + FCFuncElement("GetUserString", MetaDataImport::GetUserString) + FCFuncElement("GetScopeProps", MetaDataImport::GetScopeProps) + FCFuncElement("GetClassLayout", MetaDataImport::GetClassLayout) + FCFuncElement("GetSignatureFromToken", MetaDataImport::GetSignatureFromToken) + FCFuncElement("GetNamespace", MetaDataImport::GetNamespace) + FCFuncElement("GetEventProps", MetaDataImport::GetEventProps) + FCFuncElement("GetFieldDefProps", MetaDataImport::GetFieldDefProps) + FCFuncElement("GetPropertyProps", MetaDataImport::GetPropertyProps) + FCFuncElement("GetParentToken", MetaDataImport::GetParentToken) + FCFuncElement("GetParamDefProps", MetaDataImport::GetParamDefProps) + FCFuncElement("GetGenericParamProps", MetaDataImport::GetGenericParamProps) + + FCFuncElement("GetMemberRefProps", MetaDataImport::GetMemberRefProps) + FCFuncElement("GetCustomAttributeProps", MetaDataImport::GetCustomAttributeProps) + FCFuncElement("GetFieldOffset", MetaDataImport::GetFieldOffset) + + FCFuncElement("GetSigOfFieldDef", MetaDataImport::GetSigOfFieldDef) + FCFuncElement("GetSigOfMethodDef", MetaDataImport::GetSigOfMethodDef) + FCFuncElement("GetFieldMarshal", MetaDataImport::GetFieldMarshal) + FCFuncElement("GetPInvokeMap", MetaDataImport::GetPInvokeMap) + FCFuncElement("IsValidToken", MetaDataImport::IsValidToken) + FCFuncElement("GetMarshalAs", MetaDataImport::GetMarshalAs) FCFuncEnd() FCFuncStart(gSignatureNative) @@ -237,7 +236,6 @@ FCFuncEnd() FCFuncStart(gCOMModuleHandleFuncs) FCFuncElement("GetToken", ModuleHandle::GetToken) FCFuncElement("GetDynamicMethod", ModuleHandle::GetDynamicMethod) - FCFuncElement("_GetMetadataImport", ModuleHandle::GetMetadataImport) FCFuncElement("GetMDStreamVersion", ModuleHandle::GetMDStreamVersion) FCFuncEnd() diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index 9719e7e6dc1424..d7e6708757fd79 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -867,7 +867,7 @@ UINT_PTR ExceptionTracker::FinishSecondPass( void CleanUpForSecondPass(Thread* pThread, bool fIsSO, LPVOID MemoryStackFpForFrameChain, LPVOID MemoryStackFp); -static void PopExplicitFrames(Thread *pThread, void *targetSp) +static void PopExplicitFrames(Thread *pThread, void *targetSp, void *targetCallerSp) { Frame* pFrame = pThread->GetFrame(); while (pFrame < targetSp) @@ -877,6 +877,39 @@ static void PopExplicitFrames(Thread *pThread, void *targetSp) pFrame = pThread->GetFrame(); } + // Check if the pFrame is an active InlinedCallFrame inside of the target frame. It needs to be popped or inactivated depending + // on the target architecture / ready to run + if ((pFrame < targetCallerSp) && InlinedCallFrame::FrameHasActiveCall(pFrame)) + { + InlinedCallFrame* pInlinedCallFrame = (InlinedCallFrame*)pFrame; + // When unwinding an exception in ReadyToRun, the JIT_PInvokeEnd helper which unlinks the ICF from + // the thread will be skipped. This is because unlike jitted code, each pinvoke is wrapped by calls + // to the JIT_PInvokeBegin and JIT_PInvokeEnd helpers, which push and pop the ICF on the thread. The + // ICF is not linked at the method prolog and unlined at the epilog when running R2R code. Since the + // JIT_PInvokeEnd helper will be skipped, we need to unlink the ICF here. If the executing method + // has another pinvoke, it will re-link the ICF again when the JIT_PInvokeBegin helper is called. + TADDR returnAddress = pInlinedCallFrame->m_pCallerReturnAddress; +#ifdef USE_PER_FRAME_PINVOKE_INIT + // If we're setting up the frame for each P/Invoke for the given platform, + // then we do this for all P/Invokes except ones in IL stubs. + // IL stubs link the frame in for the whole stub, so if an exception is thrown during marshalling, + // the ICF will be on the frame chain and inactive. + if (!ExecutionManager::GetCodeMethodDesc(returnAddress)->IsILStub()) +#else + // If we aren't setting up the frame for each P/Invoke (instead setting up once per method), + // then ReadyToRun code is the only code using the per-P/Invoke logic. + if (ExecutionManager::IsReadyToRunCode(returnAddress)) +#endif + { + pFrame->ExceptionUnwind(); + pFrame->Pop(pThread); + } + else + { + pInlinedCallFrame->Reset(); + } + } + GCFrame* pGCFrame = pThread->GetGCFrame(); while (pGCFrame && pGCFrame < targetSp) { @@ -907,8 +940,8 @@ ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord, if ((pExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)) { GCX_COOP(); - PopExplicitFrames(pThread, (void*)GetSP(pContextRecord)); - ExInfo::PopExInfos(pThread, (void*)GetSP(pContextRecord)); + PopExplicitFrames(pThread, (void*)pDispatcherContext->EstablisherFrame, (void*)GetSP(pDispatcherContext->ContextRecord)); + ExInfo::PopExInfos(pThread, (void*)pDispatcherContext->EstablisherFrame); } return ExceptionContinueSearch; } @@ -7215,7 +7248,7 @@ StackFrame ExceptionTracker::FindParentStackFrameHelper(CrawlFrame* pCF, { sfResult = (StackFrame)pCurrentExInfo->m_csfEnclosingClause; break; - } + } } goto lExit; @@ -7559,7 +7592,7 @@ void MarkInlinedCallFrameAsFuncletCall(Frame* pFrame) { _ASSERTE(pFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr()); InlinedCallFrame* pInlinedCallFrame = (InlinedCallFrame*)pFrame; - pInlinedCallFrame->m_Datum = (PTR_NDirectMethodDesc)((TADDR)pInlinedCallFrame->m_Datum | (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper | (TADDR)InlinedCallFrameMarker::SecondPassFuncletCaller); + pInlinedCallFrame->m_Datum = (PTR_NDirectMethodDesc)((TADDR)pInlinedCallFrame->m_Datum | (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper | (TADDR)InlinedCallFrameMarker::SecondPassFuncletCaller); } // Mark the pinvoke frame as invoking any exception handling helper @@ -7582,7 +7615,7 @@ static TADDR GetSpForDiagnosticReporting(REGDISPLAY *pRD) extern "C" void QCALLTYPE AppendExceptionStackFrame(QCall::ObjectHandleOnStack exceptionObj, SIZE_T ip, SIZE_T sp, int flags, ExInfo *pExInfo) { QCALL_CONTRACT; - + BEGIN_QCALL; Thread* pThread = GET_THREAD(); @@ -7622,7 +7655,7 @@ extern "C" void QCALLTYPE AppendExceptionStackFrame(QCall::ObjectHandleOnStack e UINT_PTR GetEstablisherFrame(REGDISPLAY* pvRegDisplay, ExInfo* exInfo) { -#ifdef HOST_AMD64 +#ifdef HOST_AMD64 _ASSERTE(exInfo->m_frameIter.m_crawl.GetRegisterSet() == pvRegDisplay); if (exInfo->m_frameIter.m_crawl.GetCodeInfo()->HasFrameRegister()) { @@ -7643,7 +7676,7 @@ UINT_PTR GetEstablisherFrame(REGDISPLAY* pvRegDisplay, ExInfo* exInfo) return pvRegDisplay->SP; #elif defined(HOST_LOONGARCH64) return pvRegDisplay->SP; -#endif +#endif } extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptionObj, BYTE* pHandlerIP, REGDISPLAY* pvRegDisplay, ExInfo* exInfo) @@ -7661,6 +7694,7 @@ extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptio HandlerFn* pfnHandler = (HandlerFn*)pHandlerIP; exInfo->m_ScannedStackRange.ExtendUpperBound(exInfo->m_frameIter.m_crawl.GetRegisterSet()->SP); DWORD_PTR dwResumePC = 0; + UINT_PTR callerTargetSp = 0; if (pHandlerIP != NULL) { @@ -7669,7 +7703,7 @@ extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptio throwable = PossiblyUnwrapThrowable(throwable, exInfo->m_frameIter.m_crawl.GetAssembly()); UINT_PTR establisherFrame = GetEstablisherFrame(pvRegDisplay, exInfo); - + exInfo->m_csfEHClause = CallerStackFrame((UINT_PTR)GetCurrentSP()); exInfo->m_csfEnclosingClause = CallerStackFrame::FromRegDisplay(exInfo->m_frameIter.m_crawl.GetRegisterSet()); @@ -7679,7 +7713,7 @@ extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptio exInfo->MakeCallbacksRelatedToHandler(true, pThread, pMD, &exInfo->m_ClauseForCatch, (DWORD_PTR)pHandlerIP, spForDebugger); #ifdef USE_FUNCLET_CALL_HELPER - // Invoke the catch funclet. + // Invoke the catch funclet. // Since the actual caller of the funclet is the assembly helper, pass the reference // to the CallerStackFrame instance so that it can be updated. CallerStackFrame* pCallerStackFrame = &exInfo->m_csfEHClause; @@ -7690,14 +7724,15 @@ extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptio pFuncletCallerSP); #else dwResumePC = pfnHandler(establisherFrame, OBJECTREFToObject(throwable)); -#endif +#endif // Profiler, debugger and ETW events exInfo->MakeCallbacksRelatedToHandler(false, pThread, pMD, &exInfo->m_ClauseForCatch, (DWORD_PTR)pHandlerIP, spForDebugger); SetIP(pvRegDisplay->pCurrentContext, dwResumePC); + callerTargetSp = CallerStackFrame::FromRegDisplay(pvRegDisplay).SP; } UINT_PTR targetSp = GetSP(pvRegDisplay->pCurrentContext); - PopExplicitFrames(pThread, (void*)targetSp); + PopExplicitFrames(pThread, (void*)targetSp, (void*)callerTargetSp); ExInfo* pExInfo = (PTR_ExInfo)pThread->GetExceptionState()->GetCurrentExceptionTracker(); @@ -7786,7 +7821,7 @@ extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptio { if (fIntercepted) { - ClrRestoreNonvolatileContext(pvRegDisplay->pCurrentContext); + ClrRestoreNonvolatileContext(pvRegDisplay->pCurrentContext); } #ifdef HOST_UNIX if (propagateExceptionCallback) @@ -7818,7 +7853,7 @@ extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptio SetSP(pvRegDisplay->pCurrentContext, targetSp - 8); #elif defined(HOST_X86) SetSP(pvRegDisplay->pCurrentContext, targetSp - 4); -#endif +#endif #ifdef HOST_AMD64 #ifdef UNIX_AMD64_ABI #define FIRST_ARG_REG Rdi @@ -7850,13 +7885,14 @@ extern "C" void QCALLTYPE ResumeAtInterceptionLocation(REGDISPLAY* pvRegDisplay) Frame* pFrame = pThread->GetFrame(); MarkInlinedCallFrameAsFuncletCall(pFrame); - + UINT_PTR targetSp = GetSP(pvRegDisplay->pCurrentContext); ExInfo *pExInfo = (PTR_ExInfo)pThread->GetExceptionState()->GetCurrentExceptionTracker(); pExInfo->m_ScannedStackRange.ExtendUpperBound(targetSp); - PopExplicitFrames(pThread, (void*)targetSp); + EECodeManager::EnsureCallerContextIsValid(pvRegDisplay); + PopExplicitFrames(pThread, (void*)targetSp, (void*)CallerStackFrame::FromRegDisplay(pvRegDisplay).SP); // This must be done before we pop the ExInfos. BOOL fIntercepted = pThread->GetExceptionState()->GetFlags()->DebuggerInterceptInfo(); @@ -7883,7 +7919,7 @@ extern "C" void QCALLTYPE ResumeAtInterceptionLocation(REGDISPLAY* pvRegDisplay) uResumePC = codeInfo.GetJitManager()->GetCodeAddressForRelOffset(codeInfo.GetMethodToken(), static_cast(ulRelOffset)); SetIP(pvRegDisplay->pCurrentContext, uResumePC); - ClrRestoreNonvolatileContext(pvRegDisplay->pCurrentContext); + ClrRestoreNonvolatileContext(pvRegDisplay->pCurrentContext); } extern "C" void QCALLTYPE CallFinallyFunclet(BYTE* pHandlerIP, REGDISPLAY* pvRegDisplay, ExInfo* exInfo) @@ -7908,7 +7944,7 @@ extern "C" void QCALLTYPE CallFinallyFunclet(BYTE* pHandlerIP, REGDISPLAY* pvReg TADDR spForDebugger = GetSpForDiagnosticReporting(pvRegDisplay); exInfo->MakeCallbacksRelatedToHandler(true, pThread, pMD, &exInfo->m_CurrentClause, (DWORD_PTR)pHandlerIP, spForDebugger); #ifdef USE_FUNCLET_CALL_HELPER - // Invoke the finally funclet. + // Invoke the finally funclet. // Since the actual caller of the funclet is the assembly helper, pass the reference // to the CallerStackFrame instance so that it can be updated. CallerStackFrame* pCallerStackFrame = &exInfo->m_csfEHClause; @@ -7919,7 +7955,7 @@ extern "C" void QCALLTYPE CallFinallyFunclet(BYTE* pHandlerIP, REGDISPLAY* pvReg pFuncletCallerSP); #else DWORD_PTR dwResumePC = pfnHandler(establisherFrame, NULL); -#endif +#endif pThread->IncPreventAbort(); @@ -7956,7 +7992,7 @@ extern "C" BOOL QCALLTYPE CallFilterFunclet(QCall::ObjectHandleOnStack exception EX_TRY { #ifdef USE_FUNCLET_CALL_HELPER - // Invoke the filter funclet. + // Invoke the filter funclet. // Since the actual caller of the funclet is the assembly helper, pass the reference // to the CallerStackFrame instance so that it can be updated. CallerStackFrame* pCallerStackFrame = &pExInfo->m_csfEHClause; @@ -8403,7 +8439,7 @@ extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideCla else { // TODO-NewEH: Currently there are two other cases of internal VM->managed transitions. The FastCallFinalize and COMToCLRDispatchHelperWithStack - // Either add handling those here as well or rewrite all these perf critical places in C#, so that CallDescrWorker is the only path that + // Either add handling those here as well or rewrite all these perf critical places in C#, so that CallDescrWorker is the only path that // needs to be handled here. size_t CallDescrWorkerInternalReturnAddress = (size_t)CallDescrWorkerInternal + CallDescrWorkerInternalReturnAddressOffset; if (GetIP(pThis->m_crawl.GetRegisterSet()->pCallerContext) == CallDescrWorkerInternalReturnAddress) @@ -8490,7 +8526,7 @@ extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideCla { // Unwind the CallCatchFunclet retVal = MoveToNextNonSkippedFrame(pThis); - + if (retVal == SWA_FAILED) { _ASSERTE_MSG(FALSE, "StackFrameIterator::Next failed"); diff --git a/src/coreclr/vm/gc_unwind_x86.inl b/src/coreclr/vm/gc_unwind_x86.inl index 017f8f8f803a9e..33604336d28c52 100644 --- a/src/coreclr/vm/gc_unwind_x86.inl +++ b/src/coreclr/vm/gc_unwind_x86.inl @@ -1670,10 +1670,7 @@ unsigned scanArgRegTableI(PTR_CBYTE table, { thisPtrReg = REGI_NA; } - if (iptrRegs & regMask) - { - iptrRegs &= ~regMask; - } + iptrRegs &= ~regMask; } iptr = isThis = false; continue; diff --git a/src/coreclr/vm/i386/asmconstants.h b/src/coreclr/vm/i386/asmconstants.h index edafbdf72ae717..475a0f857ebd98 100644 --- a/src/coreclr/vm/i386/asmconstants.h +++ b/src/coreclr/vm/i386/asmconstants.h @@ -233,13 +233,6 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__FrameHandlerExRecord__m_pEntryFrame == offsetof( #endif - -#define MethodDesc_m_wFlags DBG_FRE(0x1a, 0x06) -ASMCONSTANTS_C_ASSERT(MethodDesc_m_wFlags == offsetof(MethodDesc, m_wFlags)) - -#define MethodDesc_mdcClassification 7 -ASMCONSTANTS_C_ASSERT(MethodDesc_mdcClassification == mdcClassification) - #define ComPlusCallMethodDesc__m_pComPlusCallInfo DBG_FRE(0x1C, 0x8) ASMCONSTANTS_C_ASSERT(ComPlusCallMethodDesc__m_pComPlusCallInfo == offsetof(ComPlusCallMethodDesc, m_pComPlusCallInfo)) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 7400708001589f..05d2ad18b5bd94 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -55,8 +55,8 @@ #ifndef FEATURE_EH_FUNCLETS #include "excep.h" #endif - #include "exinfo.h" +#include "arraynative.inl" using std::isfinite; using std::isnan; @@ -4779,21 +4779,6 @@ HCIMPLEND // //======================================================================== -/*************************************************************/ -HCIMPL3(VOID, JIT_StructWriteBarrier, void *dest, void* src, CORINFO_CLASS_HANDLE typeHnd_) -{ - FCALL_CONTRACT; - - TypeHandle typeHnd(typeHnd_); - MethodTable *pMT = typeHnd.AsMethodTable(); - - HELPER_METHOD_FRAME_BEGIN_NOPOLL(); // Set up a frame - CopyValueClass(dest, src, pMT); - HELPER_METHOD_FRAME_END_POLL(); - -} -HCIMPLEND - /*************************************************************/ // Slow helper to tailcall from the fast one NOINLINE HCIMPL0(void, JIT_PollGC_Framed) @@ -5144,7 +5129,7 @@ void JIT_Patchpoint(int* counter, int ilOffset) const int counterBump = g_pConfig->OSR_CounterBump(); *counter = counterBump; -#if _DEBUG +#ifdef _DEBUG const int ppId = ppInfo->m_patchpointId; #endif @@ -5389,6 +5374,12 @@ void JIT_Patchpoint(int* counter, int ilOffset) // Install new entry point as IP SetIP(pFrameContext, osrMethodCode); +#ifdef _DEBUG + // Keep this context around to aid in debugging OSR transition problems + static CONTEXT s_lastOSRTransitionContext; + s_lastOSRTransitionContext = *pFrameContext; +#endif + // Restore last error (since call below does not return) // END_PRESERVE_LAST_ERROR; ::SetLastError(dwLastError); @@ -5425,7 +5416,7 @@ HCIMPL1(VOID, JIT_PartialCompilationPatchpoint, int ilOffset) // Patchpoint identity is the helper return address PCODE ip = (PCODE)_ReturnAddress(); -#if _DEBUG +#ifdef _DEBUG // Friendly ID number int ppId = 0; #endif @@ -5439,7 +5430,7 @@ HCIMPL1(VOID, JIT_PartialCompilationPatchpoint, int ilOffset) OnStackReplacementManager* manager = allocator->GetOnStackReplacementManager(); ppInfo = manager->GetPerPatchpointInfo(ip); -#if _DEBUG +#ifdef _DEBUG ppId = ppInfo->m_patchpointId; #endif diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index dd61fff1cf8870..394b87a1873965 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -12075,23 +12075,6 @@ HRESULT CEEJitInfo::allocPgoInstrumentationBySchema( JIT_TO_EE_TRANSITION(); - // We need to know the code size. Typically we can get the code size - // from m_ILHeader. For dynamic methods, m_ILHeader will be NULL, so - // for that case we need to use DynamicResolver to get the code size. - - unsigned codeSize = 0; - if (m_pMethodBeingCompiled->IsDynamicMethod()) - { - unsigned stackSize, ehSize; - CorInfoOptions options; - DynamicResolver * pResolver = m_pMethodBeingCompiled->AsDynamicMethodDesc()->GetResolver(); - pResolver->GetCodeInfo(&codeSize, &stackSize, &options, &ehSize); - } - else - { - codeSize = m_ILHeader->GetCodeSize(); - } - #ifdef FEATURE_PGO hr = PgoManager::allocPgoInstrumentationBySchema(m_pMethodBeingCompiled, pSchema, countSchemaItems, pInstrumentationData); #else @@ -12111,7 +12094,8 @@ HRESULT CEEJitInfo::getPgoInstrumentationResults( PgoInstrumentationSchema **pSchema, // pointer to the schema table which describes the instrumentation results (pointer will not remain valid after jit completes) uint32_t * pCountSchemaItems, // pointer to the count schema items uint8_t ** pInstrumentationData, // pointer to the actual instrumentation data (pointer will not remain valid after jit completes) - PgoSource * pPgoSource // source of pgo data + PgoSource * pPgoSource, // source of pgo data + bool * pDynamicPgo // true if Dynamic PGO is enabled ) { CONTRACTL { @@ -12124,6 +12108,7 @@ HRESULT CEEJitInfo::getPgoInstrumentationResults( *pCountSchemaItems = 0; *pInstrumentationData = NULL; *pPgoSource = PgoSource::Unknown; + *pDynamicPgo = g_pConfig->TieredPGO(); JIT_TO_EE_TRANSITION(); @@ -14417,7 +14402,8 @@ HRESULT CEEInfo::getPgoInstrumentationResults( PgoInstrumentationSchema **pSchema, // pointer to the schema table which describes the instrumentation results (pointer will not remain valid after jit completes) uint32_t * pCountSchemaItems, // pointer to the count schema items uint8_t ** pInstrumentationData, // pointer to the actual instrumentation data (pointer will not remain valid after jit completes) - PgoSource * pPgoSource + PgoSource * pPgoSource, + bool * pDynamicPgo ) { LIMITED_METHOD_CONTRACT; diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 754d04d5554279..a8266d6b79b275 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -643,7 +643,8 @@ class CEEJitInfo : public CEEInfo PgoInstrumentationSchema** pSchema, /* OUT */ uint32_t* pCountSchemaItems, /* OUT */ uint8_t**pInstrumentationData, /* OUT */ - PgoSource *pPgoSource /* OUT */ + PgoSource *pPgoSource, /* OUT */ + bool* pDynamicPgo /* OUT */ ) override final; void recordCallSite( diff --git a/src/coreclr/vm/managedmdimport.cpp b/src/coreclr/vm/managedmdimport.cpp index 622e74edb994d1..8ab00a85f5320c 100644 --- a/src/coreclr/vm/managedmdimport.cpp +++ b/src/coreclr/vm/managedmdimport.cpp @@ -7,281 +7,169 @@ #include "managedmdimport.hpp" #include "wrappers.h" -void ThrowMetaDataImportException(HRESULT hr) -{ - WRAPPER_NO_CONTRACT; - - if (hr == CLDB_E_RECORD_NOTFOUND) - return; - - MethodDescCallSite throwError(METHOD__METADATA_IMPORT__THROW_ERROR); - - ARG_SLOT args[] = { (ARG_SLOT)hr }; - throwError.Call(args); -} - // // MetaDataImport // extern BOOL ParseNativeTypeInfo(NativeTypeParamInfo* pInfo, PCCOR_SIGNATURE pvNativeType, ULONG cbNativeType); -FCIMPL11(void, MetaDataImport::GetMarshalAs, - BYTE* pvNativeType, - ULONG cbNativeType, - INT32* unmanagedType, - INT32* safeArraySubType, - STRINGREF* safeArrayUserDefinedSubType, - INT32* arraySubType, - INT32* sizeParamIndex, - INT32* sizeConst, - STRINGREF* marshalType, - STRINGREF* marshalCookie, - INT32* iidParamIndex) +FCIMPL11(FC_BOOL_RET, MetaDataImport::GetMarshalAs, + BYTE* pvNativeType, + ULONG cbNativeType, + INT32* unmanagedType, + INT32* safeArraySubType, + LPUTF8* safeArrayUserDefinedSubType, + INT32* arraySubType, + INT32* sizeParamIndex, + INT32* sizeConst, + LPUTF8* marshalType, + LPUTF8* marshalCookie, + INT32* iidParamIndex) { FCALL_CONTRACT; - HELPER_METHOD_FRAME_BEGIN_0(); - { - NativeTypeParamInfo info; - - ZeroMemory(&info, sizeof(NativeTypeParamInfo)); + NativeTypeParamInfo info{}; - if (!ParseNativeTypeInfo(&info, pvNativeType, cbNativeType)) - { - ThrowMetaDataImportException(E_FAIL); - } + // The zeroing out of memory is important. The Reflection API's + // instantiation of MarshalAsAttribute doesn't reflect the default + // values the interop subsystem uses. This means NativeTypeParamInfo's + // constructor initialization values need to be overridden by zero + // initialization. + ZeroMemory(&info, sizeof(info)); + if (!ParseNativeTypeInfo(&info, pvNativeType, cbNativeType)) + { + FC_RETURN_BOOL(FALSE); + } - *unmanagedType = info.m_NativeType; - *sizeParamIndex = info.m_CountParamIdx; - *sizeConst = info.m_Additive; - *arraySubType = info.m_ArrayElementType; + *unmanagedType = info.m_NativeType; + *sizeParamIndex = info.m_CountParamIdx; + *sizeConst = info.m_Additive; + *arraySubType = info.m_ArrayElementType; #ifdef FEATURE_COMINTEROP - *iidParamIndex = info.m_IidParamIndex; + *iidParamIndex = info.m_IidParamIndex; - *safeArraySubType = info.m_SafeArrayElementVT; + *safeArraySubType = info.m_SafeArrayElementVT; - *safeArrayUserDefinedSubType = info.m_strSafeArrayUserDefTypeName == NULL ? NULL : - StringObject::NewString(info.m_strSafeArrayUserDefTypeName, info.m_cSafeArrayUserDefTypeNameBytes); + *safeArrayUserDefinedSubType = info.m_strSafeArrayUserDefTypeName; #else - *iidParamIndex = 0; + *iidParamIndex = 0; - *safeArraySubType = VT_EMPTY; + *safeArraySubType = VT_EMPTY; - *safeArrayUserDefinedSubType = NULL; + *safeArrayUserDefinedSubType = NULL; #endif - *marshalType = info.m_strCMMarshalerTypeName == NULL ? NULL : - StringObject::NewString(info.m_strCMMarshalerTypeName, info.m_cCMMarshalerTypeNameBytes); + *marshalType = info.m_strCMMarshalerTypeName; - *marshalCookie = info.m_strCMCookie == NULL ? NULL : - StringObject::NewString(info.m_strCMCookie, info.m_cCMCookieStrBytes); - } - HELPER_METHOD_FRAME_END(); + *marshalCookie = info.m_strCMCookie; + + FC_RETURN_BOOL(TRUE); } FCIMPLEND -MDImpl4(Object *, MetaDataImport::GetDefaultValue, mdToken tk, INT64* pDefaultValue, INT32* pLength, INT32* pCorElementType) +FCIMPL1(IMDInternalImport*, MetaDataImport::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE) { FCALL_CONTRACT; - HRESULT hr = S_OK; - Object *pRetVal = NULL; + REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE); + Module *pModule = refModule->GetModule(); + return pModule->GetMDImport(); +} +FCIMPLEND + +FCIMPL6(HRESULT, MetaDataImport::GetDefaultValue, IMDInternalImport* pScope, mdToken tk, INT64* pDefaultValue, LPCWSTR* pStringValue, INT32* pLength, INT32* pCorElementType) +{ + FCALL_CONTRACT; - IMDInternalImport *_pScope = pScope; + HRESULT hr = S_OK; MDDefaultValue value; - IfFailGo(_pScope->GetDefaultValue(tk, &value)); - - // We treat string values differently. That's because on big-endian architectures we can't return a - // pointer to static string data in the metadata, we have to buffer the string in order to byte-swap - // all the unicode characters. MDDefaultValue therefore has a destructor on big-endian machines which - // reclaims this buffer, implying we can't safely return the embedded pointer to managed code. - // The easiest thing for us to do is to construct the managed string object here, in the context of - // the still valid MDDefaultValue. We can't return a managed object via the normal out parameter - // because it won't be GC protected, so in this special case null the output parameter and return - // the string via the protected return result (which is null for all other cases). + IfFailGo(pScope->GetDefaultValue(tk, &value)); + if (value.m_bType == ELEMENT_TYPE_STRING) { - HELPER_METHOD_FRAME_BEGIN_RET_0(); *pDefaultValue = 0; - STRINGREF refRetval = StringObject::NewString(value.m_wzValue, value.m_cbSize / sizeof(WCHAR)); - pRetVal = STRINGREFToObject(refRetval); - HELPER_METHOD_FRAME_END(); + *pStringValue = value.m_wzValue; + *pLength = (INT32)value.m_cbSize / sizeof(WCHAR); // Length of string in character units } else { *pDefaultValue = value.m_ullValue; + *pStringValue = NULL; + *pLength = (INT32)value.m_cbSize; } - *pCorElementType = (UINT32)value.m_bType; - *pLength = (INT32)value.m_cbSize; -ErrExit: - if (FAILED(hr)) - { - FCThrow(kBadImageFormatException); - } - return pRetVal; +ErrExit: + return hr; } FCIMPLEND -MDImpl3(void, MetaDataImport::GetCustomAttributeProps, mdCustomAttribute cv, mdToken* ptkType, ConstArray* ppBlob) +FCIMPL4(HRESULT, MetaDataImport::GetCustomAttributeProps, IMDInternalImport* pScope, mdCustomAttribute cv, mdToken* ptkType, ConstArray* ppBlob) { FCALL_CONTRACT; HRESULT hr = S_OK; - IMDInternalImport *_pScope = pScope; - - IfFailGo(_pScope->GetCustomAttributeProps(cv, ptkType)); - IfFailGo(_pScope->GetCustomAttributeAsBlob(cv, (const void **)&ppBlob->m_array, (ULONG *)&ppBlob->m_count)); + IfFailGo(pScope->GetCustomAttributeProps(cv, ptkType)); + IfFailGo(pScope->GetCustomAttributeAsBlob(cv, (const void **)&ppBlob->m_array, (ULONG *)&ppBlob->m_count)); ErrExit: - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } -} -FCIMPLEND - -static int * EnsureResultSize(MetadataEnumResult * pResult, ULONG length) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - int * p; - - if (length >= ARRAY_SIZE(pResult->smallResult) || DbgRandomOnExe(.01)) - { - pResult->largeResult = (I4Array *)OBJECTREFToObject(AllocatePrimitiveArray(ELEMENT_TYPE_I4, length)); - p = pResult->largeResult->GetDirectPointerToNonObjectElements(); - } - else - { - ZeroMemory(pResult->smallResult, sizeof(pResult->smallResult)); - pResult->largeResult = NULL; - p = pResult->smallResult; - } - - pResult->length = length; - return p; -} - -MDImpl3(void, MetaDataImport::Enum, mdToken type, mdToken tkParent, MetadataEnumResult * pResult) -{ - CONTRACTL { - FCALL_CHECK; - PRECONDITION(pResult != NULL); - } - CONTRACTL_END; - - HELPER_METHOD_FRAME_BEGIN_0(); - { - IMDInternalImport *_pScope = pScope; - - if (type == mdtTypeDef) - { - ULONG nestedClassesCount; - IfFailThrow(_pScope->GetCountNestedClasses(tkParent, &nestedClassesCount)); - - mdTypeDef* arToken = (mdTypeDef*)EnsureResultSize(pResult, nestedClassesCount); - IfFailThrow(_pScope->GetNestedClasses(tkParent, arToken, nestedClassesCount, &nestedClassesCount)); - } - else if (type == mdtMethodDef && (TypeFromToken(tkParent) == mdtProperty || TypeFromToken(tkParent) == mdtEvent)) - { - HENUMInternalHolder hEnum(pScope); - hEnum.EnumAssociateInit(tkParent); - - ULONG associatesCount = hEnum.EnumGetCount(); - - static_assert_no_msg(sizeof(ASSOCIATE_RECORD) == 2 * sizeof(int)); - - ASSOCIATE_RECORD* arAssocRecord = (ASSOCIATE_RECORD*)EnsureResultSize(pResult, 2 * associatesCount); - IfFailThrow(_pScope->GetAllAssociates(&hEnum, arAssocRecord, associatesCount)); - } - else - { - HENUMInternalHolder hEnum(pScope); - hEnum.EnumInit(type, tkParent); - - ULONG count = hEnum.EnumGetCount(); - - mdToken* arToken = (mdToken*)EnsureResultSize(pResult, count); - for(COUNT_T i = 0; i < count && _pScope->EnumNext(&hEnum, &arToken[i]); i++); - } - } - HELPER_METHOD_FRAME_END(); + return hr; } FCIMPLEND #if defined(_MSC_VER) && defined(TARGET_X86) -#pragma optimize("y", on) // Small critical routines, don't put in EBP frame +#pragma optimize("y", on) // Small critical routines, don't put in EBP frame #endif -MDImpl1(FC_BOOL_RET, MetaDataImport::IsValidToken, mdToken tk) +FCIMPL2(FC_BOOL_RET, MetaDataImport::IsValidToken, IMDInternalImport* pScope, mdToken tk) { FCALL_CONTRACT; - IMDInternalImport *_pScope = pScope; - - FC_RETURN_BOOL(_pScope->IsValidToken(tk)); + FC_RETURN_BOOL(pScope->IsValidToken(tk)); } FCIMPLEND - -MDImpl3(void, MetaDataImport::GetClassLayout, mdTypeDef td, DWORD* pdwPackSize, ULONG* pulClassSize) +FCIMPL4(HRESULT, MetaDataImport::GetClassLayout, IMDInternalImport* pScope, mdTypeDef td, DWORD* pdwPackSize, ULONG* pulClassSize) { FCALL_CONTRACT; HRESULT hr = S_OK; + if (pdwPackSize != NULL) { - IMDInternalImport *_pScope = pScope; - - if (pdwPackSize != NULL) + hr = pScope->GetClassPackSize(td, (ULONG *)pdwPackSize); + if (hr == CLDB_E_RECORD_NOTFOUND) { - hr = _pScope->GetClassPackSize(td, (ULONG *)pdwPackSize); - if (hr == CLDB_E_RECORD_NOTFOUND) - { - *pdwPackSize = 0; - hr = S_OK; - } - IfFailGo(hr); + *pdwPackSize = 0; + hr = S_OK; } + IfFailGo(hr); + } - if (pulClassSize != NULL) + if (pulClassSize != NULL) + { + hr = pScope->GetClassTotalSize(td, pulClassSize); + if (hr == CLDB_E_RECORD_NOTFOUND) { - hr = _pScope->GetClassTotalSize(td, pulClassSize); - if (hr == CLDB_E_RECORD_NOTFOUND) - { - *pulClassSize = 0; - hr = S_OK; - } - IfFailGo(hr); + *pulClassSize = 0; + hr = S_OK; } + IfFailGo(hr); } ErrExit: - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return hr; } FCIMPLEND -MDImpl3(FC_BOOL_RET, MetaDataImport::GetFieldOffset, mdTypeDef td, mdFieldDef target, DWORD* pdwFieldOffset) +FCIMPL5(HRESULT, MetaDataImport::GetFieldOffset, IMDInternalImport* pScope, mdTypeDef td, mdFieldDef target, DWORD* pdwFieldOffset, CLR_BOOL* found) { FCALL_CONTRACT; HRESULT hr = S_OK; - IMDInternalImport *_pScope = pScope; MD_CLASS_LAYOUT layout; - BOOL retVal = FALSE; + *found = FALSE; - IfFailGo(_pScope->GetClassLayoutInit(td, &layout)); + IfFailGo(pScope->GetClassLayoutInit(td, &layout)); ULONG cFieldOffset; cFieldOffset = layout.m_ridFieldEnd - layout.m_ridFieldCur; @@ -290,147 +178,108 @@ MDImpl3(FC_BOOL_RET, MetaDataImport::GetFieldOffset, mdTypeDef td, mdFieldDef ta { mdFieldDef fd; ULONG offset; - IfFailGo(_pScope->GetClassLayoutNext(&layout, &fd, &offset)); + IfFailGo(pScope->GetClassLayoutNext(&layout, &fd, &offset)); if (fd == target) { *pdwFieldOffset = offset; - retVal = TRUE; + *found = TRUE; break; } } ErrExit: - if (FAILED(hr)) - { - FCThrow(kBadImageFormatException); - } - FC_RETURN_BOOL(retVal); + return hr; } FCIMPLEND -MDImpl3(void, MetaDataImport::GetUserString, mdToken tk, LPCSTR* pszName, ULONG* pCount) +FCIMPL4(HRESULT, MetaDataImport::GetUserString, IMDInternalImport* pScope, mdToken tk, LPCWSTR* pszName, ULONG* pCount) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; BOOL bHasExtendedChars; - - hr = _pScope->GetUserString(tk, pCount, &bHasExtendedChars, (LPCWSTR *)pszName); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetUserString(tk, pCount, &bHasExtendedChars, pszName); } FCIMPLEND -MDImpl2(void, MetaDataImport::GetName, mdToken tk, LPCSTR* pszName) +FCIMPL3(HRESULT, MetaDataImport::GetName, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName) { FCALL_CONTRACT; HRESULT hr = S_OK; - IMDInternalImport *_pScope = pScope; if (TypeFromToken(tk) == mdtMethodDef) { - hr = _pScope->GetNameOfMethodDef(tk, pszName); + hr = pScope->GetNameOfMethodDef(tk, pszName); } else if (TypeFromToken(tk) == mdtParamDef) { USHORT seq; DWORD attr; - hr = _pScope->GetParamDefProps(tk, &seq, &attr, pszName); + hr = pScope->GetParamDefProps(tk, &seq, &attr, pszName); } else if (TypeFromToken(tk) == mdtFieldDef) { - hr = _pScope->GetNameOfFieldDef(tk, pszName); + hr = pScope->GetNameOfFieldDef(tk, pszName); } else if (TypeFromToken(tk) == mdtProperty) { - hr = _pScope->GetPropertyProps(tk, pszName, NULL, NULL, NULL); + hr = pScope->GetPropertyProps(tk, pszName, NULL, NULL, NULL); } else if (TypeFromToken(tk) == mdtEvent) { - hr = _pScope->GetEventProps(tk, pszName, NULL, NULL); + hr = pScope->GetEventProps(tk, pszName, NULL, NULL); } else if (TypeFromToken(tk) == mdtModule) { - hr = _pScope->GetModuleRefProps(tk, pszName); + hr = pScope->GetModuleRefProps(tk, pszName); } else if (TypeFromToken(tk) == mdtTypeDef) { LPCSTR szNamespace = NULL; - hr = _pScope->GetNameOfTypeDef(tk, pszName, &szNamespace); + hr = pScope->GetNameOfTypeDef(tk, pszName, &szNamespace); } else { hr = E_FAIL; } - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return hr; } FCIMPLEND -MDImpl2(void, MetaDataImport::GetNamespace, mdToken tk, LPCSTR* pszName) +FCIMPL3(HRESULT, MetaDataImport::GetNamespace, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; LPCSTR szName = NULL; - - hr = _pScope->GetNameOfTypeDef(tk, &szName, pszName); - - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetNameOfTypeDef(tk, &szName, pszName); } FCIMPLEND - -MDImpl2(void, MetaDataImport::GetGenericParamProps, mdToken tk, DWORD* pAttributes) +FCIMPL3(HRESULT, MetaDataImport::GetGenericParamProps, IMDInternalImport* pScope, mdToken tk, DWORD* pAttributes) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; - - hr = _pScope->GetGenericParamProps(tk, NULL, pAttributes, NULL, NULL, NULL); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetGenericParamProps(tk, NULL, pAttributes, NULL, NULL, NULL); } FCIMPLEND -MDImpl3(void, MetaDataImport::GetEventProps, mdToken tk, LPCSTR* pszName, INT32 *pdwEventFlags) +FCIMPL4(HRESULT, MetaDataImport::GetEventProps, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName, INT32 *pdwEventFlags) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; - - hr = _pScope->GetEventProps(tk, pszName, (DWORD*)pdwEventFlags, NULL); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetEventProps(tk, pszName, (DWORD*)pdwEventFlags, NULL); } FCIMPLEND -MDImpl4(void, MetaDataImport::GetPinvokeMap, mdToken tk, DWORD* pMappingFlags, LPCSTR* pszImportName, LPCSTR* pszImportDll) +FCIMPL5(HRESULT, MetaDataImport::GetPInvokeMap, IMDInternalImport* pScope, mdToken tk, DWORD* pMappingFlags, LPCSTR* pszImportName, LPCSTR* pszImportDll) { FCALL_CONTRACT; HRESULT hr; - IMDInternalImport *_pScope = pScope; mdModule tkModule; - hr = _pScope->GetPinvokeMap(tk, pMappingFlags, pszImportName, &tkModule); + hr = pScope->GetPinvokeMap(tk, pMappingFlags, pszImportName, &tkModule); if (FAILED(hr)) { *pMappingFlags = 0; @@ -440,29 +289,24 @@ MDImpl4(void, MetaDataImport::GetPinvokeMap, mdToken tk, DWORD* pMappingFlags, L } else { - hr = _pScope->GetModuleRefProps(tkModule, pszImportDll); - } - - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); + hr = pScope->GetModuleRefProps(tkModule, pszImportDll); } + return hr; } FCIMPLEND -MDImpl3(void, MetaDataImport::GetParamDefProps, mdToken tk, INT32* pSequence, INT32* pAttributes) +FCIMPL4(HRESULT, MetaDataImport::GetParamDefProps, IMDInternalImport* pScope, mdToken tk, INT32* pSequence, INT32* pAttributes) { FCALL_CONTRACT; HRESULT hr; - IMDInternalImport *_pScope = pScope; USHORT usSequence = 0; // Is this a valid token? - if (_pScope->IsValidToken((mdParamDef)tk)) + if (pScope->IsValidToken((mdParamDef)tk)) { LPCSTR szParamName; - hr = _pScope->GetParamDefProps(tk, &usSequence, (DWORD *)pAttributes, &szParamName); + hr = pScope->GetParamDefProps(tk, &usSequence, (DWORD *)pAttributes, &szParamName); } else { @@ -471,51 +315,33 @@ MDImpl3(void, MetaDataImport::GetParamDefProps, mdToken tk, INT32* pSequence, IN } *pSequence = (INT32) usSequence; - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return hr; } FCIMPLEND -MDImpl2(void, MetaDataImport::GetFieldDefProps, mdToken tk, INT32 *pdwFieldFlags) +FCIMPL3(HRESULT, MetaDataImport::GetFieldDefProps, IMDInternalImport* pScope, mdToken tk, INT32 *pdwFieldFlags) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; - - hr = _pScope->GetFieldDefProps(tk, (DWORD *)pdwFieldFlags); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetFieldDefProps(tk, (DWORD *)pdwFieldFlags); } FCIMPLEND -MDImpl4(void, MetaDataImport::GetPropertyProps, mdToken tk, LPCSTR* pszName, INT32 *pdwPropertyFlags, ConstArray* ppValue) +FCIMPL5(HRESULT, MetaDataImport::GetPropertyProps, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName, INT32 *pdwPropertyFlags, ConstArray* ppValue) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; - - hr = _pScope->GetPropertyProps(tk, pszName, (DWORD*)pdwPropertyFlags, (PCCOR_SIGNATURE*)&ppValue->m_array, (ULONG*)&ppValue->m_count); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } -} -FCIMPLEND + return pScope->GetPropertyProps(tk, pszName, (DWORD*)pdwPropertyFlags, (PCCOR_SIGNATURE*)&ppValue->m_array, (ULONG*)&ppValue->m_count); + } + FCIMPLEND -MDImpl2(void, MetaDataImport::GetFieldMarshal, mdToken tk, ConstArray* ppValue) +FCIMPL3(HRESULT, MetaDataImport::GetFieldMarshal, IMDInternalImport* pScope, mdToken tk, ConstArray* ppValue) { FCALL_CONTRACT; HRESULT hr; - IMDInternalImport *_pScope = pScope; - hr = _pScope->GetFieldMarshal(tk, (PCCOR_SIGNATURE *)&ppValue->m_array, (ULONG *)&ppValue->m_count); + hr = pScope->GetFieldMarshal(tk, (PCCOR_SIGNATURE *)&ppValue->m_array, (ULONG *)&ppValue->m_count); if (hr == CLDB_E_RECORD_NOTFOUND) { ppValue->m_array = NULL; @@ -523,69 +349,44 @@ MDImpl2(void, MetaDataImport::GetFieldMarshal, mdToken tk, ConstArray* ppValue) hr = S_OK; } - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return hr; } FCIMPLEND -MDImpl2(void, MetaDataImport::GetSigOfMethodDef, mdToken tk, ConstArray* ppValue) +FCIMPL3(HRESULT, MetaDataImport::GetSigOfMethodDef, IMDInternalImport* pScope, mdToken tk, ConstArray* ppValue) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; - - hr = _pScope->GetSigOfMethodDef(tk, (ULONG*)&ppValue->m_count, (PCCOR_SIGNATURE *)&ppValue->m_array); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetSigOfMethodDef(tk, (ULONG*)&ppValue->m_count, (PCCOR_SIGNATURE *)&ppValue->m_array); } FCIMPLEND -MDImpl2(void, MetaDataImport::GetSignatureFromToken, mdToken tk, ConstArray* ppValue) +FCIMPL3(HRESULT, MetaDataImport::GetSignatureFromToken, IMDInternalImport* pScope, mdToken tk, ConstArray* ppValue) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; - - hr = _pScope->GetSigFromToken(tk, (ULONG*)&ppValue->m_count, (PCCOR_SIGNATURE *)&(ppValue->m_array)); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetSigFromToken(tk, (ULONG*)&ppValue->m_count, (PCCOR_SIGNATURE *)&(ppValue->m_array)); } FCIMPLEND -MDImpl2(void, MetaDataImport::GetSigOfFieldDef, mdToken tk, ConstArray* ppValue) +FCIMPL3(HRESULT, MetaDataImport::GetSigOfFieldDef, IMDInternalImport* pScope, mdToken tk, ConstArray* ppValue) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; - - hr = _pScope->GetSigOfFieldDef(tk, (ULONG*)&ppValue->m_count, (PCCOR_SIGNATURE *)&ppValue->m_array); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetSigOfFieldDef(tk, (ULONG*)&ppValue->m_count, (PCCOR_SIGNATURE *)&ppValue->m_array); } FCIMPLEND -MDImpl2(void, MetaDataImport::GetParentToken, mdToken tk, mdToken* ptk) +FCIMPL3(HRESULT, MetaDataImport::GetParentToken, IMDInternalImport* pScope, mdToken tk, mdToken* ptk) { FCALL_CONTRACT; HRESULT hr; - IMDInternalImport *_pScope = pScope; switch (TypeFromToken(tk)) { case mdtTypeDef: - hr = _pScope->GetNestedClassProps(tk, ptk); + hr = pScope->GetNestedClassProps(tk, ptk); if (hr == CLDB_E_RECORD_NOTFOUND) { *ptk = mdTypeDefNil; @@ -594,7 +395,7 @@ MDImpl2(void, MetaDataImport::GetParentToken, mdToken tk, mdToken* ptk) break; case mdtGenericParam: - hr = _pScope->GetGenericParamProps(tk, NULL, NULL, ptk, NULL, NULL); + hr = pScope->GetGenericParamProps(tk, NULL, NULL, ptk, NULL, NULL); break; case mdtMethodDef: @@ -605,7 +406,7 @@ MDImpl2(void, MetaDataImport::GetParentToken, mdToken tk, mdToken* ptk) case mdtCustomAttribute: case mdtEvent: case mdtProperty: - hr = _pScope->GetParentToken(tk, ptk); + hr = pScope->GetParentToken(tk, ptk); break; default: @@ -613,49 +414,176 @@ MDImpl2(void, MetaDataImport::GetParentToken, mdToken tk, mdToken* ptk) break; } - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return hr; } FCIMPLEND -MDImpl1(void, MetaDataImport::GetScopeProps, GUID* pmvid) +FCIMPL2(HRESULT, MetaDataImport::GetScopeProps, IMDInternalImport* pScope, GUID* pmvid) { FCALL_CONTRACT; - HRESULT hr; LPCSTR szName; - - IMDInternalImport *_pScope = pScope; - hr = _pScope->GetScopeProps(&szName, pmvid); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetScopeProps(&szName, pmvid); } FCIMPLEND -MDImpl2(void, MetaDataImport::GetMemberRefProps, +FCIMPL3(HRESULT, MetaDataImport::GetMemberRefProps, + IMDInternalImport* pScope, mdMemberRef mr, ConstArray* ppvSigBlob) { FCALL_CONTRACT; - HRESULT hr; - IMDInternalImport *_pScope = pScope; LPCSTR szName_Ignore; - - hr = _pScope->GetNameAndSigOfMemberRef(mr, (PCCOR_SIGNATURE*)&ppvSigBlob->m_array, (ULONG*)&ppvSigBlob->m_count, &szName_Ignore); - if (FAILED(hr)) - { - FCThrowVoid(kBadImageFormatException); - } + return pScope->GetNameAndSigOfMemberRef(mr, (PCCOR_SIGNATURE*)&ppvSigBlob->m_array, (ULONG*)&ppvSigBlob->m_count, &szName_Ignore); } FCIMPLEND #if defined(_MSC_VER) && defined(TARGET_X86) -#pragma optimize("", on) // restore command line optimization defaults +#pragma optimize("", on) // restore command line optimization defaults #endif +class ResultMemory final +{ + INT32 _length; + INT32* _alloc; + +public: + ResultMemory() = default; + + ~ResultMemory() + { + STANDARD_VM_CONTRACT; + delete[] _alloc; + } + + INT32* AllocateUnmanagedArray(INT32 length) + { + CONTRACT(INT32*) + { + THROWS; + MODE_PREEMPTIVE; + PRECONDITION(_alloc == NULL); + POSTCONDITION((length == _length)); + POSTCONDITION((RETVAL != NULL)); + } + CONTRACT_END; + + _alloc = new INT32[length]; + _length = length; + RETURN _alloc; + } + + void AllocateManagedArray(QCall::ObjectHandleOnStack& longResult) + { + CONTRACTL + { + THROWS; + MODE_PREEMPTIVE; + PRECONDITION(_alloc != NULL); + } + CONTRACTL_END; + + { + GCX_COOP(); + longResult.Set(AllocatePrimitiveArray(ELEMENT_TYPE_I4, _length)); + void* p = ((I4Array*)OBJECTREFToObject(longResult.Get()))->GetDirectPointerToNonObjectElements(); + memcpyNoGCRefs(p, _alloc, (size_t)_length * sizeof(INT32)); + } + } +}; + +static void* EnsureResultSize( + INT32 resultLength, + INT32 shortResultLen, + INT32* shortResult, + ResultMemory& resultMemory) +{ + CONTRACT(void*) + { + THROWS; + MODE_PREEMPTIVE; + PRECONDITION(shortResultLen > 0); + PRECONDITION(shortResult != NULL); + POSTCONDITION((RETVAL != NULL)); + } + CONTRACT_END; + + void* p; + if (resultLength <= shortResultLen) + { + p = shortResult; + } + else + { + _ASSERTE(resultLength > 0); + p = resultMemory.AllocateUnmanagedArray(resultLength); + } + ZeroMemory(p, (size_t)resultLength * sizeof(INT32)); + RETURN p; +} + +extern "C" void QCALLTYPE MetadataImport_Enum( + IMDInternalImport* pScope, + mdToken type, + mdToken tkParent, + /* in/out */ INT32* length, + INT32* shortResult, + QCall::ObjectHandleOnStack longResult) +{ + CONTRACTL + { + QCALL_CHECK; + PRECONDITION(pScope != NULL); + PRECONDITION(length != NULL); + PRECONDITION(shortResult != NULL); + } + CONTRACTL_END; + + BEGIN_QCALL; + + ResultMemory memory{}; + ULONG resultLength; + INT32 shortResultLen = *length; + if (type == mdtTypeDef) + { + IfFailThrow(pScope->GetCountNestedClasses(tkParent, &resultLength)); + + mdTypeDef* arToken = (mdTypeDef*)EnsureResultSize(resultLength, shortResultLen, shortResult, memory); + IfFailThrow(pScope->GetNestedClasses(tkParent, arToken, resultLength, &resultLength)); + } + else if (type == mdtMethodDef && (TypeFromToken(tkParent) == mdtProperty || TypeFromToken(tkParent) == mdtEvent)) + { + HENUMInternalHolder hEnum(pScope); + hEnum.EnumAssociateInit(tkParent); + + ULONG associatesCount = hEnum.EnumGetCount(); + + // The ASSOCIATE_RECORD is a pair of integers. + // This means we require a size of 2x the returned length. + resultLength = associatesCount * 2; + static_assert_no_msg(sizeof(ASSOCIATE_RECORD) == 2 * sizeof(INT32)); + + ASSOCIATE_RECORD* arAssocRecord = (ASSOCIATE_RECORD*)EnsureResultSize(resultLength, shortResultLen, shortResult, memory); + IfFailThrow(pScope->GetAllAssociates(&hEnum, arAssocRecord, associatesCount)); + } + else + { + HENUMInternalHolder hEnum(pScope); + hEnum.EnumInit(type, tkParent); + + resultLength = hEnum.EnumGetCount(); + + mdToken* arToken = (mdToken*)EnsureResultSize(resultLength, shortResultLen, shortResult, memory); + for(COUNT_T i = 0; i < resultLength && pScope->EnumNext(&hEnum, &arToken[i]); i++); + } + + // If the result was longer than the short, we need to allocate an array. + if (resultLength > (ULONG)shortResultLen) + memory.AllocateManagedArray(longResult); + + *length = resultLength; + + END_QCALL; +} diff --git a/src/coreclr/vm/managedmdimport.hpp b/src/coreclr/vm/managedmdimport.hpp index 72e3703c376d46..4db05291d6fd0b 100644 --- a/src/coreclr/vm/managedmdimport.hpp +++ b/src/coreclr/vm/managedmdimport.hpp @@ -24,95 +24,57 @@ typedef struct void* m_array; } ConstArray; -typedef struct -{ - I4Array * largeResult; - int length; - int smallResult[16]; -} MetadataEnumResult; - -#define MDDecl0(RET, NAME) static FCDECL1(RET, NAME, IMDInternalImport* pScope) -#define MDDecl1(RET, NAME, arg0) static FCDECL2(RET, NAME, IMDInternalImport* pScope, arg0) -#define MDDecl2(RET, NAME, arg0, arg1) static FCDECL3(RET, NAME, IMDInternalImport* pScope, arg0, arg1) -#define MDDecl3(RET, NAME, arg0, arg1, arg2) static FCDECL4(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2) -#define MDDecl4(RET, NAME, arg0, arg1, arg2, arg3) static FCDECL5(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3) -#define MDDecl5(RET, NAME, arg0, arg1, arg2, arg3, arg4) static FCDECL6(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4) -#define MDDecl6(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5) static FCDECL7(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5) -#define MDDecl7(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6) static FCDECL8(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6) -#define MDDecl8(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) static FCDECL9(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) -#define MDDecl9(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) static FCDECL10(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) -#define MDDecl10(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) static FCDECL11(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) - -#define MDImpl0(RET, NAME) FCIMPL1(RET, NAME, IMDInternalImport* pScope) -#define MDImpl1(RET, NAME, arg0) FCIMPL2(RET, NAME, IMDInternalImport* pScope, arg0) -#define MDImpl2(RET, NAME, arg0, arg1) FCIMPL3(RET, NAME, IMDInternalImport* pScope, arg0, arg1) -#define MDImpl3(RET, NAME, arg0, arg1, arg2) FCIMPL4(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2) -#define MDImpl4(RET, NAME, arg0, arg1, arg2, arg3) FCIMPL5(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3) -#define MDImpl5(RET, NAME, arg0, arg1, arg2, arg3, arg4) FCIMPL6(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4) -#define MDImpl6(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5) FCIMPL7(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5) -#define MDImpl7(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6) FCIMPL8(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6) -#define MDImpl8(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) FCIMPL9(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) -#define MDImpl9(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) FCIMPL10(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) -#define MDImpl10(RET, NAME, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) FCIMPL11(RET, NAME, IMDInternalImport* pScope, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) - class MetaDataImport { public: - // - // GetXXXProps - // - MDDecl1(void, GetScopeProps, GUID* pmvid); - MDDecl4(void, GetTypeDefProps, mdTypeDef td, STRINGREF* pszTypeDef, DWORD* pdwTypeDefFlags, mdToken* ptkExtends); - MDDecl2(void, GetMemberRefProps, mdMemberRef mr, ConstArray* ppvSigBlob); - - - //// - //// EnumXXX - //// - MDDecl3(void, Enum, mdToken type, mdToken tkParent, MetadataEnumResult * pResult); - MDDecl3(void, GetCustomAttributeProps, mdCustomAttribute cv, mdToken* ptkType, ConstArray* ppBlob); - - //// - //// Misc - //// - - MDDecl4(Object *, GetDefaultValue, mdToken tk, INT64* pDefaultValue, INT32* pLength, INT32* pCorElementType); - MDDecl2(void, GetName, mdToken tk, LPCSTR* pszName); - MDDecl3(void, GetUserString, mdToken tk, LPCSTR* pszName, ULONG* pCount); - MDDecl2(void, GetNamespace, mdToken tk, LPCSTR* pszName); - MDDecl2(void, GetParentToken, mdToken tk, mdToken* ptk); - MDDecl3(void, GetParamDefProps, mdToken tk, INT32* pSequence, INT32* pAttributes); - MDDecl4(void, GetPinvokeMap, mdToken tk, DWORD* pMappingFlags, LPCSTR* pszImportName, LPCSTR* pszImportDll); - - MDDecl3(void, GetClassLayout, mdTypeDef td, DWORD* pdwPackSize, ULONG* pulClassSize); - MDDecl3(FC_BOOL_RET, GetFieldOffset, mdTypeDef td, mdFieldDef target, DWORD* pdwFieldOffset); - - MDDecl3(void, GetEventProps, mdToken tk, LPCSTR* pszName, INT32 *pdwEventFlags); - MDDecl2(void, GetGenericParamProps, mdToken tk, DWORD* pAttributes); - MDDecl2(void, GetFieldDefProps, mdToken tk, INT32 *pdwFieldFlags); - MDDecl4(void, GetPropertyProps, mdToken tk, LPCSTR* pszName, INT32 *pdwPropertyFlags, ConstArray* ppvSigBlob); - - MDDecl2(void, GetSignatureFromToken, mdToken tk, ConstArray* pSig); - MDDecl2(void, GetSigOfFieldDef, mdToken tk, ConstArray* pMarshalInfo); - MDDecl2(void, GetSigOfMethodDef, mdToken tk, ConstArray* pMarshalInfo); - MDDecl2(void, GetFieldMarshal, mdToken tk, ConstArray* pMarshalInfo); - MDDecl2(mdParamDef, GetParamForMethodIndex, mdMethodDef md, ULONG ulParamSeq); - MDDecl1(FC_BOOL_RET, IsValidToken, mdToken tk); - MDDecl1(mdTypeDef, GetNestedClassProps, mdTypeDef tdNestedClass); - MDDecl1(ULONG, GetNativeCallConvFromSig, ConstArray sig); - - static FCDECL11(void, GetMarshalAs, - BYTE* pvNativeType, - ULONG cbNativeType, - INT32* unmanagedType, - INT32* safeArraySubType, - STRINGREF* safeArrayUserDefinedSubType, - INT32* arraySubType, - INT32* sizeParamIndex, - INT32* sizeConst, - STRINGREF* marshalType, - STRINGREF* marshalCookie, - INT32* iidParamIndex); + static FCDECL1(IMDInternalImport*, GetMetadataImport, ReflectModuleBaseObject* pModuleUNSAFE); + static FCDECL2(HRESULT, GetScopeProps, IMDInternalImport* pScope, GUID* pmvid); + static FCDECL3(HRESULT, GetMemberRefProps, IMDInternalImport* pScope, mdMemberRef mr, ConstArray* ppvSigBlob); + + static FCDECL4(HRESULT, GetCustomAttributeProps, IMDInternalImport* pScope, mdCustomAttribute cv, mdToken* ptkType, ConstArray* ppBlob); + + static FCDECL6(HRESULT, GetDefaultValue, IMDInternalImport* pScope, mdToken tk, INT64* pDefaultValue, LPCWSTR* pStringValue, INT32* pLength, INT32* pCorElementType); + static FCDECL3(HRESULT, GetName, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName); + static FCDECL4(HRESULT, GetUserString, IMDInternalImport* pScope, mdToken tk, LPCWSTR* pszName, ULONG* pCount); + static FCDECL3(HRESULT, GetNamespace, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName); + static FCDECL3(HRESULT, GetParentToken, IMDInternalImport* pScope, mdToken tk, mdToken* ptk); + static FCDECL4(HRESULT, GetParamDefProps, IMDInternalImport* pScope, mdToken tk, INT32* pSequence, INT32* pAttributes); + static FCDECL5(HRESULT, GetPInvokeMap, IMDInternalImport* pScope, mdToken tk, DWORD* pMappingFlags, LPCSTR* pszImportName, LPCSTR* pszImportDll); + + static FCDECL4(HRESULT, GetClassLayout, IMDInternalImport* pScope, mdTypeDef td, DWORD* pdwPackSize, ULONG* pulClassSize); + static FCDECL5(HRESULT, GetFieldOffset, IMDInternalImport* pScope, mdTypeDef td, mdFieldDef target, DWORD* pdwFieldOffsetGetFieldOffset, CLR_BOOL* found); + + static FCDECL4(HRESULT, GetEventProps, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName, INT32 *pdwEventFlags); + static FCDECL3(HRESULT, GetGenericParamProps, IMDInternalImport* pScope, mdToken tk, DWORD* pAttributes); + static FCDECL3(HRESULT, GetFieldDefProps, IMDInternalImport* pScope, mdToken tk, INT32 *pdwFieldFlags); + static FCDECL5(HRESULT, GetPropertyProps, IMDInternalImport* pScope, mdToken tk, LPCSTR* pszName, INT32 *pdwPropertyFlags, ConstArray* ppvSigBlob); + + static FCDECL3(HRESULT, GetSignatureFromToken, IMDInternalImport* pScope, mdToken tk, ConstArray* pSig); + static FCDECL3(HRESULT, GetSigOfFieldDef, IMDInternalImport* pScope, mdToken tk, ConstArray* pMarshalInfo); + static FCDECL3(HRESULT, GetSigOfMethodDef, IMDInternalImport* pScope, mdToken tk, ConstArray* pMarshalInfo); + static FCDECL3(HRESULT, GetFieldMarshal, IMDInternalImport* pScope, mdToken tk, ConstArray* pMarshalInfo); + static FCDECL2(FC_BOOL_RET, IsValidToken, IMDInternalImport* pScope, mdToken tk); + + static FCDECL11(FC_BOOL_RET, GetMarshalAs, + BYTE* pvNativeType, + ULONG cbNativeType, + INT32* unmanagedType, + INT32* safeArraySubType, + LPUTF8* safeArrayUserDefinedSubType, + INT32* arraySubType, + INT32* sizeParamIndex, + INT32* sizeConst, + LPUTF8* marshalType, + LPUTF8* marshalCookie, + INT32* iidParamIndex); }; +extern "C" void QCALLTYPE MetadataImport_Enum( + IMDInternalImport* pScope, + mdToken type, + mdToken tkParent, + INT32* length, + INT32* shortResult, + QCall::ObjectHandleOnStack longResult); + #endif diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 6f97c67c87895f..bbbed6bd33a486 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -120,10 +120,10 @@ SIZE_T MethodDesc::SizeOf() LIMITED_METHOD_DAC_CONTRACT; SIZE_T size = s_ClassificationSizeTable[m_wFlags & - (mdcClassification - | mdcHasNonVtableSlot - | mdcMethodImpl - | mdcHasNativeCodeSlot)]; + (mdfClassification + | mdfHasNonVtableSlot + | mdfMethodImpl + | mdfHasNativeCodeSlot)]; return size; } @@ -946,7 +946,7 @@ PTR_PCODE MethodDesc::GetAddrOfNativeCodeSlot() _ASSERTE(HasNativeCodeSlot()); - SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdcClassification | mdcHasNonVtableSlot | mdcMethodImpl)]; + SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdfClassification | mdfHasNonVtableSlot | mdfMethodImpl)]; return (PTR_PCODE)(dac_cast(this) + size); } @@ -2252,7 +2252,7 @@ MethodImpl *MethodDesc::GetMethodImpl() } CONTRACTL_END - SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdcClassification | mdcHasNonVtableSlot)]; + SIZE_T size = s_ClassificationSizeTable[m_wFlags & (mdfClassification | mdfHasNonVtableSlot)]; return PTR_MethodImpl(dac_cast(this) + size); } diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index b198ea27733a68..ad662fa9607495 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -101,15 +101,6 @@ enum MethodClassification // for both shared and unshared code (see InstantiatedMethodDesc) #ifdef FEATURE_COMINTEROP - // This needs a little explanation. There are MethodDescs on MethodTables - // which are Interfaces. These have the mdcInterface bit set. Then there - // are MethodDescs on MethodTables that are Classes, where the method is - // exposed through an interface. These do not have the mdcInterface bit set. - // - // So, today, a dispatch through an 'mdcInterface' MethodDesc is either an - // error (someone forgot to look up the method in a class' VTable) or it is - // a case of COM Interop. - mcComInterop = 6, #endif // FEATURE_COMINTEROP mcDynamic = 7, // for method desc with no metadata behind @@ -119,58 +110,55 @@ enum MethodClassification // All flags in the MethodDesc now reside in a single 16-bit field. -enum MethodDescClassification +enum MethodDescFlags { // Method is IL, FCall etc., see MethodClassification above. - mdcClassification = 0x0007, - mdcClassificationCount = mdcClassification+1, + mdfClassification = 0x0007, + mdfClassificationCount = mdfClassification+1, // Note that layout of code:MethodDesc::s_ClassificationSizeTable depends on the exact values - // of mdcHasNonVtableSlot and mdcMethodImpl + // of mdfHasNonVtableSlot and mdfMethodImpl // Has local slot (vs. has real slot in MethodTable) - mdcHasNonVtableSlot = 0x0008, + mdfHasNonVtableSlot = 0x0008, // Method is a body for a method impl (MI_MethodDesc, MI_NDirectMethodDesc, etc) // where the function explicitly implements IInterface.foo() instead of foo(). - mdcMethodImpl = 0x0010, + mdfMethodImpl = 0x0010, // Has slot for native code - mdcHasNativeCodeSlot = 0x0020, + mdfHasNativeCodeSlot = 0x0020, // Method was added via Edit And Continue - mdcEnCAddedMethod = 0x0040, + mdfEnCAddedMethod = 0x0040, // Method is static - mdcStatic = 0x0080, + mdfStatic = 0x0080, - mdcValueTypeParametersWalked = 0x0100, // Indicates that all typeref's in the signature of the method have been resolved + mdfValueTypeParametersWalked = 0x0100, // Indicates that all typeref's in the signature of the method have been resolved // to typedefs (or that process failed). - mdcValueTypeParametersLoaded = 0x0200, // Indicates if the valuetype parameter types have been loaded. + mdfValueTypeParametersLoaded = 0x0200, // Indicates if the valuetype parameter types have been loaded. // Duplicate method. When a method needs to be placed in multiple slots in the // method table, because it could not be packed into one slot. For eg, a method // providing implementation for two interfaces, MethodImpl, etc - mdcDuplicate = 0x0400, + mdfDuplicate = 0x0400, - mdcDoesNotHaveEquivalentValuetypeParameters = 0x0800, // Indicates that we have verified that there are no equivalent valuetype parameters + mdfDoesNotHaveEquivalentValuetypeParameters = 0x0800, // Indicates that we have verified that there are no equivalent valuetype parameters // for this method. - mdcRequiresCovariantReturnTypeChecking = 0x1000, + mdfRequiresCovariantReturnTypeChecking = 0x1000, // Is this method ineligible for inlining? - mdcNotInline = 0x2000, + mdfNotInline = 0x2000, // Is the method synchronized - mdcSynchronized = 0x4000, + mdfSynchronized = 0x4000, - mdcIsIntrinsic = 0x8000 // Jit may expand method as an intrinsic + mdfIsIntrinsic = 0x8000 // Jit may expand method as an intrinsic }; -#define METHOD_MAX_RVA 0x7FFFFFFF - - // The size of this structure needs to be a multiple of MethodDesc::ALIGNMENT // // @GENERICS: @@ -211,20 +199,6 @@ class MethodDesc static const size_t ALIGNMENT = (1 << ALIGNMENT_SHIFT); static const size_t ALIGNMENT_MASK = (ALIGNMENT - 1); -#ifdef _DEBUG - - // These are set only for MethodDescs but every time we want to use the debugger - // to examine these fields, the code has the thing stored in a MethodDesc*. - // So... - LPCUTF8 m_pszDebugMethodName; - LPCUTF8 m_pszDebugClassName; - LPCUTF8 m_pszDebugMethodSignature; - PTR_MethodTable m_pDebugMethodTable; - - PTR_GCCoverageInfo m_GcCover; - -#endif // _DEBUG - inline BOOL HasStableEntryPoint() { LIMITED_METHOD_DAC_CONTRACT; @@ -390,13 +364,13 @@ class MethodDesc inline void SetHasMethodImplSlot() { - m_wFlags |= mdcMethodImpl; + m_wFlags |= mdfMethodImpl; } inline BOOL HasMethodImplSlot() { LIMITED_METHOD_DAC_CONTRACT; - return (mdcMethodImpl & m_wFlags); + return (mdfMethodImpl & m_wFlags); } FORCEINLINE BOOL IsMethodImpl() @@ -415,21 +389,21 @@ class MethodDesc // accesses metadata that is not compatible with contracts of this method. The metadata access can fail, the metadata // are not available during shutdown, the metadata access can take locks. It is not worth it to code around all these // just for the assert. - // _ASSERTE((((m_wFlags & mdcStatic) != 0) == (IsMdStatic(flags) != 0))); + // _ASSERTE((((m_wFlags & mdfStatic) != 0) == (IsMdStatic(flags) != 0))); - return (m_wFlags & mdcStatic) != 0; + return (m_wFlags & mdfStatic) != 0; } inline void SetStatic() { LIMITED_METHOD_CONTRACT; - m_wFlags |= mdcStatic; + m_wFlags |= mdfStatic; } inline void ClearStatic() { LIMITED_METHOD_CONTRACT; - m_wFlags &= ~mdcStatic; + m_wFlags &= ~mdfStatic; } inline BOOL IsIL() @@ -662,13 +636,13 @@ class MethodDesc inline BOOL IsNotInline() { LIMITED_METHOD_CONTRACT; - return (m_wFlags & mdcNotInline); + return (m_wFlags & mdfNotInline); } inline void SetNotInline(BOOL set) { WRAPPER_NO_CONTRACT; - InterlockedUpdateFlags(mdcNotInline, set); + InterlockedUpdateFlags(mdfNotInline, set); } #ifndef DACCESS_COMPILE @@ -897,13 +871,13 @@ class MethodDesc inline void SetSynchronized() { LIMITED_METHOD_CONTRACT; - m_wFlags |= mdcSynchronized; + m_wFlags |= mdfSynchronized; } inline DWORD IsSynchronized() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcSynchronized) != 0; + return (m_wFlags & mdfSynchronized) != 0; } //================================================================== @@ -942,14 +916,14 @@ class MethodDesc void SetHasNonVtableSlot() { LIMITED_METHOD_CONTRACT; - m_wFlags |= mdcHasNonVtableSlot; + m_wFlags |= mdfHasNonVtableSlot; } // duplicate methods inline BOOL IsDuplicate() { LIMITED_METHOD_CONTRACT; - return (m_wFlags & mdcDuplicate) == mdcDuplicate; + return (m_wFlags & mdfDuplicate) == mdfDuplicate; } void SetDuplicate() @@ -957,7 +931,7 @@ class MethodDesc LIMITED_METHOD_CONTRACT; // method table is not setup yet //_ASSERTE(!GetClass()->IsInterface()); - m_wFlags |= mdcDuplicate; + m_wFlags |= mdfDuplicate; } //================================================================== @@ -1616,6 +1590,20 @@ class MethodDesc //================================================================ // The actual data stored in a MethodDesc follows. +#ifdef _DEBUG +public: + // These are set only for MethodDescs but every time we want to use the debugger + // to examine these fields, the code has the thing stored in a MethodDesc*. + // So... + LPCUTF8 m_pszDebugMethodName; + LPCUTF8 m_pszDebugClassName; + LPCUTF8 m_pszDebugMethodSignature; + PTR_MethodTable m_pDebugMethodTable; + + PTR_GCCoverageInfo m_GcCover; + +#endif // _DEBUG + protected: enum { // There are flags available for use here (currently 4 flags bits are available); however, new bits are hard to come by, so any new flags bits should @@ -1634,9 +1622,8 @@ class MethodDesc BYTE m_chunkIndex; BYTE m_methodIndex; // Used to hold the index into the chunk of this MethodDesc. Currently all 8 bits are used, but we could likely work with only 7 bits - // The slot number of this MethodDesc in the vtable array. - WORD m_wSlotNumber; - WORD m_wFlags; + WORD m_wSlotNumber; // The slot number of this MethodDesc in the vtable array. + WORD m_wFlags; // See MethodDescFlags public: #ifdef DACCESS_COMPILE @@ -1659,39 +1646,39 @@ class MethodDesc { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcClassification); + return (m_wFlags & mdfClassification); } inline void SetClassification(DWORD classification) { LIMITED_METHOD_CONTRACT; - _ASSERTE((m_wFlags & mdcClassification) == 0); + _ASSERTE((m_wFlags & mdfClassification) == 0); m_wFlags |= classification; } inline BOOL HasNativeCodeSlot() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcHasNativeCodeSlot) != 0; + return (m_wFlags & mdfHasNativeCodeSlot) != 0; } inline void SetHasNativeCodeSlot() { LIMITED_METHOD_CONTRACT; - m_wFlags |= mdcHasNativeCodeSlot; + m_wFlags |= mdfHasNativeCodeSlot; } #ifdef FEATURE_METADATA_UPDATER inline BOOL IsEnCAddedMethod() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcEnCAddedMethod) != 0; + return (m_wFlags & mdfEnCAddedMethod) != 0; } inline void SetIsEnCAddedMethod() { LIMITED_METHOD_CONTRACT; - m_wFlags |= mdcEnCAddedMethod; + m_wFlags |= mdfEnCAddedMethod; } #else inline BOOL IsEnCAddedMethod() @@ -1704,26 +1691,26 @@ class MethodDesc inline BOOL IsIntrinsic() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcIsIntrinsic) != 0; + return (m_wFlags & mdfIsIntrinsic) != 0; } inline void SetIsIntrinsic() { LIMITED_METHOD_CONTRACT; - m_wFlags |= mdcIsIntrinsic; + m_wFlags |= mdfIsIntrinsic; } BOOL RequiresCovariantReturnTypeChecking() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcRequiresCovariantReturnTypeChecking) != 0; + return (m_wFlags & mdfRequiresCovariantReturnTypeChecking) != 0; } void SetRequiresCovariantReturnTypeChecking() { LIMITED_METHOD_CONTRACT; - m_wFlags |= mdcRequiresCovariantReturnTypeChecking; + m_wFlags |= mdfRequiresCovariantReturnTypeChecking; } static const BYTE s_ClassificationSizeTable[]; @@ -1731,7 +1718,7 @@ class MethodDesc static SIZE_T GetBaseSize(DWORD classification) { LIMITED_METHOD_DAC_CONTRACT; - _ASSERTE(classification < mdcClassificationCount); + _ASSERTE(classification < mdfClassificationCount); return s_ClassificationSizeTable[classification]; } @@ -1748,38 +1735,38 @@ class MethodDesc inline BOOL HaveValueTypeParametersBeenWalked() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcValueTypeParametersWalked) != 0; + return (m_wFlags & mdfValueTypeParametersWalked) != 0; } inline void SetValueTypeParametersWalked() { LIMITED_METHOD_CONTRACT; - InterlockedUpdateFlags(mdcValueTypeParametersWalked, TRUE); + InterlockedUpdateFlags(mdfValueTypeParametersWalked, TRUE); } inline BOOL HaveValueTypeParametersBeenLoaded() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcValueTypeParametersLoaded) != 0; + return (m_wFlags & mdfValueTypeParametersLoaded) != 0; } inline void SetValueTypeParametersLoaded() { LIMITED_METHOD_CONTRACT; - InterlockedUpdateFlags(mdcValueTypeParametersLoaded, TRUE); + InterlockedUpdateFlags(mdfValueTypeParametersLoaded, TRUE); } #ifdef FEATURE_TYPEEQUIVALENCE inline BOOL DoesNotHaveEquivalentValuetypeParameters() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcDoesNotHaveEquivalentValuetypeParameters) != 0; + return (m_wFlags & mdfDoesNotHaveEquivalentValuetypeParameters) != 0; } inline void SetDoesNotHaveEquivalentValuetypeParameters() { LIMITED_METHOD_CONTRACT; - InterlockedUpdateFlags(mdcDoesNotHaveEquivalentValuetypeParameters, TRUE); + InterlockedUpdateFlags(mdfDoesNotHaveEquivalentValuetypeParameters, TRUE); } #endif // FEATURE_TYPEEQUIVALENCE @@ -3493,7 +3480,7 @@ inline BOOL MethodDesc::HasNonVtableSlot() { LIMITED_METHOD_DAC_CONTRACT; - return (m_wFlags & mdcHasNonVtableSlot) != 0; + return (m_wFlags & mdfHasNonVtableSlot) != 0; } inline Instantiation MethodDesc::GetMethodInstantiation() const diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 69d2a105ecd8d5..db015d227538e2 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -10051,6 +10051,9 @@ void MethodTableBuilder::CheckForSystemTypes() // The Procedure Call Standard for ARM 64-bit (with SVE support) defaults to // 16-byte alignment for __m256. + pLayout->m_ManagedLargestAlignmentRequirementOfAllMembers = 16; + #elif defined(TARGET_LOONGARCH64) + // TODO-LoongArch64: Update alignment to proper value when implement LoongArch64 intrinsic. pLayout->m_ManagedLargestAlignmentRequirementOfAllMembers = 16; #elif defined(TARGET_RISCV64) // TODO-RISCV64: Update alignment to proper value when we implement RISC-V intrinsic. @@ -10074,6 +10077,9 @@ void MethodTableBuilder::CheckForSystemTypes() pLayout->m_ManagedLargestAlignmentRequirementOfAllMembers = 16; + #elif defined(TARGET_LOONGARCH64) + // TODO-LoongArch64: Update alignment to proper value when implement LoongArch64 intrinsic. + pLayout->m_ManagedLargestAlignmentRequirementOfAllMembers = 16; #elif defined(TARGET_RISCV64) // TODO-RISCV64: Update alignment to proper value when we implement RISC-V intrinsic. // RISC-V Vector Extenstion Intrinsic Document diff --git a/src/coreclr/vm/object.cpp b/src/coreclr/vm/object.cpp index 2207b728ce1e7f..cf41103441844c 100644 --- a/src/coreclr/vm/object.cpp +++ b/src/coreclr/vm/object.cpp @@ -21,6 +21,18 @@ SVAL_IMPL(INT32, ArrayBase, s_arrayBoundsZero); +static DWORD GetGlobalNewHashCode() +{ + LIMITED_METHOD_CONTRACT; + // Used for generating hash codes for exceptions to determine whether the + // Catch_Handler_Found_Event should be reported. See Thread::GetNewHashCode. + // Using linear congruential generator from Knuth Vol. 2, p. 102, line 24 + static DWORD dwHashCodeSeed = 123456789U * 1566083941U + 1; + const DWORD multiplier = 1*4 + 5; //same as the GetNewHashCode method + dwHashCodeSeed = dwHashCodeSeed*multiplier + 1; + return dwHashCodeSeed; +} + // follow the necessary rules to get a new valid hashcode for an object DWORD Object::ComputeHashCode() { @@ -29,10 +41,18 @@ DWORD Object::ComputeHashCode() // note that this algorithm now uses at most HASHCODE_BITS so that it will // fit into the objheader if the hashcode has to be moved back into the objheader // such as for an object that is being frozen + Thread *pThread = GetThreadNULLOk(); do { - // we use the high order bits in this case because they're more random - hashCode = GetThread()->GetNewHashCode() >> (32-HASHCODE_BITS); + if (pThread == NULL) + { + hashCode = (GetGlobalNewHashCode() >> (32-HASHCODE_BITS)); + } + else + { + // we use the high order bits in this case because they're more random + hashCode = pThread->GetNewHashCode() >> (32-HASHCODE_BITS); + } } while (hashCode == 0); // need to enforce hashCode != 0 @@ -42,6 +62,18 @@ DWORD Object::ComputeHashCode() return hashCode; } +DWORD Object::GetGlobalNewHashCode() +{ + LIMITED_METHOD_CONTRACT; + // Used for generating hash codes for exceptions to determine whether the + // Catch_Handler_Found_Event should be reported. See Thread::GetNewHashCode. + // Using linear congruential generator from Knuth Vol. 2, p. 102, line 24 + static DWORD dwHashCodeSeed = 123456789U * 1566083941U + 1; + const DWORD multiplier = 1*4 + 5; //same as the GetNewHashCode method + dwHashCodeSeed = dwHashCodeSeed*multiplier + 1; + return dwHashCodeSeed; +} + #ifndef DACCESS_COMPILE INT32 Object::GetHashCodeEx() { diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index 17803b62521e7c..a282dd867e94a9 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -263,6 +263,7 @@ class Object } static DWORD ComputeHashCode(); + static DWORD GetGlobalNewHashCode(); #ifndef DACCESS_COMPILE INT32 GetHashCodeEx(); diff --git a/src/coreclr/vm/perfinfo.cpp b/src/coreclr/vm/perfinfo.cpp deleted file mode 100644 index 98fc667661a504..00000000000000 --- a/src/coreclr/vm/perfinfo.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: perfinfo.cpp -// - -#include "common.h" - -#if defined(FEATURE_PERFMAP) && !defined(DACCESS_COMPILE) -#include "perfinfo.h" -#include "pal.h" - -PerfInfo::PerfInfo(int pid, const char* basePath) - : m_Stream(nullptr) -{ - LIMITED_METHOD_CONTRACT; - - SString path; - path.Printf("%s/perfinfo-%d.map", basePath, pid); - OpenFile(path); -} - -// Logs image loads into the process' perfinfo-%d.map file -void PerfInfo::LogImage(PEAssembly* pPEAssembly, CHAR* guid) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - PRECONDITION(pPEAssembly != nullptr); - PRECONDITION(guid != nullptr); - } CONTRACTL_END; - - // Nothing to log if the assembly path isn't present. - SString path{ pPEAssembly->GetPath() }; - if (path.IsEmpty()) - { - return; - } - - SIZE_T baseAddr = 0; - if (pPEAssembly->IsReadyToRun()) - { - PEImageLayout *pLoadedLayout = pPEAssembly->GetLoadedLayout(); - if (pLoadedLayout) - { - baseAddr = (SIZE_T)pLoadedLayout->GetBase(); - } - } - - SString value; - value.Printf("%s%c%s%c%p", path.GetUTF8(), sDelimiter, guid, sDelimiter, baseAddr); - - SString command{ SString::Literal, "ImageLoad" }; - WriteLine(command, value); -} - -// Writes a command line, with "type" being the type of command, with "value" as the command's corresponding instructions/values. This is to be used to log specific information, e.g. LogImage -void PerfInfo::WriteLine(SString& type, SString& value) -{ - - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - if (m_Stream == nullptr) - { - return; - } - - SString line; - line.Printf("%s%c%s%c\n", - type.GetUTF8(), sDelimiter, value.GetUTF8(), sDelimiter); - - EX_TRY - { - const char* strLine = line.GetUTF8(); - ULONG inCount = line.GetCount(); - ULONG outCount; - - m_Stream->Write(strLine, inCount, &outCount); - - if (inCount != outCount) - { - // error encountered - } - } - EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); -} - -// Opens a file ready to be written in. -void PerfInfo::OpenFile(SString& path) -{ - STANDARD_VM_CONTRACT; - - m_Stream = new (nothrow) CFileStream(); - - if (m_Stream != nullptr) - { - HRESULT hr = m_Stream->OpenForWrite(path.GetUnicode()); - if (FAILED(hr)) - { - delete m_Stream; - m_Stream = nullptr; - } - } -} - -PerfInfo::~PerfInfo() -{ - LIMITED_METHOD_CONTRACT; - - delete m_Stream; - m_Stream = nullptr; -} - - -#endif - - - - - - - - - - diff --git a/src/coreclr/vm/perfinfo.h b/src/coreclr/vm/perfinfo.h deleted file mode 100644 index ce54cc19faee60..00000000000000 --- a/src/coreclr/vm/perfinfo.h +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: perfinfo.h -// - -#ifndef PERFINFO_H -#define PERFINFO_H - - -#include "sstring.h" -#include "fstream.h" - -/* - A perfinfo-%d.map is created for every process that is created with manage code, the %d - being repaced with the process ID. - Every line in the perfinfo-%d.map is a type and value, separated by sDelimiter character: type;value - type represents what the user might want to do with its given value. value has a format chosen by - the user for parsing later on. -*/ -class PerfInfo { -public: - PerfInfo(int pid, const char* basePath); - ~PerfInfo(); - void LogImage(PEAssembly* pPEAssembly, CHAR* guid); - -private: - CFileStream* m_Stream; - - const char sDelimiter = ';'; - - void OpenFile(SString& path); - - void WriteLine(SString& type, SString& value); - -}; - - -#endif diff --git a/src/coreclr/vm/perfmap.cpp b/src/coreclr/vm/perfmap.cpp index 9e553a975da0a7..2d823e546fca51 100644 --- a/src/coreclr/vm/perfmap.cpp +++ b/src/coreclr/vm/perfmap.cpp @@ -9,7 +9,6 @@ #if defined(FEATURE_PERFMAP) && !defined(DACCESS_COMPILE) #include #include "perfmap.h" -#include "perfinfo.h" #include "pal.h" @@ -113,7 +112,6 @@ void PerfMap::Enable(PerfMapType type, bool sendExisting) while (assemblyIterator.Next(pDomainAssembly.This())) { CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetAssembly(); - PerfMap::LogImageLoad(pAssembly->GetPEAssembly()); // PerfMap does not log R2R methods so only proceed if we are emitting jitdumps if (type == PerfMapType::ALL || type == PerfMapType::JITDUMP) @@ -204,7 +202,6 @@ PerfMap::PerfMap() // Initialize with no failures. m_ErrorEncountered = false; - m_PerfInfo = nullptr; } // Clean-up resources. @@ -214,9 +211,6 @@ PerfMap::~PerfMap() delete m_FileStream; m_FileStream = nullptr; - - delete m_PerfInfo; - m_PerfInfo = nullptr; } void PerfMap::OpenFileForPid(int pid, const char* basePath) @@ -226,8 +220,6 @@ void PerfMap::OpenFileForPid(int pid, const char* basePath) // Open the map file for writing. OpenFile(fullPath); - - m_PerfInfo = new PerfInfo(pid, basePath); } // Open the specified destination map file. @@ -281,43 +273,6 @@ void PerfMap::WriteLine(SString& line) EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); } -void PerfMap::LogImageLoad(PEAssembly * pPEAssembly) -{ - CrstHolder ch(&(s_csPerfMap)); - - if (s_enabled && s_Current != nullptr) - { - s_Current->LogImage(pPEAssembly); - } -} - -// Log an image load to the map. -void PerfMap::LogImage(PEAssembly * pPEAssembly) -{ - CONTRACTL{ - THROWS; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - PRECONDITION(pPEAssembly != nullptr); - } CONTRACTL_END; - - - if (m_FileStream == nullptr || m_ErrorEncountered) - { - // A failure occurred, do not log. - return; - } - - EX_TRY - { - CHAR szSignature[GUID_STR_BUFFER_LEN]; - GetNativeImageSignature(pPEAssembly, szSignature, ARRAY_SIZE(szSignature)); - - m_PerfInfo->LogImage(pPEAssembly, szSignature); - } - EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); -} - void PerfMap::LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, PrepareCodeConfig *pConfig) { LIMITED_METHOD_CONTRACT; diff --git a/src/coreclr/vm/perfmap.h b/src/coreclr/vm/perfmap.h index ffc7f3228b2cfa..f6eb8cfc73831b 100644 --- a/src/coreclr/vm/perfmap.h +++ b/src/coreclr/vm/perfmap.h @@ -10,8 +10,6 @@ #include "fstream.h" #include "volatile.h" -class PerfInfo; - // Generates a perfmap file. class PerfMap { @@ -32,9 +30,6 @@ class PerfMap // The file stream to write the map to. CFileStream * m_FileStream; - // The perfinfo file to log images to. - PerfInfo * m_PerfInfo; - // Set to true if an error is encountered when writing to the file. bool m_ErrorEncountered; @@ -57,9 +52,6 @@ class PerfMap // Does the actual work to log a method to the map. void LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier); - // Does the actual work to log an image - void LogImage(PEAssembly * pPEAssembly); - // Get the image signature and store it as a string. static void GetNativeImageSignature(PEAssembly * pPEAssembly, CHAR * pszSig, unsigned int nSigSize); @@ -87,9 +79,6 @@ class PerfMap static void Enable(PerfMapType type, bool sendExisting); - // Log a native image load to the map. - static void LogImageLoad(PEAssembly * pPEAssembly); - static void LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, PrepareCodeConfig *pConfig); // Log a pre-compiled method to the map. diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 233899582572e9..99e76824a5df96 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -333,6 +333,7 @@ static const Entry s_QCall[] = DllImportEntry(Monitor_Pulse) DllImportEntry(Monitor_PulseAll) DllImportEntry(Monitor_GetLockContentionCount) + DllImportEntry(MetadataImport_Enum) DllImportEntry(ReflectionInvocation_RunClassConstructor) DllImportEntry(ReflectionInvocation_RunModuleConstructor) DllImportEntry(ReflectionInvocation_CompileMethod) diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index 36afe9fbb8691d..f57e21801253a3 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -1984,6 +1984,7 @@ extern "C" void QCALLTYPE Enum_GetValuesAndNames(QCall::TypeHandle pEnumType, QC MDDefaultValue defaultValue = { }; IfFailThrow(pImport->GetDefaultValue(field, &defaultValue)); + _ASSERTE(defaultValue.m_bType != ELEMENT_TYPE_STRING); // Strings in metadata are little-endian. // The following code assumes that the address of all union members is the same. static_assert_no_msg(offsetof(MDDefaultValue, m_byteValue) == offsetof(MDDefaultValue, m_usValue)); diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 4598f4d1e49a4b..c660763f11577b 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1488,21 +1488,6 @@ FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, PTR_ReflectCla } FCIMPLEND -FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE) -{ - FCALL_CONTRACT; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - Module *pModule = refType->GetType().GetModule(); - - return pModule->GetMDImport(); -} -FCIMPLEND - extern "C" void* QCALLTYPE RuntimeTypeHandle_AllocateTypeAssociatedMemory(QCall::TypeHandle type, uint32_t size) { QCALL_CONTRACT; @@ -2790,20 +2775,6 @@ FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) } FCIMPLEND -FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE) -{ - FCALL_CONTRACT; - - REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE); - - if (refModule == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - Module *pModule = refModule->GetModule(); - return pModule->GetMDImport(); -} -FCIMPLEND - extern "C" void QCALLTYPE ModuleHandle_ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType) { QCALL_CONTRACT; diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 6b0d995977c654..56bb2df245f9f7 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -163,8 +163,6 @@ class RuntimeTypeHandle { static FCDECL1(MethodDesc *, GetFirstIntroducedMethod, ReflectClassBaseObject* pType); static FCDECL1(void, GetNextIntroducedMethod, MethodDesc **ppMethod); - static FCDECL1(IMDInternalImport*, GetMetadataImport, ReflectClassBaseObject * pModuleUNSAFE); - // Helper methods not called by managed code static void ValidateTypeAbleToBeInstantiated(TypeHandle typeHandle, bool fGetUninitializedObject); @@ -316,13 +314,7 @@ class ModuleHandle { public: static FCDECL5(ReflectMethodObject*, GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig, Object *resolver); static FCDECL1(INT32, GetToken, ReflectModuleBaseObject *pModuleUNSAFE); - - static - FCDECL1(IMDInternalImport*, GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE); - - static - FCDECL1(INT32, GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE); - + static FCDECL1(INT32, GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE); }; extern "C" void QCALLTYPE ModuleHandle_GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType); diff --git a/src/coreclr/vm/stackingallocator.cpp b/src/coreclr/vm/stackingallocator.cpp index 7db829eb1b441a..c5d1ea2ad79d26 100644 --- a/src/coreclr/vm/stackingallocator.cpp +++ b/src/coreclr/vm/stackingallocator.cpp @@ -399,7 +399,7 @@ void * __cdecl operator new[](size_t n, StackingAllocator * alloc) return retval; } -void * __cdecl operator new(size_t n, StackingAllocator * alloc, const NoThrow&) throw() +void * __cdecl operator new(size_t n, StackingAllocator * alloc, const std::nothrow_t&) noexcept { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_FAULT; @@ -412,7 +412,7 @@ void * __cdecl operator new(size_t n, StackingAllocator * alloc, const NoThrow&) return alloc->UnsafeAllocNoThrow((unsigned)n); } -void * __cdecl operator new[](size_t n, StackingAllocator * alloc, const NoThrow&) throw() +void * __cdecl operator new[](size_t n, StackingAllocator * alloc, const std::nothrow_t&) noexcept { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_FAULT; diff --git a/src/coreclr/vm/stackingallocator.h b/src/coreclr/vm/stackingallocator.h index c306e1b482d38e..1878433a7748ef 100644 --- a/src/coreclr/vm/stackingallocator.h +++ b/src/coreclr/vm/stackingallocator.h @@ -271,8 +271,8 @@ class StackingAllocatorHolder void * __cdecl operator new(size_t n, StackingAllocator *alloc); void * __cdecl operator new[](size_t n, StackingAllocator *alloc); -void * __cdecl operator new(size_t n, StackingAllocator *alloc, const NoThrow&) throw(); -void * __cdecl operator new[](size_t n, StackingAllocator *alloc, const NoThrow&) throw(); +void * __cdecl operator new(size_t n, StackingAllocator *alloc, const std::nothrow_t&) noexcept; +void * __cdecl operator new[](size_t n, StackingAllocator *alloc, const std::nothrow_t&) noexcept; #ifdef _MSC_VER #pragma warning(pop) diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 48ede10b35fef0..606137ee8eba75 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -2851,15 +2851,9 @@ BOOL SyncBlock::Wait(INT32 timeOut) _ASSERTE ((SyncBlock*)((DWORD_PTR)walk->m_Next->m_WaitSB & ~1)== this); - PendingSync syncState(walk); - - OBJECTREF obj = m_Monitor.GetOwningObject(); - syncState.m_Object = OBJECTREFToObject(obj); - - m_Monitor.IncrementTransientPrecious(); - // While we are in this frame the thread is considered blocked on the - // event of the monitor lock according to the debugger + // event of the monitor lock according to the debugger. DebugBlockingItemHolder + // can trigger a GC, so set it up before accessing the owning object. DebugBlockingItem blockingMonitorInfo; blockingMonitorInfo.dwTimeout = timeOut; blockingMonitorInfo.pMonitor = &m_Monitor; @@ -2867,6 +2861,13 @@ BOOL SyncBlock::Wait(INT32 timeOut) blockingMonitorInfo.type = DebugBlock_MonitorEvent; DebugBlockingItemHolder holder(pCurThread, &blockingMonitorInfo); + PendingSync syncState(walk); + + OBJECTREF obj = m_Monitor.GetOwningObject(); + syncState.m_Object = OBJECTREFToObject(obj); + + m_Monitor.IncrementTransientPrecious(); + GCPROTECT_BEGIN(obj); { GCX_PREEMP(); diff --git a/src/coreclr/vm/syncblk.h b/src/coreclr/vm/syncblk.h index 2ddec753159759..029ee9337d7aab 100644 --- a/src/coreclr/vm/syncblk.h +++ b/src/coreclr/vm/syncblk.h @@ -602,6 +602,12 @@ class AwareLock LIMITED_METHOD_CONTRACT; return m_HoldingThread; } + + static int GetOffsetOfHoldingOSThreadId() + { + LIMITED_METHOD_CONTRACT; + return (int)offsetof(AwareLock, m_HoldingOSThreadId); + } }; #ifdef FEATURE_COMINTEROP diff --git a/src/coreclr/vm/threaddebugblockinginfo.cpp b/src/coreclr/vm/threaddebugblockinginfo.cpp index 8767091566891a..8f4f3831b3518e 100644 --- a/src/coreclr/vm/threaddebugblockinginfo.cpp +++ b/src/coreclr/vm/threaddebugblockinginfo.cpp @@ -72,9 +72,37 @@ VOID ThreadDebugBlockingInfo::VisitBlockingItems(DebugBlockingItemVisitor visito // Holder constructor pushes a blocking item on the blocking info stack #ifndef DACCESS_COMPILE DebugBlockingItemHolder::DebugBlockingItemHolder(Thread *pThread, DebugBlockingItem *pItem) : -m_pThread(pThread) + m_pThread(pThread), m_ppFirstBlockingInfo(nullptr) { - LIMITED_METHOD_CONTRACT; + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + // Try to get the address of the thread-local slot for the managed ThreadBlockingInfo.t_first + EX_TRY + { + FieldDesc *pFD = CoreLibBinder::GetField(FIELD__THREAD_BLOCKING_INFO__FIRST); + m_ppFirstBlockingInfo = (ThreadBlockingInfo **)Thread::GetStaticFieldAddress(pFD); + } + EX_CATCH + { + } + EX_END_CATCH(RethrowTerminalExceptions); + + if (m_ppFirstBlockingInfo != nullptr) + { + // Push info for the managed ThreadBlockingInfo + m_blockingInfo.objectPtr = pItem->pMonitor; + m_blockingInfo.objectKind = (ThreadBlockingInfo::ObjectKind)pItem->type; + m_blockingInfo.timeoutMs = (INT32)pItem->dwTimeout; + m_blockingInfo.next = *m_ppFirstBlockingInfo; + *m_ppFirstBlockingInfo = &m_blockingInfo; + } + pThread->DebugBlockingInfo.PushBlockingItem(pItem); } #endif //DACCESS_COMPILE @@ -84,6 +112,17 @@ m_pThread(pThread) DebugBlockingItemHolder::~DebugBlockingItemHolder() { LIMITED_METHOD_CONTRACT; + m_pThread->DebugBlockingInfo.PopBlockingItem(); + + if (m_ppFirstBlockingInfo != nullptr) + { + // Pop info for the managed ThreadBlockingInfo + _ASSERTE( + m_ppFirstBlockingInfo == + (void *)m_pThread->GetStaticFieldAddrNoCreate(CoreLibBinder::GetField(FIELD__THREAD_BLOCKING_INFO__FIRST))); + _ASSERTE(*m_ppFirstBlockingInfo == &m_blockingInfo); + *m_ppFirstBlockingInfo = m_blockingInfo.next; + } } #endif //DACCESS_COMPILE diff --git a/src/coreclr/vm/threaddebugblockinginfo.h b/src/coreclr/vm/threaddebugblockinginfo.h index 9a2815b3a0c78e..c0d035dd88f01b 100644 --- a/src/coreclr/vm/threaddebugblockinginfo.h +++ b/src/coreclr/vm/threaddebugblockinginfo.h @@ -14,8 +14,8 @@ // Different ways thread can block that the debugger will expose enum DebugBlockingItemType { - DebugBlock_MonitorCriticalSection, - DebugBlock_MonitorEvent, + DebugBlock_MonitorCriticalSection, // maps to ThreadBlockingInfo.ObjectKind.MonitorLock below and in managed code + DebugBlock_MonitorEvent, // maps to ThreadBlockingInfo.ObjectKind.MonitorWait below and in managed code }; typedef DPTR(struct DebugBlockingItem) PTR_DebugBlockingItem; @@ -65,15 +65,35 @@ class ThreadDebugBlockingInfo }; #ifndef DACCESS_COMPILE + +// This is the equivalent of the managed ThreadBlockingInfo (see ThreadBlockingInfo.cs), which is used for tracking blocking +// info from the managed side, similarly to DebugBlockingItem +struct ThreadBlockingInfo +{ + enum class ObjectKind : INT32 + { + MonitorLock, // maps to DebugBlockingItemType::DebugBlock_MonitorCriticalSection + MonitorWait // maps to DebugBlockingItemType::DebugBlock_MonitorEvent + }; + + void *objectPtr; + ObjectKind objectKind; + INT32 timeoutMs; + ThreadBlockingInfo *next; +}; + class DebugBlockingItemHolder { private: Thread *m_pThread; + ThreadBlockingInfo **m_ppFirstBlockingInfo; + ThreadBlockingInfo m_blockingInfo; public: DebugBlockingItemHolder(Thread *pThread, DebugBlockingItem *pItem); ~DebugBlockingItemHolder(); }; + #endif //!DACCESS_COMPILE #endif // __ThreadBlockingInfo__ diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h index 4241893ee522bb..67c4b6b83c975b 100644 --- a/src/coreclr/vm/threads.h +++ b/src/coreclr/vm/threads.h @@ -121,6 +121,7 @@ #include "gchandleutilities.h" #include "gcinfotypes.h" #include +#include "cdacoffsets.h" class Thread; class ThreadStore; @@ -4076,8 +4077,17 @@ class Thread private: bool m_hasPendingActivation; + + template friend struct ::cdac_offsets; }; +template<> +struct cdac_offsets +{ + static constexpr size_t ExposedObject = offsetof(Thread, m_ExposedObject); + static constexpr size_t Link = offsetof(Thread, m_Link); +}; + // End of class Thread typedef Thread::ForbidSuspendThreadHolder ForbidSuspendThreadHolder; diff --git a/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-arm64.xml b/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-arm64.xml index 1b0dca06e4095d..2d501b30731695 100644 --- a/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-arm64.xml +++ b/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-arm64.xml @@ -7,7 +7,7 @@ - + diff --git a/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-x64.xml b/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-x64.xml index 419795e0f348fe..538f475d5d5836 100644 --- a/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-x64.xml +++ b/src/installer/pkg/sfx/bundle/shared-framework-distribution-template-x64.xml @@ -7,7 +7,7 @@ - + diff --git a/src/libraries/Common/src/Extensions/ChangeCallbackRegistrar.cs b/src/libraries/Common/src/Extensions/ChangeCallbackRegistrar.cs index eecd1fa8c1e515..aa7899a64136e3 100644 --- a/src/libraries/Common/src/Extensions/ChangeCallbackRegistrar.cs +++ b/src/libraries/Common/src/Extensions/ChangeCallbackRegistrar.cs @@ -21,7 +21,7 @@ internal static class ChangeCallbackRegistrar /// The registration. internal static IDisposable UnsafeRegisterChangeCallback(Action callback, object? state, CancellationToken token, Action onFailure, T onFailureState) { -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 try { return token.UnsafeRegister(callback, state); diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs index e94a88249a1d0a..59e93080c562e8 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Evp.cs @@ -56,6 +56,21 @@ internal static unsafe int EvpDigestCurrentXOF(SafeEvpMdCtxHandle ctx, Span destination) + { + _ = ctx; + _ = destination; + Debug.Fail("Should have validated that XOF is not supported before getting here."); + throw new UnreachableException(); + } + internal static readonly int EVP_MAX_MD_SIZE = GetMaxMdSize(); } } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs b/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs index 2a7b1d02ad21ad..73fbfa924d141d 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Calendar.cs @@ -9,6 +9,6 @@ internal static partial class Interop internal static unsafe partial class JsGlobalization { [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe int GetCalendarInfo(in string culture, CalendarId calendarId, char* buffer, int bufferLength, out int exceptionalResult, out object result); + internal static extern unsafe nint GetCalendarInfo(char* culture, int cultureLength, CalendarId calendarId, char* buffer, int bufferMaxLength, out int bufferLength); } } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs b/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs index cb7edf5b380a26..638934edb416d6 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.CompareInfo.cs @@ -8,15 +8,15 @@ internal static partial class Interop internal static unsafe partial class JsGlobalization { [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe int CompareString(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int exceptionalResult, out object result); + internal static extern unsafe nint CompareString(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int resultPtr); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe bool StartsWith(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int exceptionalResult, out object result); + internal static extern unsafe nint StartsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe bool EndsWith(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int exceptionalResult, out object result); + internal static extern unsafe nint EndsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe int IndexOf(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, bool fromBeginning, out int exceptionalResult, out object result); + internal static extern unsafe nint IndexOf(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, bool fromBeginning, out int resultPtr); } } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs b/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs index b831e72e70cdbc..b2dc0db99c00c0 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs @@ -8,12 +8,12 @@ internal static partial class Interop internal static unsafe partial class JsGlobalization { [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe int GetCultureInfo(in string culture, char* buffer, int bufferLength, out int exceptionalResult, out object result); + internal static extern unsafe nint GetCultureInfo(char* culture, int cultureLength, char* buffer, int bufferMaxLength, out int resultLength); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe int GetFirstDayOfWeek(in string culture, out int exceptionalResult, out object result); + internal static extern unsafe nint GetFirstDayOfWeek(char* culture, int cultureLength, out int resultPtr); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe int GetFirstWeekOfYear(in string culture, out int exceptionalResult, out object result); + internal static extern unsafe nint GetFirstWeekOfYear(char* culture, int cultureLength, out int resultPtr); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe int GetLocaleInfo(in string locale, in string culture, char* buffer, int bufferLength, out int exceptionalResult, out object result); + internal static extern unsafe nint GetLocaleInfo(char* locale, int localeLength, char* culture, int cultureLength, char* buffer, int bufferLength, out int resultLength); } } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index 518a4ff53bee20..aa35d57828ee3a 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -69,6 +69,6 @@ internal static unsafe partial class Runtime [MethodImpl(MethodImplOptions.InternalCall)] public static extern void BindAssemblyExports(IntPtr assemblyNamePtr); [MethodImpl(MethodImplOptions.InternalCall)] - public static extern void GetAssemblyExport(IntPtr assemblyNamePtr, IntPtr namespacePtr, IntPtr classnamePtr, IntPtr methodNamePtr, IntPtr* monoMethodPtrPtr); + public static extern void GetAssemblyExport(IntPtr assemblyNamePtr, IntPtr namespacePtr, IntPtr classnamePtr, IntPtr methodNamePtr, int signatureHash, IntPtr* monoMethodPtrPtr); } } diff --git a/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs b/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs index ff157eb45f26cf..a10d2897f75be0 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.TextInfo.cs @@ -8,8 +8,8 @@ internal static partial class Interop internal static unsafe partial class JsGlobalization { [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe void ChangeCaseInvariant(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper, out int exceptionalResult, out object result); + internal static extern unsafe nint ChangeCaseInvariant(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern unsafe void ChangeCase(in string culture, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper, out int exceptionalResult, out object result); + internal static extern unsafe nint ChangeCase(char* culture, int cultureLen, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper); } } diff --git a/src/libraries/Common/src/Interop/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Interop.Ldap.cs index 7fb63a1d3c5e20..4020dd0fe89bbb 100644 --- a/src/libraries/Common/src/Interop/Interop.Ldap.cs +++ b/src/libraries/Common/src/Interop/Interop.Ldap.cs @@ -4,7 +4,7 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif using System.Security.Authentication; @@ -31,7 +31,7 @@ internal readonly struct Luid public int HighPart => _highPart; } -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #endif [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -49,7 +49,7 @@ internal struct SEC_WINNT_AUTH_IDENTITY_EX public string packageList; public int packageListLength; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(SEC_WINNT_AUTH_IDENTITY_EX), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))] internal static class Marshaller { @@ -176,7 +176,7 @@ internal struct LDAP_TIMEVAL public int tv_usec; } -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(PinningMarshaller))] #endif [StructLayout(LayoutKind.Sequential)] @@ -185,7 +185,7 @@ internal sealed class BerVal public int bv_len; public IntPtr bv_val = IntPtr.Zero; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(BerVal), MarshalMode.ManagedToUnmanagedIn, typeof(PinningMarshaller))] internal static unsafe class PinningMarshaller { @@ -207,7 +207,7 @@ internal sealed class LdapControl public LdapControl() { } } -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #endif [StructLayout(LayoutKind.Sequential)] @@ -217,7 +217,7 @@ internal struct LdapReferralCallback public QUERYFORCONNECTIONInternal query; public NOTIFYOFNEWCONNECTIONInternal notify; public DEREFERENCECONNECTIONInternal dereference; -#if NET7_0_OR_GREATER +#if NET public static readonly unsafe int Size = sizeof(Marshaller.MarshalValue.Native); [CustomMarshaller(typeof(LdapReferralCallback), MarshalMode.ManagedToUnmanagedIn, typeof(MarshalValue))] diff --git a/src/libraries/Common/src/Interop/Interop.Odbc.cs b/src/libraries/Common/src/Interop/Interop.Odbc.cs index 250ef4371298b3..3e751856262025 100644 --- a/src/libraries/Common/src/Interop/Interop.Odbc.cs +++ b/src/libraries/Common/src/Interop/Interop.Odbc.cs @@ -5,7 +5,7 @@ using System.Data.Odbc; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif using System.Runtime.Versioning; @@ -38,7 +38,7 @@ internal static partial ODBC32.SQLRETURN SQLAllocHandle( /*SQLUSMALLINT*/ushort ColumnNumber, /*SQLSMALLINT*/ODBC32.SQL_C TargetType, /*SQLPOINTER*/ -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef TargetValue, @@ -64,13 +64,13 @@ internal static partial ODBC32.SQLRETURN SQLBindCol( /*SQLULEN*/IntPtr cbColDef, /*SQLSMALLINT*/IntPtr ibScale, /*SQLPOINTER*/ -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef rgbValue, /*SQLLEN*/IntPtr BufferLength, /*SQLLEN* */ -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef StrLen_or_Ind); @@ -326,7 +326,7 @@ internal static partial ODBC32.SQLRETURN SQLSetConnectAttrW( /*SQLSMALLINT*/short ColumnNumber, /*SQLSMALLINT*/ODBC32.SQL_DESC FieldIdentifier, /*SQLPOINTER*/ -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef CharacterAttribute, diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.cs index 088ee79ab02580..f9fd00f227f4e7 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EVP.cs @@ -9,6 +9,9 @@ internal static partial class Interop { internal static partial class Crypto { + [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpMdCtxCopyEx")] + internal static partial SafeEvpMdCtxHandle EvpMdCtxCopyEx(SafeEvpMdCtxHandle ctx); + [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpMdCtxCreate")] internal static partial SafeEvpMdCtxHandle EvpMdCtxCreate(IntPtr type); @@ -18,6 +21,13 @@ internal static partial class Crypto [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDigestReset")] internal static partial int EvpDigestReset(SafeEvpMdCtxHandle ctx, IntPtr type); + [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDigestSqueeze")] + private static partial int EvpDigestSqueeze( + SafeEvpMdCtxHandle ctx, + Span md, + uint len, + [MarshalAs(UnmanagedType.Bool)] out bool haveFeature); + [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpDigestUpdate")] internal static partial int EvpDigestUpdate(SafeEvpMdCtxHandle ctx, ReadOnlySpan d, int cnt); @@ -89,6 +99,18 @@ internal static unsafe int EvpDigestXOFOneShot(IntPtr type, ReadOnlySpan s return EvpDigestXOFOneShot(type, source, source.Length, destination, (uint)destination.Length); } + internal static int EvpDigestSqueeze(SafeEvpMdCtxHandle ctx, Span destination) + { + int ret = EvpDigestSqueeze(ctx, destination, (uint)destination.Length, out bool haveFeature); + + if (!haveFeature) + { + throw new PlatformNotSupportedException(); + } + + return ret; + } + internal static readonly int EVP_MAX_MD_SIZE = GetMaxMdSize(); } } diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 8636bbe4884866..171980d0a7654a 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -748,7 +748,7 @@ private static unsafe void RemoveSessionCallback(IntPtr ctx, IntPtr session) IntPtr name = Ssl.SessionGetHostname(session); Debug.Assert(name != IntPtr.Zero); - ctxHandle.RemoveSession(name); + ctxHandle.RemoveSession(name, session); } [UnmanagedCallersOnly] diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs index 5baa776d9d5a8a..d92e15e940e65e 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs @@ -39,6 +39,9 @@ internal static partial class Ssl [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCaching")] internal static unsafe partial int SslCtxSetCaching(SafeSslContextHandle ctx, int mode, int cacheSize, int contextIdLength, Span contextId, delegate* unmanaged neewSessionCallback, delegate* unmanaged removeSessionCallback); + [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxRemoveSession")] + internal static unsafe partial void SslCtxRemoveSession(SafeSslContextHandle ctx, IntPtr session); + internal static bool AddExtraChainCertificates(SafeSslContextHandle ctx, ReadOnlyCollection chain) { // send pre-computed list of intermediates. @@ -142,27 +145,38 @@ internal bool TryAddSession(IntPtr namePtr, IntPtr session) // This will use strdup() so it is safe to pass in raw pointer. Interop.Ssl.SessionSetHostname(session, namePtr); + IntPtr oldSession = IntPtr.Zero; + lock (_sslSessions) { if (!_sslSessions.TryAdd(targetName, session)) { - if (_sslSessions.Remove(targetName, out IntPtr oldSession)) - { - Interop.Ssl.SessionFree(oldSession); - } - + // session to this target host exists, replace it + _sslSessions.Remove(targetName, out oldSession); bool added = _sslSessions.TryAdd(targetName, session); Debug.Assert(added); } } + if (oldSession != IntPtr.Zero) + { + // remove old session also from the internal OpenSSL cache + // and drop reference count. Since SSL_CTX_remove_session + // will call session_remove_cb, we need to do this outside + // of _sslSessions lock to avoid deadlock with another thread + // which could be holding SSL_CTX lock and trying to acquire + // _sslSessions lock. + Interop.Ssl.SslCtxRemoveSession(this, oldSession); + Interop.Ssl.SessionFree(oldSession); + } + return true; } return false; } - internal void RemoveSession(IntPtr namePtr) + internal void RemoveSession(IntPtr namePtr, IntPtr session) { Debug.Assert(_sslSessions != null); @@ -171,11 +185,14 @@ internal void RemoveSession(IntPtr namePtr) if (_sslSessions != null && targetName != null) { - IntPtr oldSession; - bool removed; + IntPtr oldSession = IntPtr.Zero; + bool removed = false; lock (_sslSessions) { - removed = _sslSessions.Remove(targetName, out oldSession); + if (_sslSessions.TryGetValue(targetName, out IntPtr existingSession) && existingSession == session) + { + removed = _sslSessions.Remove(targetName, out oldSession); + } } if (removed) @@ -209,7 +226,6 @@ internal bool TrySetSession(SafeSslHandle sslHandle, string name) // This will increase reference count on the session as needed. // We need to hold lock here to prevent session being deleted before the call is done. Interop.Ssl.SslSetSession(sslHandle, session); - return true; } } diff --git a/src/libraries/Common/src/Interop/Windows/CryptUI/Interop.CryptUIDlgCertificate.cs b/src/libraries/Common/src/Interop/Windows/CryptUI/Interop.CryptUIDlgCertificate.cs index e58a0b497dc412..97b5d4bba72617 100644 --- a/src/libraries/Common/src/Interop/Windows/CryptUI/Interop.CryptUIDlgCertificate.cs +++ b/src/libraries/Common/src/Interop/Windows/CryptUI/Interop.CryptUIDlgCertificate.cs @@ -4,7 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif using Microsoft.Win32.SafeHandles; @@ -13,7 +13,7 @@ internal static partial class Interop { internal static partial class CryptUI { -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #else [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -39,7 +39,7 @@ internal struct CRYPTUI_VIEWCERTIFICATE_STRUCTW internal IntPtr rgPropSheetPages; internal uint nStartPage; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW), MarshalMode.Default, typeof(Marshaller))] public static class Marshaller { @@ -127,7 +127,7 @@ public CRYPTUI_VIEWCERTIFICATE_STRUCTW ToManaged() #endif } -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #else [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -151,7 +151,7 @@ internal struct CRYPTUI_SELECTCERTIFICATE_STRUCTW internal IntPtr rgPropSheetPages; internal IntPtr hSelectedCertStore; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(CRYPTUI_SELECTCERTIFICATE_STRUCTW), MarshalMode.Default, typeof(Marshaller))] public static class Marshaller { diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.AbortDoc.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.AbortDoc.cs index cca83bef74b6a4..0326ead026c334 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.AbortDoc.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.AbortDoc.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -12,7 +12,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial int AbortDoc( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateCompatibleBitmap.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateCompatibleBitmap.cs index e051d8f8d70055..fdfc84cddf583c 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateCompatibleBitmap.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateCompatibleBitmap.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,7 +13,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial IntPtr CreateCompatibleBitmap( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC, int width, int height); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateDIBSection.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateDIBSection.cs index ca024801b4287e..2654d0e653ad19 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateDIBSection.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.CreateDIBSection.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,7 +13,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial IntPtr CreateDIBSection( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hdc, ref BITMAPINFO_FLAT bmi, int iUsage, ref IntPtr ppvBits, IntPtr hSection, int dwOffset); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.DEVMODE.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.DEVMODE.cs index aa26afa85665fb..bb0fa59f771279 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.DEVMODE.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.DEVMODE.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndDoc.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndDoc.cs index b65d8106b34392..2bd8ad72416341 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndDoc.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndDoc.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -12,7 +12,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial int EndDoc( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndPage.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndPage.cs index f09232b01fbacc..0349c5044ba194 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndPage.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.EndPage.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -12,7 +12,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial int EndPage( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ExtEscape.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ExtEscape.cs index 449ba1b934b333..6ade151f8b0660 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ExtEscape.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ExtEscape.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -16,14 +16,14 @@ internal static partial class Gdi32 [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial int ExtEscape( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC, int nEscape, int cbInput, ref int inData, int cbOutput, out int outData); [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial int ExtEscape( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC, int nEscape, int cbInput, byte[] inData, int cbOutput, out int outData); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetDIBits.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetDIBits.cs index 03cbc74a846d5f..11900ac16602ca 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetDIBits.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetDIBits.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,11 +13,11 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32)] internal static partial int GetDIBits( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hdc, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hbm, int arg1, int arg2, IntPtr arg3, ref BITMAPINFO_FLAT bmi, int arg5); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetObject.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetObject.cs index 83fcfa6f9d2359..afb88d5bd14a54 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetObject.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetObject.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,20 +13,20 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, EntryPoint = "GetObjectW", SetLastError = true)] internal static partial int GetObject( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hObject, int nSize, ref BITMAP bm); [LibraryImport(Libraries.Gdi32, EntryPoint = "GetObjectW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)] internal static partial int GetObject( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hObject, int nSize, ref Interop.User32.LOGFONT lf); internal static unsafe int GetObject( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hObject, ref Interop.User32.LOGFONT lp) diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetPaletteEntries.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetPaletteEntries.cs index 4f2f2ed8035918..ab2ad0b6ea33bc 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetPaletteEntries.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.GetPaletteEntries.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -12,7 +12,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32)] internal static partial uint GetPaletteEntries( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hpal, int iStartIndex, int nEntries, byte[] lppe); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.IntersectClipRect.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.IntersectClipRect.cs index a82d6c5514ed2f..0084bcd6265270 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.IntersectClipRect.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.IntersectClipRect.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,7 +13,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial int IntersectClipRect( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC, int x1, int y1, int x2, int y2); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ResetDC.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ResetDC.cs index 3737f3f46699b1..e26750aa2895f9 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ResetDC.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.ResetDC.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,11 +13,11 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, EntryPoint = "ResetDCW", SetLastError = true)] internal static partial IntPtr /*HDC*/ ResetDC( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef /*DEVMODE*/ lpDevMode); diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartDoc.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartDoc.cs index c62da1844b8e6e..8199ff3f217ff3 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartDoc.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartDoc.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,12 +13,12 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, EntryPoint = "StartDocW", SetLastError = true)] internal static partial int StartDoc( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC, in DOCINFO lpDocInfo); -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #endif [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] @@ -32,7 +32,7 @@ internal struct DOCINFO public DOCINFO() { } -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(DOCINFO), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))] public static class Marshaller { diff --git a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartPage.cs b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartPage.cs index 00ecc844d7e8a3..549151d43337dd 100644 --- a/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartPage.cs +++ b/src/libraries/Common/src/Interop/Windows/Gdi32/Interop.StartPage.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -12,7 +12,7 @@ internal static partial class Gdi32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial int StartPage( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC); diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SelectObject.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SelectObject.cs index efcc90a00fb256..da8fb34e900af0 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SelectObject.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SelectObject.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,11 +13,11 @@ internal static partial class Kernel32 { [LibraryImport(Libraries.Gdi32, SetLastError = true)] internal static partial IntPtr SelectObject( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hdc, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef obj); diff --git a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs index 41c079d5ad144e..ec001c0b55a93d 100644 --- a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs +++ b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Properties.cs @@ -56,7 +56,7 @@ internal static unsafe ErrorCode NCryptGetIntProperty(SafeNCryptHandle hObject, { fixed (int* pResult = &result) { -#if NETSTANDARD || NETCOREAPP +#if NETSTANDARD || NET Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); #endif diff --git a/src/libraries/Common/src/Interop/Windows/Shell32/Interop.ExtractAssociatedIcon.cs b/src/libraries/Common/src/Interop/Windows/Shell32/Interop.ExtractAssociatedIcon.cs index 6162795d061e19..d71fc5b7a0835a 100644 --- a/src/libraries/Common/src/Interop/Windows/Shell32/Interop.ExtractAssociatedIcon.cs +++ b/src/libraries/Common/src/Interop/Windows/Shell32/Interop.ExtractAssociatedIcon.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,7 +13,7 @@ internal static partial class Shell32 { [LibraryImport(Libraries.Shell32, EntryPoint = "ExtractAssociatedIconW")] internal static unsafe partial IntPtr ExtractAssociatedIcon( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hInst, char* iconPath, ref int index); diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.CopyImage.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.CopyImage.cs index 4211c156c36552..b971b37309311e 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.CopyImage.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.CopyImage.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,7 +13,7 @@ internal static partial class User32 { [LibraryImport(Libraries.User32, SetLastError = true)] internal static partial IntPtr CopyImage( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hImage, int uType, int cxDesired, int cyDesired, int fuFlags); diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.CreateIconFromResourceEx.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.CreateIconFromResourceEx.cs index a295619f2ac4a3..9c11ee7eba900b 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.CreateIconFromResourceEx.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.CreateIconFromResourceEx.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.DestroyIcon.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.DestroyIcon.cs index 1528c6ae181eb3..782dbcec0e7f4c 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.DestroyIcon.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.DestroyIcon.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -14,7 +14,7 @@ internal static partial class User32 [LibraryImport(Libraries.User32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool DestroyIcon( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hIcon); diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.DrawIconEx.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.DrawIconEx.cs index 6ac69016bde602..9c0a0bfee89ea3 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.DrawIconEx.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.DrawIconEx.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -14,15 +14,15 @@ internal static partial class User32 [LibraryImport(Libraries.User32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool DrawIconEx( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hDC, int x, int y, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hIcon, int width, int height, int iStepIfAniCursor, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hBrushFlickerFree, int diFlags); diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.GetIconInfo.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.GetIconInfo.cs index e97f54e2e8f6ee..faa505574e6b8c 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.GetIconInfo.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.GetIconInfo.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -14,7 +14,7 @@ internal static partial class User32 [LibraryImport(Libraries.User32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static partial bool GetIconInfo( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hIcon, ref ICONINFO info); diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.GetSystemMetrics.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.GetSystemMetrics.cs index 761e69a4a2c829..4232c4348719e9 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.GetSystemMetrics.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.GetSystemMetrics.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadIcon.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadIcon.cs index f391366d89b125..378129442bf185 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadIcon.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadIcon.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,7 +13,7 @@ internal static partial class User32 { [LibraryImport(Libraries.User32, EntryPoint = "LoadIconW", SetLastError = true)] internal static partial IntPtr LoadIcon( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hInst, IntPtr iconId); diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs index 7e1010013c35d5..69457b97300730 100644 --- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs +++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif using System.Text; @@ -45,7 +45,7 @@ public static partial SafeWinHttpHandle WinHttpOpenRequest( [return: MarshalAs(UnmanagedType.Bool)] public static partial bool WinHttpAddRequestHeaders( SafeWinHttpHandle requestHandle, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(SimpleStringBufferMarshaller))] StringBuilder headers, #else #pragma warning disable CA1838 // Uses pooled StringBuilder @@ -55,7 +55,7 @@ public static partial bool WinHttpAddRequestHeaders( uint headersLength, uint modifiers); -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(StringBuilder), MarshalMode.ManagedToUnmanagedIn, typeof(SimpleStringBufferMarshaller))] private static unsafe class SimpleStringBufferMarshaller { diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs index 1cbdfa79d5962a..e76fa9b67e5bcb 100644 --- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs +++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif using System.Text; @@ -247,7 +247,7 @@ public delegate void WINHTTP_STATUS_CALLBACK( IntPtr statusInformation, uint statusInformationLength); -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #endif [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -261,7 +261,7 @@ public struct WINHTTP_AUTOPROXY_OPTIONS public uint Reserved2; [MarshalAs(UnmanagedType.Bool)] public bool AutoLoginIfChallenged; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(WINHTTP_AUTOPROXY_OPTIONS), MarshalMode.Default, typeof(Marshaller))] public static class Marshaller { diff --git a/src/libraries/Common/src/Interop/Windows/WinMm/Interop.waveOutGetDevCaps.cs b/src/libraries/Common/src/Interop/Windows/WinMm/Interop.waveOutGetDevCaps.cs index a9ebcba2950c55..954101a9c3cbee 100644 --- a/src/libraries/Common/src/Interop/Windows/WinMm/Interop.waveOutGetDevCaps.cs +++ b/src/libraries/Common/src/Interop/Windows/WinMm/Interop.waveOutGetDevCaps.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -12,7 +12,7 @@ internal static partial class Interop internal static partial class WinMM { #pragma warning disable CA1823 // unused fields -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #endif internal struct WAVEOUTCAPS @@ -27,7 +27,7 @@ internal struct WAVEOUTCAPS private ushort wChannels; private ushort wReserved1; private ushort dwSupport; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(WAVEOUTCAPS), MarshalMode.Default, typeof(Marshaller))] public static class Marshaller { diff --git a/src/libraries/Common/src/Interop/Windows/Winspool/Interop.DocumentProperties.cs b/src/libraries/Common/src/Interop/Windows/Winspool/Interop.DocumentProperties.cs index bf54cfb1b5b90c..8e7b6ce0c9d763 100644 --- a/src/libraries/Common/src/Interop/Windows/Winspool/Interop.DocumentProperties.cs +++ b/src/libraries/Common/src/Interop/Windows/Winspool/Interop.DocumentProperties.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif @@ -13,26 +13,26 @@ internal static partial class Winspool { [LibraryImport(Libraries.Winspool, EntryPoint = "DocumentPropertiesW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)] internal static partial int DocumentProperties( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hwnd, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hPrinter, string pDeviceName, IntPtr /*DEVMODE*/ pDevModeOutput, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef /*DEVMODE*/ pDevModeInput, int fMode); [LibraryImport(Libraries.Winspool, EntryPoint = "DocumentPropertiesW", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)] internal static partial int DocumentProperties( -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hwnd, -#if NET7_0_OR_GREATER +#if NET [MarshalUsing(typeof(HandleRefMarshaller))] #endif HandleRef hPrinter, string pDeviceName, IntPtr /*DEVMODE*/ pDevModeOutput, IntPtr /*DEVMODE*/ pDevModeInput, int fMode); diff --git a/src/libraries/Common/src/Interop/Windows/Winspool/Interop.EnumPrinters.cs b/src/libraries/Common/src/Interop/Windows/Winspool/Interop.EnumPrinters.cs index ca967e11d16d86..baeed522bb0c82 100644 --- a/src/libraries/Common/src/Interop/Windows/Winspool/Interop.EnumPrinters.cs +++ b/src/libraries/Common/src/Interop/Windows/Winspool/Interop.EnumPrinters.cs @@ -3,7 +3,7 @@ using System; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif diff --git a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeHandleCache.cs b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeHandleCache.cs index 2ce8fbf1b378d5..76e58eeaf7e732 100644 --- a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeHandleCache.cs +++ b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeHandleCache.cs @@ -21,11 +21,13 @@ internal static class SafeHandleCache where T : SafeHandle /// internal static T GetInvalidHandle(Func invalidHandleFactory) { - T? currentHandle = Volatile.Read(ref s_invalidHandle); - if (currentHandle == null) + return s_invalidHandle ?? CreateInvalidHandle(invalidHandleFactory); + + static T CreateInvalidHandle(Func invalidHandleFactory) { T newHandle = invalidHandleFactory(); - currentHandle = Interlocked.CompareExchange(ref s_invalidHandle, newHandle, null); + T? currentHandle = Interlocked.CompareExchange(ref s_invalidHandle, newHandle, null); + if (currentHandle == null) { GC.SuppressFinalize(newHandle); @@ -35,9 +37,10 @@ internal static T GetInvalidHandle(Func invalidHandleFactory) { newHandle.Dispose(); } + + Debug.Assert(currentHandle.IsInvalid); + return currentHandle; } - Debug.Assert(currentHandle.IsInvalid); - return currentHandle; } /// Gets whether the specified handle is invalid handle. @@ -46,7 +49,7 @@ internal static T GetInvalidHandle(Func invalidHandleFactory) internal static bool IsCachedInvalidHandle(SafeHandle handle) { Debug.Assert(handle != null); - bool isCachedInvalidHandle = ReferenceEquals(handle, Volatile.Read(ref s_invalidHandle)); + bool isCachedInvalidHandle = ReferenceEquals(handle, s_invalidHandle); Debug.Assert(!isCachedInvalidHandle || handle.IsInvalid, "The cached invalid handle must still be invalid."); return isCachedInvalidHandle; } diff --git a/src/libraries/Common/src/System/CodeDom/CodeTypeReference.cs b/src/libraries/Common/src/System/CodeDom/CodeTypeReference.cs index 615d6017e37e37..cb75ff887f6871 100644 --- a/src/libraries/Common/src/System/CodeDom/CodeTypeReference.cs +++ b/src/libraries/Common/src/System/CodeDom/CodeTypeReference.cs @@ -42,7 +42,7 @@ public CodeTypeReference() public CodeTypeReference(Type type) { -#if NET5_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(type); #else if (type is null) @@ -271,7 +271,7 @@ private void Initialize(string? typeName, CodeTypeReferenceOptions options) } // Now see if we have some arity. baseType could be null if this is an array type. -#if NET5_0_OR_GREATER +#if NET if (_baseType != null && _baseType.Contains('`')) // string.Contains(char) is .NetCore2.1+ specific #else if (_baseType != null && _baseType.IndexOf('`') != -1) // string.Contains(char) is .NetCore2.1+ specific diff --git a/src/libraries/Common/src/System/CodeDom/CodeTypeReferenceCollection.cs b/src/libraries/Common/src/System/CodeDom/CodeTypeReferenceCollection.cs index 21b2ae857366ac..55119bc720664b 100644 --- a/src/libraries/Common/src/System/CodeDom/CodeTypeReferenceCollection.cs +++ b/src/libraries/Common/src/System/CodeDom/CodeTypeReferenceCollection.cs @@ -41,7 +41,7 @@ public CodeTypeReference this[int index] public void AddRange(CodeTypeReference[] value) { -#if NET5_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(value); #else if (value is null) @@ -58,7 +58,7 @@ public void AddRange(CodeTypeReference[] value) public void AddRange(CodeTypeReferenceCollection value) { -#if NET5_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(value); #else if (value is null) diff --git a/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs b/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs index 936c81c094e45d..da3b254f99eb25 100644 --- a/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs +++ b/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs @@ -50,7 +50,7 @@ internal partial class DbConnectionOptions private static readonly Regex s_connectionStringRegex = CreateConnectionStringRegex(); private static readonly Regex s_connectionStringRegexOdbc = CreateConnectionStringRegexOdbc(); -#if NET7_0_OR_GREATER +#if NET [GeneratedRegex(ConnectionStringPattern, RegexOptions.ExplicitCapture)] private static partial Regex CreateConnectionStringRegex(); @@ -67,7 +67,7 @@ internal partial class DbConnectionOptions private static readonly Regex s_connectionStringQuoteValueRegex = CreateConnectionStringQuoteValueRegex(); // generally do not quote the value if it matches the pattern private static readonly Regex s_connectionStringQuoteOdbcValueRegex = CreateConnectionStringQuoteOdbcValueRegex(); // do not quote odbc value if it matches this pattern -#if NET7_0_OR_GREATER +#if NET [GeneratedRegex("^(?![;\\s])[^\\p{Cc}]+(? + { + public readonly Uri UriPrefix; + public readonly int UriPrefixLength = -1; + public readonly string AuthenticationType; + + internal CredentialCacheKey(Uri uriPrefix, string authenticationType) + { + Debug.Assert(uriPrefix != null); + Debug.Assert(authenticationType != null); + + UriPrefix = uriPrefix; + UriPrefixLength = UriPrefix.AbsolutePath.LastIndexOf('/'); + AuthenticationType = authenticationType; + } + + internal bool Match(Uri uri, string authenticationType) + { + if (uri == null || authenticationType == null) + { + return false; + } + + // If the protocols don't match, this credential is not applicable for the given Uri. + if (!string.Equals(authenticationType, AuthenticationType, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Match({UriPrefix} & {uri})"); + + return IsPrefix(uri, UriPrefix); + } + + // IsPrefix (Uri) + // + // Determines whether is a prefix of this URI. A prefix + // match is defined as: + // + // scheme match + // + host match + // + port match, if any + // + path is a prefix of path, if any + // + // Returns: + // True if is a prefix of this URI + private static bool IsPrefix(Uri uri, Uri prefixUri) + { + Debug.Assert(uri != null); + Debug.Assert(prefixUri != null); + + if (prefixUri.Scheme != uri.Scheme || prefixUri.Host != uri.Host || prefixUri.Port != uri.Port) + { + return false; + } + + int prefixLen = prefixUri.AbsolutePath.LastIndexOf('/'); + if (prefixLen > uri.AbsolutePath.LastIndexOf('/')) + { + return false; + } + + return string.Compare(uri.AbsolutePath, 0, prefixUri.AbsolutePath, 0, prefixLen, StringComparison.OrdinalIgnoreCase) == 0; + } + + public override int GetHashCode() => + StringComparer.OrdinalIgnoreCase.GetHashCode(AuthenticationType) ^ + UriPrefix.GetHashCode(); + + public bool Equals([NotNullWhen(true)] CredentialCacheKey? other) + { + if (other == null) + { + return false; + } + + bool equals = + string.Equals(AuthenticationType, other.AuthenticationType, StringComparison.OrdinalIgnoreCase) && + UriPrefix.Equals(other.UriPrefix); + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Equals({this},{other}) returns {equals}"); + + return equals; + } + + public override bool Equals([NotNullWhen(true)] object? obj) => Equals(obj as CredentialCacheKey); + + public override string ToString() => + string.Create(CultureInfo.InvariantCulture, $"[{UriPrefixLength}]:{UriPrefix}:{AuthenticationType}"); + } + + internal static class CredentialCacheHelper + { + public static bool TryGetCredential(Dictionary cache, Uri uriPrefix, string authType, [NotNullWhen(true)] out Uri? mostSpecificMatchUri, [NotNullWhen(true)] out NetworkCredential? mostSpecificMatch) + { + int longestMatchPrefix = -1; + mostSpecificMatch = null; + mostSpecificMatchUri = null; + + // Enumerate through every credential in the cache + foreach ((CredentialCacheKey key, NetworkCredential value) in cache) + { + // Determine if this credential is applicable to the current Uri/AuthType + if (key.Match(uriPrefix, authType)) + { + int prefixLen = key.UriPrefixLength; + + // Check if the match is better than the current-most-specific match + if (prefixLen > longestMatchPrefix) + { + // Yes: update the information about currently preferred match + longestMatchPrefix = prefixLen; + mostSpecificMatch = value; + mostSpecificMatchUri = key.UriPrefix; + } + } + } + + return mostSpecificMatch != null; + } + } +} diff --git a/src/libraries/Common/src/System/Number.Formatting.Common.cs b/src/libraries/Common/src/System/Number.Formatting.Common.cs index 4caa59472eaea4..672ff2402682b9 100644 --- a/src/libraries/Common/src/System/Number.Formatting.Common.cs +++ b/src/libraries/Common/src/System/Number.Formatting.Common.cs @@ -12,6 +12,8 @@ namespace System { internal static partial class Number { + private const int CharStackBufferSize = 32; + private const int DefaultPrecisionExponentialFormat = 6; private const int MaxUInt32DecDigits = 10; diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs b/src/libraries/Common/src/System/Reflection/AssemblyNameFormatter.cs similarity index 92% rename from src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs rename to src/libraries/Common/src/System/Reflection/AssemblyNameFormatter.cs index c1a810db507557..b4fbdca1e9091e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs +++ b/src/libraries/Common/src/System/Reflection/AssemblyNameFormatter.cs @@ -6,6 +6,8 @@ using System.Globalization; using System.Text; +#nullable enable + namespace System.Reflection { internal static class AssemblyNameFormatter @@ -91,7 +93,8 @@ private static void AppendQuoted(this ref ValueStringBuilder vsb, string s) // App-compat: You can use double or single quotes to quote a name, and Fusion (or rather the IdentityAuthority) picks one // by some algorithm. Rather than guess at it, we use double quotes consistently. - if (s != s.Trim() || s.Contains('\"') || s.Contains('\'')) + ReadOnlySpan span = s.AsSpan(); + if (s.Length != span.Trim().Length || span.IndexOfAny('\"', '\'') >= 0) needsQuoting = true; if (needsQuoting) @@ -125,5 +128,12 @@ private static void AppendQuoted(this ref ValueStringBuilder vsb, string s) if (needsQuoting) vsb.Append(quoteChar); } + +#if !NET + private static void AppendSpanFormattable(this ref ValueStringBuilder vsb, ushort value) + { + vsb.Append(value.ToString()); + } +#endif } } diff --git a/src/libraries/Common/src/System/Reflection/AssemblyNameParser.cs b/src/libraries/Common/src/System/Reflection/AssemblyNameParser.cs new file mode 100644 index 00000000000000..bfd91d781a4ecc --- /dev/null +++ b/src/libraries/Common/src/System/Reflection/AssemblyNameParser.cs @@ -0,0 +1,506 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.CompilerServices; +using System.Text; + +#nullable enable + +namespace System.Reflection +{ + /// + /// Parses an assembly name. + /// + internal ref partial struct AssemblyNameParser + { + public readonly struct AssemblyNameParts + { + public AssemblyNameParts(string name, Version? version, string? cultureName, AssemblyNameFlags flags, byte[]? publicKeyOrToken) + { + _name = name; + _version = version; + _cultureName = cultureName; + _flags = flags; + _publicKeyOrToken = publicKeyOrToken; + } + + public readonly string _name; + public readonly Version? _version; + public readonly string? _cultureName; + public readonly AssemblyNameFlags _flags; + public readonly byte[]? _publicKeyOrToken; + } + + /// + /// Token categories for the lexer. + /// + private enum Token + { + Equals = 1, + Comma = 2, + String = 3, + End = 4, + } + + private enum AttributeKind + { + Version = 1, + Culture = 2, + PublicKeyOrToken = 4, + ProcessorArchitecture = 8, + Retargetable = 16, + ContentType = 32 + } + + private readonly ReadOnlySpan _input; + private int _index; + + private AssemblyNameParser(ReadOnlySpan input) + { +#if SYSTEM_PRIVATE_CORELIB + if (input.Length == 0) + throw new ArgumentException(SR.Format_StringZeroLength); +#else + Debug.Assert(input.Length > 0); +#endif + + _input = input; + _index = 0; + } + +#if SYSTEM_PRIVATE_CORELIB + public static AssemblyNameParts Parse(string name) => Parse(name.AsSpan()); + + public static AssemblyNameParts Parse(ReadOnlySpan name) + { + AssemblyNameParser parser = new(name); + AssemblyNameParts result = default; + if (parser.TryParse(ref result)) + { + return result; + } + throw new FileLoadException(SR.InvalidAssemblyName, name.ToString()); + } +#endif + + internal static bool TryParse(ReadOnlySpan name, ref AssemblyNameParts parts) + { + AssemblyNameParser parser = new(name); + return parser.TryParse(ref parts); + } + + private static bool TryRecordNewSeen(scoped ref AttributeKind seenAttributes, AttributeKind newAttribute) + { + if ((seenAttributes & newAttribute) != 0) + { + return false; + } + seenAttributes |= newAttribute; + return true; + } + + private bool TryParse(ref AssemblyNameParts result) + { + // Name must come first. + if (!TryGetNextToken(out string name, out Token token) || token != Token.String || string.IsNullOrEmpty(name)) + return false; + + Version? version = null; + string? cultureName = null; + byte[]? pkt = null; + AssemblyNameFlags flags = 0; + + AttributeKind alreadySeen = default; + if (!TryGetNextToken(out _, out token)) + return false; + + while (token != Token.End) + { + if (token != Token.Comma) + return false; + + if (!TryGetNextToken(out string attributeName, out token) || token != Token.String) + return false; + + if (!TryGetNextToken(out _, out token) || token != Token.Equals) + return false; + + if (!TryGetNextToken(out string attributeValue, out token) || token != Token.String) + return false; + + if (attributeName == string.Empty) + return false; + + if (IsAttribute(attributeName, "Version")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.Version)) + { + return false; + } + if (!TryParseVersion(attributeValue, ref version)) + { + return false; + } + } + else if (IsAttribute(attributeName, "Culture")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.Culture)) + { + return false; + } + if (!TryParseCulture(attributeValue, out cultureName)) + { + return false; + } + } + else if (IsAttribute(attributeName, "PublicKeyToken")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.PublicKeyOrToken)) + { + return false; + } + if (!TryParsePKT(attributeValue, isToken: true, out pkt)) + { + return false; + } + } + else if (IsAttribute(attributeName, "PublicKey")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.PublicKeyOrToken)) + { + return false; + } + if (!TryParsePKT(attributeValue, isToken: false, out pkt)) + { + return false; + } + flags |= AssemblyNameFlags.PublicKey; + } + else if (IsAttribute(attributeName, "ProcessorArchitecture")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.ProcessorArchitecture)) + { + return false; + } + if (!TryParseProcessorArchitecture(attributeValue, out ProcessorArchitecture arch)) + { + return false; + } + flags |= (AssemblyNameFlags)(((int)arch) << 4); + } + else if (IsAttribute(attributeName, "Retargetable")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.Retargetable)) + { + return false; + } + + if (attributeValue.Equals("Yes", StringComparison.OrdinalIgnoreCase)) + { + flags |= AssemblyNameFlags.Retargetable; + } + else if (attributeValue.Equals("No", StringComparison.OrdinalIgnoreCase)) + { + // nothing to do + } + else + { + return false; + } + } + else if (IsAttribute(attributeName, "ContentType")) + { + if (!TryRecordNewSeen(ref alreadySeen, AttributeKind.ContentType)) + { + return false; + } + + if (attributeValue.Equals("WindowsRuntime", StringComparison.OrdinalIgnoreCase)) + { + flags |= (AssemblyNameFlags)(((int)AssemblyContentType.WindowsRuntime) << 9); + } + else + { + return false; + } + } + else + { + // Desktop compat: If we got here, the attribute name is unknown to us. Ignore it. + } + + if (!TryGetNextToken(out _, out token)) + { + return false; + } + } + + result = new AssemblyNameParts(name, version, cultureName, flags, pkt); + return true; + } + + private static bool IsAttribute(string candidate, string attributeKind) + => candidate.Equals(attributeKind, StringComparison.OrdinalIgnoreCase); + + private static bool TryParseVersion(string attributeValue, ref Version? version) + { +#if NET8_0_OR_GREATER + ReadOnlySpan attributeValueSpan = attributeValue; + Span parts = stackalloc Range[5]; + parts = parts.Slice(0, attributeValueSpan.Split(parts, '.')); +#else + string[] parts = attributeValue.Split('.'); +#endif + if (parts.Length is < 2 or > 4) + { + return false; + } + + Span versionNumbers = stackalloc ushort[4] { ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue }; + for (int i = 0; i < parts.Length; i++) + { + if (!ushort.TryParse( +#if NET8_0_OR_GREATER + attributeValueSpan[parts[i]], +#else + parts[i], +#endif + NumberStyles.None, NumberFormatInfo.InvariantInfo, out versionNumbers[i])) + { + return false; + } + } + + if (versionNumbers[0] == ushort.MaxValue || + versionNumbers[1] == ushort.MaxValue) + { + return false; + } + + version = + versionNumbers[2] == ushort.MaxValue ? new Version(versionNumbers[0], versionNumbers[1]) : + versionNumbers[3] == ushort.MaxValue ? new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2]) : + new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2], versionNumbers[3]); + + return true; + } + + private static bool TryParseCulture(string attributeValue, out string? result) + { + if (attributeValue.Equals("Neutral", StringComparison.OrdinalIgnoreCase)) + { + result = ""; + return true; + } + + result = attributeValue; + return true; + } + + private static bool TryParsePKT(string attributeValue, bool isToken, out byte[]? result) + { + if (attributeValue.Equals("null", StringComparison.OrdinalIgnoreCase) || attributeValue == string.Empty) + { + result = Array.Empty(); + return true; + } + + if (attributeValue.Length % 2 != 0 || (isToken && attributeValue.Length != 8 * 2)) + { + result = null; + return false; + } + + byte[] pkt = new byte[attributeValue.Length / 2]; + if (!HexConverter.TryDecodeFromUtf16(attributeValue.AsSpan(), pkt, out int _)) + { + result = null; + return false; + } + + result = pkt; + return true; + } + + private static bool TryParseProcessorArchitecture(string attributeValue, out ProcessorArchitecture result) + { + result = attributeValue switch + { + _ when attributeValue.Equals("msil", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.MSIL, + _ when attributeValue.Equals("x86", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.X86, + _ when attributeValue.Equals("ia64", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.IA64, + _ when attributeValue.Equals("amd64", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.Amd64, + _ when attributeValue.Equals("arm", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.Arm, + _ when attributeValue.Equals("msil", StringComparison.OrdinalIgnoreCase) => ProcessorArchitecture.MSIL, + _ => ProcessorArchitecture.None + }; + return result != ProcessorArchitecture.None; + } + + private static bool IsWhiteSpace(char ch) + => ch is '\n' or '\r' or ' ' or '\t'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool TryGetNextChar(out char ch) + { + if (_index < _input.Length) + { + ch = _input[_index++]; + if (ch == '\0') + { + return false; + } + } + else + { + ch = '\0'; + } + + return true; + } + + // + // Return the next token in assembly name. If the result is Token.String, + // sets "tokenString" to the tokenized string. + // + private bool TryGetNextToken(out string tokenString, out Token token) + { + tokenString = string.Empty; + char c; + + while (true) + { + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + + switch (c) + { + case ',': + { + token = Token.Comma; + return true; + } + case '=': + { + token = Token.Equals; + return true; + } + case '\0': + { + token = Token.End; + return true; + } + } + + if (!IsWhiteSpace(c)) + { + break; + } + } + + using ValueStringBuilder sb = new ValueStringBuilder(stackalloc char[64]); + + char quoteChar = '\0'; + if (c is '\'' or '\"') + { + quoteChar = c; + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + } + + for (; ; ) + { + if (c == 0) + { + if (quoteChar != 0) + { + // EOS and unclosed quotes is an error + token = default; + return false; + } + // Reached end of input and therefore of string + break; + } + + if (quoteChar != 0 && c == quoteChar) + break; // Terminate: Found closing quote of quoted string. + + if (quoteChar == 0 && (c is ',' or '=')) + { + _index--; + break; // Terminate: Found start of a new ',' or '=' token. + } + + if (quoteChar == 0 && (c is '\'' or '\"')) + { + token = default; + return false; + } + + if (c is '\\') + { + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + + switch (c) + { + case '\\': + case ',': + case '=': + case '\'': + case '"': + sb.Append(c); + break; + case 't': + sb.Append('\t'); + break; + case 'r': + sb.Append('\r'); + break; + case 'n': + sb.Append('\n'); + break; + default: + token = default; + return false; + } + } + else + { + sb.Append(c); + } + + if (!TryGetNextChar(out c)) + { + token = default; + return false; + } + } + + + int length = sb.Length; + if (quoteChar == 0) + { + while (length > 0 && IsWhiteSpace(sb[length - 1])) + length--; + } + + tokenString = sb.AsSpan(0, length).ToString(); + token = Token.String; + return true; + } + } +} diff --git a/src/libraries/Common/src/System/Reflection/Metadata/AssemblyNameInfo.cs b/src/libraries/Common/src/System/Reflection/Metadata/AssemblyNameInfo.cs new file mode 100644 index 00000000000000..cb4de9467f660b --- /dev/null +++ b/src/libraries/Common/src/System/Reflection/Metadata/AssemblyNameInfo.cs @@ -0,0 +1,215 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text; + +#if !SYSTEM_PRIVATE_CORELIB +using System.Collections.Immutable; +using System.Linq; +#endif + +namespace System.Reflection.Metadata +{ + /// + /// Describes an assembly. + /// + /// + /// It's a more lightweight, immutable version of that does not pre-allocate instances. + /// + [DebuggerDisplay("{FullName}")] +#if SYSTEM_REFLECTION_METADATA + public +#else + internal +#endif + sealed class AssemblyNameInfo + { + internal readonly AssemblyNameFlags _flags; + private string? _fullName; + +#if !SYSTEM_PRIVATE_CORELIB + /// + /// Initializes a new instance of the AssemblyNameInfo class. + /// + /// The simple name of the assembly. + /// The version of the assembly. + /// The name of the culture associated with the assembly. + /// The attributes of the assembly. + /// The public key or its token. Set to when it's public key. + /// is null. + public AssemblyNameInfo(string name, Version? version = null, string? cultureName = null, AssemblyNameFlags flags = AssemblyNameFlags.None, ImmutableArray publicKeyOrToken = default) + { + Name = name ?? throw new ArgumentNullException(nameof(name)); + Version = version; + CultureName = cultureName; + _flags = flags; + PublicKeyOrToken = publicKeyOrToken; + } +#endif + + internal AssemblyNameInfo(AssemblyNameParser.AssemblyNameParts parts) + { + Name = parts._name; + Version = parts._version; + CultureName = parts._cultureName; + _flags = parts._flags; +#if SYSTEM_PRIVATE_CORELIB + PublicKeyOrToken = parts._publicKeyOrToken; +#else + PublicKeyOrToken = parts._publicKeyOrToken is null ? default : parts._publicKeyOrToken.Length == 0 + ? ImmutableArray.Empty + #if NET8_0_OR_GREATER + : Runtime.InteropServices.ImmutableCollectionsMarshal.AsImmutableArray(parts._publicKeyOrToken); + #else + : ImmutableArray.Create(parts._publicKeyOrToken); + #endif +#endif + } + + /// + /// Gets the simple name of the assembly. + /// + public string Name { get; } + + /// + /// Gets the version of the assembly. + /// + public Version? Version { get; } + + /// + /// Gets the name of the culture associated with the assembly. + /// + public string? CultureName { get; } + + /// + /// Gets the attributes of the assembly. + /// + public AssemblyNameFlags Flags => _flags; + + /// + /// Gets the public key or the public key token of the assembly. + /// + /// Check for flag to see whether it's public key or its token. +#if SYSTEM_PRIVATE_CORELIB + public byte[]? PublicKeyOrToken { get; } +#else + public ImmutableArray PublicKeyOrToken { get; } +#endif + + /// + /// Gets the full name of the assembly, also known as the display name. + /// + /// In contrary to it does not validate public key token neither computes it based on the provided public key. + public string FullName + { + get + { + if (_fullName is null) + { + byte[]? publicKeyToken = ((Flags & AssemblyNameFlags.PublicKey) != 0) ? null : +#if SYSTEM_PRIVATE_CORELIB + PublicKeyOrToken; +#elif NET8_0_OR_GREATER + !PublicKeyOrToken.IsDefault ? Runtime.InteropServices.ImmutableCollectionsMarshal.AsArray(PublicKeyOrToken) : null; +#else + !PublicKeyOrToken.IsDefault ? PublicKeyOrToken.ToArray() : null; +#endif + _fullName = AssemblyNameFormatter.ComputeDisplayName(Name, Version, CultureName, publicKeyToken, + ExtractAssemblyNameFlags(_flags), ExtractAssemblyContentType(_flags)); + } + + return _fullName; + } + } + + /// + /// Initializes a new instance of the class based on the stored information. + /// + public AssemblyName ToAssemblyName() + { + AssemblyName assemblyName = new(); + assemblyName.Name = Name; + assemblyName.CultureName = CultureName; + assemblyName.Version = Version; + assemblyName.Flags = Flags; + assemblyName.ContentType = ExtractAssemblyContentType(_flags); +#pragma warning disable SYSLIB0037 // Type or member is obsolete + assemblyName.ProcessorArchitecture = ExtractProcessorArchitecture(_flags); +#pragma warning restore SYSLIB0037 // Type or member is obsolete + +#if SYSTEM_PRIVATE_CORELIB + if (PublicKeyOrToken is not null) + { + if ((Flags & AssemblyNameFlags.PublicKey) != 0) + { + assemblyName.SetPublicKey(PublicKeyOrToken); + } + else + { + assemblyName.SetPublicKeyToken(PublicKeyOrToken); + } + } +#else + if (!PublicKeyOrToken.IsDefault) + { +#pragma warning disable RS0030 // TypeSystem does not allow System.Linq, but we need to use System.Linq.ImmutableArrayExtensions.ToArray + // A copy of the array needs to be created, as AssemblyName allows for the mutation of provided array. + if ((Flags & AssemblyNameFlags.PublicKey) != 0) + { + assemblyName.SetPublicKey(PublicKeyOrToken.ToArray()); + } + else + { + assemblyName.SetPublicKeyToken(PublicKeyOrToken.ToArray()); + } +#pragma warning restore RS0030 + } +#endif + + return assemblyName; + } + + /// + /// Parses a span of characters into a assembly name. + /// + /// A span containing the characters representing the assembly name to parse. + /// Parsed type name. + /// Provided assembly name was invalid. + public static AssemblyNameInfo Parse(ReadOnlySpan assemblyName) + => TryParse(assemblyName, out AssemblyNameInfo? result) + ? result! + : throw new ArgumentException(SR.InvalidAssemblyName, nameof(assemblyName)); + + /// + /// Tries to parse a span of characters into an assembly name. + /// + /// A span containing the characters representing the assembly name to parse. + /// Contains the result when parsing succeeds. + /// true if assembly name was converted successfully, otherwise, false. + public static bool TryParse(ReadOnlySpan assemblyName, [NotNullWhen(true)] out AssemblyNameInfo? result) + { + AssemblyNameParser.AssemblyNameParts parts = default; + if (AssemblyNameParser.TryParse(assemblyName, ref parts)) + { + result = new(parts); + return true; + } + + result = null; + return false; + } + + internal static AssemblyNameFlags ExtractAssemblyNameFlags(AssemblyNameFlags combinedFlags) + => combinedFlags & unchecked((AssemblyNameFlags)0xFFFFF10F); + + internal static AssemblyContentType ExtractAssemblyContentType(AssemblyNameFlags flags) + => (AssemblyContentType)((((int)flags) >> 9) & 0x7); + + internal static ProcessorArchitecture ExtractProcessorArchitecture(AssemblyNameFlags flags) + => (ProcessorArchitecture)((((int)flags) >> 4) & 0x7); + } +} diff --git a/src/libraries/Common/src/System/Reflection/Metadata/TypeName.cs b/src/libraries/Common/src/System/Reflection/Metadata/TypeName.cs new file mode 100644 index 00000000000000..1464f0248280b2 --- /dev/null +++ b/src/libraries/Common/src/System/Reflection/Metadata/TypeName.cs @@ -0,0 +1,398 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Text; + +#if !SYSTEM_PRIVATE_CORELIB +using System.Collections.Immutable; +#endif + +namespace System.Reflection.Metadata +{ + [DebuggerDisplay("{AssemblyQualifiedName}")] +#if SYSTEM_REFLECTION_METADATA + public +#else + internal +#endif + sealed class TypeName + { + /// + /// Positive value is array rank. + /// Negative value is modifier encoded using constants defined in . + /// + private readonly sbyte _rankOrModifier; + /// + /// To avoid the need of allocating a string for all declaring types (example: A+B+C+D+E+F+G), + /// length of the name is stored and the fullName passed in ctor represents the full name of the nested type. + /// So when the name is needed, a substring is being performed. + /// + private readonly int _nestedNameLength; + private readonly TypeName? _elementOrGenericType; + private readonly TypeName? _declaringType; +#if SYSTEM_PRIVATE_CORELIB + private readonly List? _genericArguments; +#else + private readonly ImmutableArray _genericArguments; +#endif + private string? _name, _fullName, _assemblyQualifiedName; + + internal TypeName(string? fullName, + AssemblyNameInfo? assemblyName, + TypeName? elementOrGenericType = default, + TypeName? declaringType = default, +#if SYSTEM_PRIVATE_CORELIB + List? genericTypeArguments = default, +#else + ImmutableArray.Builder? genericTypeArguments = default, +#endif + sbyte rankOrModifier = default, + int nestedNameLength = -1) + { + _fullName = fullName; + AssemblyName = assemblyName; + _rankOrModifier = rankOrModifier; + _elementOrGenericType = elementOrGenericType; + _declaringType = declaringType; + _nestedNameLength = nestedNameLength; + +#if SYSTEM_PRIVATE_CORELIB + _genericArguments = genericTypeArguments; +#else + _genericArguments = genericTypeArguments is null + ? ImmutableArray.Empty + : genericTypeArguments.Count == genericTypeArguments.Capacity ? genericTypeArguments.MoveToImmutable() : genericTypeArguments.ToImmutableArray(); +#endif + } + + /// + /// The assembly-qualified name of the type; e.g., "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". + /// + /// + /// If returns null, simply returns . + /// + public string AssemblyQualifiedName + => _assemblyQualifiedName ??= AssemblyName is null ? FullName : $"{FullName}, {AssemblyName.FullName}"; + + /// + /// Returns assembly name which contains this type, or null if this was not + /// created from a fully-qualified name. + /// + public AssemblyNameInfo? AssemblyName { get; } + + /// + /// If this type is a nested type (see ), gets + /// the declaring type. If this type is not a nested type, throws. + /// + /// + /// For example, given "Namespace.Declaring+Nested", unwraps the outermost type and returns "Namespace.Declaring". + /// + /// The current type is not a nested type. + public TypeName DeclaringType + { + get + { + if (_declaringType is null) + { + TypeNameParserHelpers.ThrowInvalidOperation_NotNestedType(); + } + + return _declaringType; + } + } + + /// + /// The full name of this type, including namespace, but without the assembly name; e.g., "System.Int32". + /// Nested types are represented with a '+'; e.g., "MyNamespace.MyType+NestedType". + /// + /// + /// For constructed generic types, the type arguments will be listed using their fully qualified + /// names. For example, given "List<int>", the property will return + /// "System.Collections.Generic.List`1[[System.Int32, mscorlib, ...]]". + /// For open generic types, the convention is to use a backtick ("`") followed by + /// the arity of the generic type. For example, given "Dictionary<,>", the + /// property will return "System.Collections.Generic.Dictionary`2". Given "Dictionary<,>.Enumerator", + /// the property will return "System.Collections.Generic.Dictionary`2+Enumerator". + /// See ECMA-335, Sec. I.10.7.2 (Type names and arity encoding) for more information. + /// + public string FullName + { + get + { + if (_fullName is null) + { + if (IsConstructedGenericType) + { + _fullName = TypeNameParserHelpers.GetGenericTypeFullName(GetGenericTypeDefinition().FullName.AsSpan(), +#if SYSTEM_PRIVATE_CORELIB + CollectionsMarshal.AsSpan(_genericArguments)); +#else + _genericArguments.AsSpan()); +#endif + } + else if (IsArray || IsPointer || IsByRef) + { + ValueStringBuilder builder = new(stackalloc char[128]); + builder.Append(GetElementType().FullName); + _fullName = TypeNameParserHelpers.GetRankOrModifierStringRepresentation(_rankOrModifier, ref builder); + } + else + { + Debug.Fail("Pre-allocated full name should have been provided in the ctor"); + } + } + else if (_nestedNameLength > 0 && _fullName.Length > _nestedNameLength) // Declaring types + { + // Stored fullName represents the full name of the nested type. + // Example: Namespace.Declaring+Nested + _fullName = _fullName.Substring(0, _nestedNameLength); + } + + return _fullName!; + } + } + + /// + /// Returns true if this type represents any kind of array, regardless of the array's + /// rank or its bounds. + /// + public bool IsArray => _rankOrModifier == TypeNameParserHelpers.SZArray || _rankOrModifier > 0; + + /// + /// Returns true if this type represents a constructed generic type (e.g., "List<int>"). + /// + /// + /// Returns false for open generic types (e.g., "Dictionary<,>"). + /// + public bool IsConstructedGenericType => +#if SYSTEM_PRIVATE_CORELIB + _genericArguments is not null; +#else + _genericArguments.Length > 0; +#endif + + /// + /// Returns true if this is a "plain" type; that is, not an array, not a pointer, not a reference, and + /// not a constructed generic type. Examples of elemental types are "System.Int32", + /// "System.Uri", and "YourNamespace.YourClass". + /// + /// + /// This property returning true doesn't mean that the type is a primitive like string + /// or int; it just means that there's no underlying type. + /// This property will return true for generic type definitions (e.g., "Dictionary<,>"). + /// This is because determining whether a type truly is a generic type requires loading the type + /// and performing a runtime check. + /// + public bool IsSimple => _elementOrGenericType is null; + + /// + /// Returns true if this is a managed pointer type (e.g., "ref int"). + /// Managed pointer types are sometimes called byref types () + /// + public bool IsByRef => _rankOrModifier == TypeNameParserHelpers.ByRef; + + /// + /// Returns true if this is a nested type (e.g., "Namespace.Declaring+Nested"). + /// For nested types returns their declaring type. + /// + public bool IsNested => _declaringType is not null; + + /// + /// Returns true if this type represents a single-dimensional, zero-indexed array (e.g., "int[]"). + /// + public bool IsSZArray => _rankOrModifier == TypeNameParserHelpers.SZArray; + + /// + /// Returns true if this type represents an unmanaged pointer (e.g., "int*" or "void*"). + /// Unmanaged pointer types are often just called pointers () + /// + public bool IsPointer => _rankOrModifier == TypeNameParserHelpers.Pointer; + + /// + /// Returns true if this type represents a variable-bound array; that is, an array of rank greater + /// than 1 (e.g., "int[,]") or a single-dimensional array which isn't necessarily zero-indexed. + /// + public bool IsVariableBoundArrayType => _rankOrModifier >= 1; + + /// + /// The name of this type, without the namespace and the assembly name; e.g., "Int32". + /// Nested types are represented without a '+'; e.g., "MyNamespace.MyType+NestedType" is just "NestedType". + /// + public string Name + { + get + { + if (_name is null) + { + if (IsConstructedGenericType) + { + _name = TypeNameParserHelpers.GetName(GetGenericTypeDefinition().FullName.AsSpan()).ToString(); + } + else if (IsPointer || IsByRef || IsArray) + { + ValueStringBuilder builder = new(stackalloc char[64]); + builder.Append(GetElementType().Name); + _name = TypeNameParserHelpers.GetRankOrModifierStringRepresentation(_rankOrModifier, ref builder); + } + else if (_nestedNameLength > 0 && _fullName is not null) + { + _name = TypeNameParserHelpers.GetName(_fullName.AsSpan(0, _nestedNameLength)).ToString(); + } + else + { + _name = TypeNameParserHelpers.GetName(FullName.AsSpan()).ToString(); + } + } + + return _name; + } + } + + /// + /// Represents the total number of instances that are used to describe + /// this instance, including any generic arguments or underlying types. + /// + /// + /// This value is computed every time this method gets called, it's not cached. + /// There's not really a parallel concept to this in reflection. Think of it + /// as the total number of instances that would be created if + /// you were to totally deconstruct this instance and visit each intermediate + /// that occurs as part of deconstruction. + /// "int" and "Person" each have complexities of 1 because they're standalone types. + /// "int[]" has a node count of 2 because to fully inspect it involves inspecting the + /// array type itself, plus unwrapping the underlying type ("int") and inspecting that. + /// + /// "Dictionary<string, List<int[][]>>" has node count 8 because fully visiting it + /// involves inspecting 8 instances total: + /// + /// Dictionary<string, List<int[][]>> (the original type) + /// Dictionary`2 (the generic type definition) + /// string (a type argument of Dictionary) + /// List<int[][]> (a type argument of Dictionary) + /// List`1 (the generic type definition) + /// int[][] (a type argument of List) + /// int[] (the underlying type of int[][]) + /// int (the underlying type of int[]) + /// + /// + /// + public int GetNodeCount() + { + int result = 1; + + if (IsNested) + { + result += DeclaringType.GetNodeCount(); + } + else if (IsConstructedGenericType) + { + result++; + } + else if (IsArray || IsPointer || IsByRef) + { + result += GetElementType().GetNodeCount(); + } + + foreach (TypeName genericArgument in GetGenericArguments()) + { + result += genericArgument.GetNodeCount(); + } + + return result; + } + + /// + /// The TypeName of the object encompassed or referred to by the current array, pointer, or reference type. + /// + /// + /// For example, given "int[][]", unwraps the outermost array and returns "int[]". + /// + /// The current type is not an array, pointer or reference. + public TypeName GetElementType() + { + if (!(IsArray || IsPointer || IsByRef)) + { + TypeNameParserHelpers.ThrowInvalidOperation_NoElement(); + } + + return _elementOrGenericType!; + } + + /// + /// Returns a TypeName object that represents a generic type name definition from which the current generic type name can be constructed. + /// + /// + /// Given "Dictionary<string, int>", returns the generic type definition "Dictionary<,>". + /// + /// The current type is not a generic type. + public TypeName GetGenericTypeDefinition() + { + if (!IsConstructedGenericType) + { + TypeNameParserHelpers.ThrowInvalidOperation_NotGenericType(); + } + + return _elementOrGenericType!; + } + + /// + /// Parses a span of characters into a type name. + /// + /// A span containing the characters representing the type name to parse. + /// An object that describes optional parameters to use. + /// Parsed type name. + /// Provided type name was invalid. + /// Parsing has exceeded the limit set by . + public static TypeName Parse(ReadOnlySpan typeName, TypeNameParseOptions? options = default) + => TypeNameParser.Parse(typeName, throwOnError: true, options)!; + + /// + /// Tries to parse a span of characters into a type name. + /// + /// A span containing the characters representing the type name to parse. + /// An object that describes optional parameters to use. + /// Contains the result when parsing succeeds. + /// true if type name was converted successfully, otherwise, false. + public static bool TryParse(ReadOnlySpan typeName, [NotNullWhen(true)] out TypeName? result, TypeNameParseOptions? options = default) + { + result = TypeNameParser.Parse(typeName, throwOnError: false, options); + return result is not null; + } + + /// + /// Gets the number of dimensions in an array. + /// + /// An integer that contains the number of dimensions in the current type. + /// The current type is not an array. + public int GetArrayRank() + { + if (!(_rankOrModifier == TypeNameParserHelpers.SZArray || _rankOrModifier > 0)) + { + TypeNameParserHelpers.ThrowInvalidOperation_HasToBeArrayClass(); + } + + return _rankOrModifier == TypeNameParserHelpers.SZArray ? 1 : _rankOrModifier; + } + + /// + /// If this represents a constructed generic type, returns an array + /// of all the generic arguments. Otherwise it returns an empty array. + /// + /// + /// For example, given "Dictionary<string, int>", returns a 2-element array containing + /// string and int. + /// + public +#if SYSTEM_PRIVATE_CORELIB + IReadOnlyList GetGenericArguments() => _genericArguments is null ? Array.Empty() : _genericArguments; +#else + ImmutableArray GetGenericArguments() => _genericArguments; +#endif + } +} diff --git a/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParser.cs b/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParser.cs new file mode 100644 index 00000000000000..dcba442054a5d6 --- /dev/null +++ b/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParser.cs @@ -0,0 +1,261 @@ +// 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.Diagnostics; + +#if !SYSTEM_PRIVATE_CORELIB +using System.Collections.Immutable; +#endif + +using static System.Reflection.Metadata.TypeNameParserHelpers; + +#nullable enable + +namespace System.Reflection.Metadata +{ + [DebuggerDisplay("{_inputString}")] + internal ref struct TypeNameParser + { + private static readonly TypeNameParseOptions s_defaults = new(); + + private readonly bool _throwOnError; + private readonly TypeNameParseOptions _parseOptions; + private ReadOnlySpan _inputString; + + private TypeNameParser(ReadOnlySpan name, bool throwOnError, TypeNameParseOptions? options) : this() + { + _inputString = name; + _throwOnError = throwOnError; + _parseOptions = options ?? s_defaults; + } + + internal static TypeName? Parse(ReadOnlySpan typeName, bool throwOnError, TypeNameParseOptions? options = default) + { + ReadOnlySpan trimmedName = typeName.TrimStart(); // whitespaces at beginning are always OK + if (trimmedName.IsEmpty) + { + if (throwOnError) + { + ThrowArgumentException_InvalidTypeName(errorIndex: 0); // whitespace input needs to report the error index as 0 + } + + return null; + } + + int recursiveDepth = 0; + TypeNameParser parser = new(trimmedName, throwOnError, options); + TypeName? parsedName = parser.ParseNextTypeName(allowFullyQualifiedName: true, ref recursiveDepth); + + if (parsedName is null || !parser._inputString.IsEmpty) // unconsumed input == error + { + if (throwOnError) + { + if (parser._parseOptions.IsMaxDepthExceeded(recursiveDepth)) + { + ThrowInvalidOperation_MaxNodesExceeded(parser._parseOptions.MaxNodes); + } + + int errorIndex = typeName.Length - parser._inputString.Length; + ThrowArgumentException_InvalidTypeName(errorIndex); + } + + return null; + } + + return parsedName; + } + + // this method should return null instead of throwing, so the caller can get errorIndex and include it in error msg + private TypeName? ParseNextTypeName(bool allowFullyQualifiedName, ref int recursiveDepth) + { + if (!TryDive(ref recursiveDepth)) + { + return null; + } + + List? nestedNameLengths = null; + if (!TryGetTypeNameInfo(ref _inputString, ref nestedNameLengths, out int fullTypeNameLength)) + { + return null; + } + + ReadOnlySpan fullTypeName = _inputString.Slice(0, fullTypeNameLength); + _inputString = _inputString.Slice(fullTypeNameLength); + + // Don't allocate now, as it may be an open generic type like "Name`1" +#if SYSTEM_PRIVATE_CORELIB + List? genericArgs = null; +#else + ImmutableArray.Builder? genericArgs = null; +#endif + + // Are there any captured generic args? We'll look for "[[" and "[". + // There are no spaces allowed before the first '[', but spaces are allowed + // after that. The check slices _inputString, so we'll capture it into + // a local so we can restore it later if needed. + ReadOnlySpan capturedBeforeProcessing = _inputString; + if (IsBeginningOfGenericArgs(ref _inputString, out bool doubleBrackets)) + { + ParseAnotherGenericArg: + + // Namespace.Type`2[[GenericArgument1, AssemblyName1],[GenericArgument2, AssemblyName2]] - double square bracket syntax allows for fully qualified type names + // Namespace.Type`2[GenericArgument1,GenericArgument2] - single square bracket syntax is legal only for non-fully qualified type names + // Namespace.Type`2[[GenericArgument1, AssemblyName1], GenericArgument2] - mixed mode + // Namespace.Type`2[GenericArgument1, [GenericArgument2, AssemblyName2]] - mixed mode + TypeName? genericArg = ParseNextTypeName(allowFullyQualifiedName: doubleBrackets, ref recursiveDepth); + if (genericArg is null) // parsing failed + { + return null; + } + + // For [[, there had better be a ']' after the type name. + if (doubleBrackets && !TryStripFirstCharAndTrailingSpaces(ref _inputString, ']')) + { + return null; + } + + if (genericArgs is null) + { +#if SYSTEM_PRIVATE_CORELIB + genericArgs = new List(2); +#else + genericArgs = ImmutableArray.CreateBuilder(2); +#endif + } + genericArgs.Add(genericArg); + + // Is there a ',[' indicating fully qualified generic type arg? + // Is there a ',' indicating non-fully qualified generic type arg? + if (TryStripFirstCharAndTrailingSpaces(ref _inputString, ',')) + { + doubleBrackets = TryStripFirstCharAndTrailingSpaces(ref _inputString, '['); + + goto ParseAnotherGenericArg; + } + + // The only other allowable character is ']', indicating the end of + // the generic type arg list. + if (!TryStripFirstCharAndTrailingSpaces(ref _inputString, ']')) + { + return null; + } + } + + // If there was an error stripping the generic args, back up to + // before we started processing them, and let the decorator + // parser try handling it. + if (genericArgs is null) + { + _inputString = capturedBeforeProcessing; + } + + int previousDecorator = default; + // capture the current state so we can reprocess it again once we know the AssemblyName + capturedBeforeProcessing = _inputString; + // iterate over the decorators to ensure there are no illegal combinations + while (TryParseNextDecorator(ref _inputString, out int parsedDecorator)) + { + if (!TryDive(ref recursiveDepth)) + { + return null; + } + + // Currently it's illegal for managed reference to be followed by any other decorator, + // but this is a runtime-specific behavior and the parser is not enforcing that rule. + previousDecorator = parsedDecorator; + } + + AssemblyNameInfo? assemblyName = null; + if (allowFullyQualifiedName && !TryParseAssemblyName(ref assemblyName)) + { +#if SYSTEM_PRIVATE_CORELIB + // backward compat: throw FileLoadException for non-empty invalid strings + if (_throwOnError || !_inputString.TrimStart().StartsWith(",")) + { + throw new IO.FileLoadException(SR.InvalidAssemblyName, _inputString.ToString()); + } +#else + return null; +#endif + } + + // No matter what was parsed, the full name string is allocated only once. + // In case of generic, nested, array, pointer and byref types the full name is allocated + // when needed for the first time . + string fullName = fullTypeName.ToString(); + + TypeName? declaringType = GetDeclaringType(fullName, nestedNameLengths, assemblyName); + TypeName result = new(fullName, assemblyName, declaringType: declaringType); + if (genericArgs is not null) + { + result = new(fullName: null, assemblyName, elementOrGenericType: result, declaringType, genericArgs); + } + + if (previousDecorator != default) // some decorators were recognized + { + while (TryParseNextDecorator(ref capturedBeforeProcessing, out int parsedModifier)) + { + result = new(fullName: null, assemblyName, elementOrGenericType: result, rankOrModifier: (sbyte)parsedModifier); + } + } + + return result; + } + + /// false means the input was invalid and parsing has failed. Empty input is valid and returns true. + private bool TryParseAssemblyName(ref AssemblyNameInfo? assemblyName) + { + ReadOnlySpan capturedBeforeProcessing = _inputString; + if (TryStripFirstCharAndTrailingSpaces(ref _inputString, ',')) + { + if (_inputString.IsEmpty) + { + _inputString = capturedBeforeProcessing; // restore the state + return false; + } + + ReadOnlySpan candidate = GetAssemblyNameCandidate(_inputString); + if (!AssemblyNameInfo.TryParse(candidate, out assemblyName)) + { + return false; + } + + _inputString = _inputString.Slice(candidate.Length); + return true; + } + + return true; + } + + private static TypeName? GetDeclaringType(string fullTypeName, List? nestedNameLengths, AssemblyNameInfo? assemblyName) + { + if (nestedNameLengths is null) + { + return null; + } + + TypeName? declaringType = null; + int nameOffset = 0; + foreach (int nestedNameLength in nestedNameLengths) + { + Debug.Assert(nestedNameLength > 0, "TryGetTypeNameInfo should return error on zero lengths"); + int fullNameLength = nameOffset + nestedNameLength; + declaringType = new(fullTypeName, assemblyName, declaringType: declaringType, nestedNameLength: fullNameLength); + nameOffset += nestedNameLength + 1; // include the '+' that was skipped in name + } + + return declaringType; + } + + private bool TryDive(ref int depth) + { + if (_parseOptions.IsMaxDepthExceeded(depth)) + { + return false; + } + depth++; + return true; + } + } +} diff --git a/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParserHelpers.cs b/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParserHelpers.cs new file mode 100644 index 00000000000000..1cdc5e230ad96a --- /dev/null +++ b/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParserHelpers.cs @@ -0,0 +1,394 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text; + +#nullable enable + +namespace System.Reflection.Metadata +{ + internal static class TypeNameParserHelpers + { + internal const sbyte SZArray = -1; + internal const sbyte Pointer = -2; + internal const sbyte ByRef = -3; + private const char EscapeCharacter = '\\'; +#if NET8_0_OR_GREATER + private static readonly SearchValues s_endOfFullTypeNameDelimitersSearchValues = SearchValues.Create("[]&*,+\\"); +#endif + + internal static string GetGenericTypeFullName(ReadOnlySpan fullTypeName, ReadOnlySpan genericArgs) + { + Debug.Assert(genericArgs.Length > 0); + + ValueStringBuilder result = new(stackalloc char[128]); + result.Append(fullTypeName); + + result.Append('['); + foreach (TypeName genericArg in genericArgs) + { + result.Append('['); + result.Append(genericArg.AssemblyQualifiedName); + result.Append(']'); + result.Append(','); + } + result[result.Length - 1] = ']'; // replace ',' with ']' + + return result.ToString(); + } + + /// Positive length or negative value for invalid name + internal static int GetFullTypeNameLength(ReadOnlySpan input, out bool isNestedType) + { + isNestedType = false; + + // NET 6+ guarantees that MemoryExtensions.IndexOfAny has worst-case complexity + // O(m * i) if a match is found, or O(m * n) if a match is not found, where: + // i := index of match position + // m := number of needles + // n := length of search space (haystack) + // + // Downlevel versions of .NET do not make this guarantee, instead having a + // worst-case complexity of O(m * n) even if a match occurs at the beginning of + // the search space. Since we're running this in a loop over untrusted user + // input, that makes the total loop complexity potentially O(m * n^2), where + // 'n' is adversary-controlled. To avoid DoS issues here, we'll loop manually. + +#if NET8_0_OR_GREATER + int offset = input.IndexOfAny(s_endOfFullTypeNameDelimitersSearchValues); + if (offset < 0) + { + return input.Length; // no type name end chars were found, the whole input is the type name + } + + if (input[offset] == EscapeCharacter) // this is very rare (IL Emit or pure IL) + { + offset = GetUnescapedOffset(input, startOffset: offset); // this is slower, but very rare so acceptable + } +#else + int offset = GetUnescapedOffset(input, startOffset: 0); +#endif + isNestedType = offset > 0 && offset < input.Length && input[offset] == '+'; + return offset; + + static int GetUnescapedOffset(ReadOnlySpan input, int startOffset) + { + int offset = startOffset; + for (; offset < input.Length; offset++) + { + char c = input[offset]; + if (c == EscapeCharacter) + { + offset++; // skip the escaped char + + if (offset == input.Length || // invalid name that ends with escape character + !NeedsEscaping(input[offset])) // invalid name, escapes a char that does not need escaping + { + return -1; + } + } + else if (NeedsEscaping(c)) + { + break; + } + } + return offset; + } + + static bool NeedsEscaping(char c) => c is '[' or ']' or '&' or '*' or ',' or '+' or EscapeCharacter; + } + + internal static ReadOnlySpan GetName(ReadOnlySpan fullName) + { + int offset = fullName.LastIndexOfAny('.', '+'); + + if (offset > 0 && fullName[offset - 1] == EscapeCharacter) // this should be very rare (IL Emit & pure IL) + { + offset = GetUnescapedOffset(fullName, startIndex: offset); + } + + return offset < 0 ? fullName : fullName.Slice(offset + 1); + + static int GetUnescapedOffset(ReadOnlySpan fullName, int startIndex) + { + int offset = startIndex; + for (; offset >= 0; offset--) + { + if (fullName[offset] is '.' or '+') + { + if (offset == 0 || fullName[offset - 1] != EscapeCharacter) + { + break; + } + offset--; // skip the escaping character + } + } + return offset; + } + } + + // this method handles escaping of the ] just to let the AssemblyNameParser fail for the right input + internal static ReadOnlySpan GetAssemblyNameCandidate(ReadOnlySpan input) + { + // The only delimiter which can terminate an assembly name is ']'. + // Otherwise EOL serves as the terminator. + int offset = input.IndexOf(']'); + + if (offset > 0 && input[offset - 1] == EscapeCharacter) // this should be very rare (IL Emit & pure IL) + { + offset = GetUnescapedOffset(input, startIndex: offset); + } + + return offset < 0 ? input : input.Slice(0, offset); + + static int GetUnescapedOffset(ReadOnlySpan input, int startIndex) + { + int offset = startIndex; + for (; offset < input.Length; offset++) + { + if (input[offset] is ']') + { + if (input[offset - 1] != EscapeCharacter) + { + break; + } + } + } + return offset; + } + } + + internal static string GetRankOrModifierStringRepresentation(int rankOrModifier, ref ValueStringBuilder builder) + { + if (rankOrModifier == ByRef) + { + builder.Append('&'); + } + else if (rankOrModifier == Pointer) + { + builder.Append('*'); + } + else if (rankOrModifier == SZArray) + { + builder.Append("[]"); + } + else if (rankOrModifier == 1) + { + builder.Append("[*]"); + } + else + { + Debug.Assert(rankOrModifier >= 2); + + builder.Append('['); + builder.Append(',', rankOrModifier - 1); + builder.Append(']'); + } + + return builder.ToString(); + } + + /// + /// Are there any captured generic args? We'll look for "[[" and "[" that is not followed by "]", "*" and ",". + /// + internal static bool IsBeginningOfGenericArgs(ref ReadOnlySpan span, out bool doubleBrackets) + { + doubleBrackets = false; + + if (!span.IsEmpty && span[0] == '[') + { + // There are no spaces allowed before the first '[', but spaces are allowed after that. + ReadOnlySpan trimmed = span.Slice(1).TrimStart(); + if (!trimmed.IsEmpty) + { + if (trimmed[0] == '[') + { + doubleBrackets = true; + span = trimmed.Slice(1).TrimStart(); + return true; + } + if (!(trimmed[0] is ',' or '*' or ']')) // [] or [*] or [,] or [,,,, ...] + { + span = trimmed; + return true; + } + } + } + + return false; + } + + internal static bool TryGetTypeNameInfo(ref ReadOnlySpan input, ref List? nestedNameLengths, out int totalLength) + { + bool isNestedType; + totalLength = 0; + do + { + int length = GetFullTypeNameLength(input.Slice(totalLength), out isNestedType); + if (length <= 0) + { + // invalid type names: + // -1: invalid escaping + // 0: pair of unescaped "++" characters + return false; + } + +#if SYSTEM_PRIVATE_CORELIB + // Compat: Ignore leading '.' for type names without namespace. .NET Framework historically ignored leading '.' here. It is likely + // that code out there depends on this behavior. For example, type names formed by concatenating namespace and name, without checking for + // empty namespace (bug), are going to have superfluous leading '.'. + // This behavior means that types that start with '.' are not round-trippable via type name. + if (length > 1 && input[0] == '.' && input.Slice(0, length).LastIndexOf('.') == 0) + { + input = input.Slice(1); + length--; + } +#endif + if (isNestedType) + { + (nestedNameLengths ??= new()).Add(length); + totalLength += 1; // skip the '+' sign in next search + } + totalLength += length; + } while (isNestedType); + + return true; + } + + internal static bool TryParseNextDecorator(ref ReadOnlySpan input, out int rankOrModifier) + { + // Then try pulling a single decorator. + // Whitespace cannot precede the decorator, but it can follow the decorator. + + ReadOnlySpan originalInput = input; // so we can restore on 'false' return + + if (TryStripFirstCharAndTrailingSpaces(ref input, '*')) + { + rankOrModifier = Pointer; + return true; + } + + if (TryStripFirstCharAndTrailingSpaces(ref input, '&')) + { + rankOrModifier = ByRef; + return true; + } + + if (TryStripFirstCharAndTrailingSpaces(ref input, '[')) + { + // SZArray := [] + // MDArray := [*] or [,] or [,,,, ...] + + int rank = 1; + bool hasSeenAsterisk = false; + + ReadNextArrayToken: + + if (TryStripFirstCharAndTrailingSpaces(ref input, ']')) + { + // End of array marker + rankOrModifier = rank == 1 && !hasSeenAsterisk ? SZArray : rank; + return true; + } + + if (!hasSeenAsterisk) + { + if (rank == 1 && TryStripFirstCharAndTrailingSpaces(ref input, '*')) + { + // [*] + hasSeenAsterisk = true; + goto ReadNextArrayToken; + } + else if (TryStripFirstCharAndTrailingSpaces(ref input, ',')) + { + // [,,, ...] + checked { rank++; } + goto ReadNextArrayToken; + } + } + + // Don't know what this token is. + // Fall through to 'return false' statement. + } + + input = originalInput; // ensure 'ref input' not mutated + rankOrModifier = 0; + return false; + } + + internal static bool TryStripFirstCharAndTrailingSpaces(ref ReadOnlySpan span, char value) + { + if (!span.IsEmpty && span[0] == value) + { + span = span.Slice(1).TrimStart(); + return true; + } + return false; + } + + [DoesNotReturn] + internal static void ThrowArgumentException_InvalidTypeName(int errorIndex) + { + throw new ArgumentException(SR.Argument_InvalidTypeName, $"typeName@{errorIndex}"); + } + + [DoesNotReturn] + internal static void ThrowInvalidOperation_MaxNodesExceeded(int limit) + { +#if SYSTEM_REFLECTION_METADATA + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_MaxNodesExceeded, limit)); +#else + Debug.Fail("Expected to be unreachable"); + throw new InvalidOperationException(); +#endif + } + + [DoesNotReturn] + internal static void ThrowInvalidOperation_NotGenericType() + { +#if SYSTEM_REFLECTION_METADATA + throw new InvalidOperationException(SR.InvalidOperation_NotGenericType); +#else + Debug.Fail("Expected to be unreachable"); + throw new InvalidOperationException(); +#endif + } + + [DoesNotReturn] + internal static void ThrowInvalidOperation_NotNestedType() + { +#if SYSTEM_REFLECTION_METADATA + throw new InvalidOperationException(SR.InvalidOperation_NotNestedType); +#else + Debug.Fail("Expected to be unreachable"); + throw new InvalidOperationException(); +#endif + } + + [DoesNotReturn] + internal static void ThrowInvalidOperation_NoElement() + { +#if SYSTEM_REFLECTION_METADATA + throw new InvalidOperationException(SR.InvalidOperation_NoElement); +#else + Debug.Fail("Expected to be unreachable"); + throw new InvalidOperationException(); +#endif + } + + [DoesNotReturn] + internal static void ThrowInvalidOperation_HasToBeArrayClass() + { +#if SYSTEM_REFLECTION_METADATA + throw new InvalidOperationException(SR.Argument_HasToBeArrayClass); +#else + Debug.Fail("Expected to be unreachable"); + throw new InvalidOperationException(); +#endif + } + } +} diff --git a/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParserOptions.cs b/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParserOptions.cs new file mode 100644 index 00000000000000..551876e73147c9 --- /dev/null +++ b/src/libraries/Common/src/System/Reflection/Metadata/TypeNameParserOptions.cs @@ -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. + +namespace System.Reflection.Metadata +{ + public sealed class TypeNameParseOptions + { + private int _maxNodes = 20; + + /// + /// Limits the maximum value of node count that parser can handle. + /// + public int MaxNodes + { + get => _maxNodes; + set + { +#if NET8_0_OR_GREATER + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(value, 0, nameof(value)); +#else + if (value <= 0) + { + throw new ArgumentOutOfRangeException(paramName: nameof(value)); + } +#endif + + _maxNodes = value; + } + } + + internal bool IsMaxDepthExceeded(int depth) => depth >= _maxNodes; + } +} diff --git a/src/libraries/Common/src/System/Reflection/TypeNameParser.Helpers.cs b/src/libraries/Common/src/System/Reflection/TypeNameParser.Helpers.cs new file mode 100644 index 00000000000000..84ef2137fb095b --- /dev/null +++ b/src/libraries/Common/src/System/Reflection/TypeNameParser.Helpers.cs @@ -0,0 +1,214 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Reflection.Metadata; +using System.Text; + +#nullable enable + +#if SYSTEM_PRIVATE_CORELIB +namespace System.Reflection.Metadata +{ + internal struct TypeNameParseOptions + { + public TypeNameParseOptions() { } +#pragma warning disable CA1822 // Mark members as static + // CoreLib does not enforce any limits + public bool IsMaxDepthExceeded(int _) => false; + public int MaxNodes + { + get + { + Debug.Fail("Expected to be unreachable"); + return 0; + } + } +#pragma warning restore CA1822 + } +} +#endif + +namespace System.Reflection +{ + internal partial struct TypeNameParser + { +#if !MONO // Mono never needs unescaped names + private const char EscapeCharacter = '\\'; + + /// + /// Removes escape characters from the string (if there were any found). + /// + private static string UnescapeTypeName(string name) + { + int indexOfEscapeCharacter = name.IndexOf(EscapeCharacter); + if (indexOfEscapeCharacter < 0) + { + return name; + } + + return Unescape(name, indexOfEscapeCharacter); + + static string Unescape(string name, int indexOfEscapeCharacter) + { + // this code path is executed very rarely (IL Emit or pure IL with chars not allowed in C# or F#) + var sb = new ValueStringBuilder(stackalloc char[64]); + sb.EnsureCapacity(name.Length); + sb.Append(name.AsSpan(0, indexOfEscapeCharacter)); + + for (int i = indexOfEscapeCharacter; i < name.Length;) + { + char c = name[i++]; + + if (c != EscapeCharacter) + { + sb.Append(c); + } + else if (i < name.Length && name[i] == EscapeCharacter) // escaped escape character ;) + { + sb.Append(c); + // Consume the escaped escape character, it's important for edge cases + // like escaped escape character followed by another escaped char (example: "\\\\\\+") + i++; + } + } + + return sb.ToString(); + } + } +#endif + + private static (string typeNamespace, string name) SplitFullTypeName(string typeName) + { + string typeNamespace, name; + + // Matches algorithm from ns::FindSep in src\coreclr\utilcode\namespaceutil.cpp + // This could result in the type name beginning with a '.' character. + int separator = typeName.LastIndexOf('.'); + if (separator <= 0) + { + typeNamespace = ""; + name = typeName; + } + else + { + if (typeName[separator - 1] == '.') + separator--; + typeNamespace = typeName.Substring(0, separator); + name = typeName.Substring(separator + 1); + } + + return (typeNamespace, name); + } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050:RequiresDynamicCode", + Justification = "Used to implement resolving types from strings.")] + private Type? Resolve(TypeName typeName) + { + if (typeName.IsNested) + { + TypeName? current = typeName; + int nestingDepth = 0; + while (current is not null && current.IsNested) + { + nestingDepth++; + current = current.DeclaringType; + } + + // We're performing real type resolution, it is assumed that the caller has already validated the correctness + // of this TypeName object against their own policies, so there is no need for this method to perform any further checks. + string[] nestedTypeNames = new string[nestingDepth]; + current = typeName; + while (current is not null && current.IsNested) + { +#if MONO + nestedTypeNames[--nestingDepth] = current.Name; +#else // CLR, NativeAOT and tools require unescaped nested type names + nestedTypeNames[--nestingDepth] = UnescapeTypeName(current.Name); +#endif + current = current.DeclaringType; + } +#if SYSTEM_PRIVATE_CORELIB + string nonNestedParentName = current!.FullName; +#else // the tools require unescaped names + string nonNestedParentName = UnescapeTypeName(current!.FullName); +#endif + Type? type = GetType(nonNestedParentName, nestedTypeNames, typeName); + return type is null || !typeName.IsConstructedGenericType ? type : MakeGenericType(type, typeName); + } + else if (typeName.IsConstructedGenericType) + { + Type? type = Resolve(typeName.GetGenericTypeDefinition()); + return type is null ? null : MakeGenericType(type, typeName); + } + else if (typeName.IsArray || typeName.IsPointer || typeName.IsByRef) + { + Type? type = Resolve(typeName.GetElementType()); + if (type is null) + { + return null; + } + + if (typeName.IsByRef) + { + return type.MakeByRefType(); + } + else if (typeName.IsPointer) + { + return type.MakePointerType(); + } + else if (typeName.IsSZArray) + { + return type.MakeArrayType(); + } + else + { + Debug.Assert(typeName.IsVariableBoundArrayType); + + return type.MakeArrayType(rank: typeName.GetArrayRank()); + } + } + else + { + Debug.Assert(typeName.IsSimple); + + Type? type = GetType( +#if SYSTEM_PRIVATE_CORELIB + typeName.FullName, +#else // the tools require unescaped names + UnescapeTypeName(typeName.FullName), +#endif + nestedTypeNames: ReadOnlySpan.Empty, typeName); + + return type; + } + } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", + Justification = "Used to implement resolving types from strings.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050:RequiresDynamicCode", + Justification = "Used to implement resolving types from strings.")] + private Type? MakeGenericType(Type type, TypeName typeName) + { + var genericArgs = typeName.GetGenericArguments(); +#if SYSTEM_PRIVATE_CORELIB + int size = genericArgs.Count; +#else + int size = genericArgs.Length; +#endif + Type[] genericTypes = new Type[size]; + for (int i = 0; i < size; i++) + { + Type? genericArg = Resolve(genericArgs[i]); + if (genericArg is null) + { + return null; + } + genericTypes[i] = genericArg; + } + + return type.MakeGenericType(genericTypes); + } + } +} diff --git a/src/libraries/Common/src/System/Reflection/TypeNameParser.cs b/src/libraries/Common/src/System/Reflection/TypeNameParser.cs deleted file mode 100644 index 0b69e4e18aaae4..00000000000000 --- a/src/libraries/Common/src/System/Reflection/TypeNameParser.cs +++ /dev/null @@ -1,701 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using System.Text; - -#nullable enable - -namespace System.Reflection -{ - // - // Parser for type names passed to GetType() apis. - // - [StructLayout(LayoutKind.Auto)] - internal ref partial struct TypeNameParser - { - private ReadOnlySpan _input; - private int _index; - private int _errorIndex; // Position for error reporting - - private TypeNameParser(ReadOnlySpan name) - { - _input = name; - _errorIndex = _index = 0; - } - - // - // Parses a type name. The type name may be optionally postpended with a "," followed by a legal assembly name. - // - private Type? Parse() - { - TypeName? typeName = ParseNonQualifiedTypeName(); - if (typeName is null) - return null; - - string? assemblyName = null; - - TokenType token = GetNextToken(); - if (token != TokenType.End) - { - if (token != TokenType.Comma) - { - ParseError(); - return null; - } - - if (!CheckTopLevelAssemblyQualifiedName()) - return null; - - assemblyName = GetNextAssemblyName(); - if (assemblyName is null) - return null; - Debug.Assert(Peek == TokenType.End); - } - - return typeName.ResolveType(ref this, assemblyName); - } - - // - // Parses a type name without any assembly name qualification. - // - private TypeName? ParseNonQualifiedTypeName() - { - // Parse the named type or constructed generic type part first. - TypeName? typeName = ParseNamedOrConstructedGenericTypeName(); - if (typeName is null) - return null; - - // Iterate through any "has-element" qualifiers ([], &, *). - while (true) - { - TokenType token = Peek; - if (token == TokenType.End) - break; - if (token == TokenType.Asterisk) - { - Skip(); - typeName = new ModifierTypeName(typeName, ModifierTypeName.Pointer); - } - else if (token == TokenType.Ampersand) - { - Skip(); - typeName = new ModifierTypeName(typeName, ModifierTypeName.ByRef); - } - else if (token == TokenType.OpenSqBracket) - { - Skip(); - token = GetNextToken(); - if (token == TokenType.Asterisk) - { - typeName = new ModifierTypeName(typeName, 1); - token = GetNextToken(); - } - else - { - int rank = 1; - while (token == TokenType.Comma) - { - token = GetNextToken(); - rank++; - } - if (rank == 1) - typeName = new ModifierTypeName(typeName, ModifierTypeName.Array); - else - typeName = new ModifierTypeName(typeName, rank); - } - if (token != TokenType.CloseSqBracket) - { - ParseError(); - return null; - } - } - else - { - break; - } - } - return typeName; - } - - // - // Foo or Foo+Inner or Foo[String] or Foo+Inner[String] - // - private TypeName? ParseNamedOrConstructedGenericTypeName() - { - TypeName? namedType = ParseNamedTypeName(); - if (namedType is null) - return null; - - // Because "[" is used both for generic arguments and array indexes, we must peek two characters deep. - if (!(Peek is TokenType.OpenSqBracket && (PeekSecond is TokenType.Other or TokenType.OpenSqBracket))) - return namedType; - - Skip(); - - TypeName[] typeArguments = new TypeName[2]; - int typeArgumentsCount = 0; - while (true) - { - TypeName? typeArgument = ParseGenericTypeArgument(); - if (typeArgument is null) - return null; - if (typeArgumentsCount >= typeArguments.Length) - Array.Resize(ref typeArguments, 2 * typeArgumentsCount); - typeArguments[typeArgumentsCount++] = typeArgument; - TokenType token = GetNextToken(); - if (token == TokenType.CloseSqBracket) - break; - if (token != TokenType.Comma) - { - ParseError(); - return null; - } - } - - return new GenericTypeName(namedType, typeArguments, typeArgumentsCount); - } - - // - // Foo or Foo+Inner - // - private TypeName? ParseNamedTypeName() - { - string? fullName = GetNextIdentifier(); - if (fullName is null) - return null; - - fullName = ApplyLeadingDotCompatQuirk(fullName); - - if (Peek == TokenType.Plus) - { - string[] nestedNames = new string[1]; - int nestedNamesCount = 0; - - do - { - Skip(); - - string? nestedName = GetNextIdentifier(); - if (nestedName is null) - return null; - - nestedName = ApplyLeadingDotCompatQuirk(nestedName); - - if (nestedNamesCount >= nestedNames.Length) - Array.Resize(ref nestedNames, 2 * nestedNamesCount); - nestedNames[nestedNamesCount++] = nestedName; - } - while (Peek == TokenType.Plus); - - return new NestedNamespaceTypeName(fullName, nestedNames, nestedNamesCount); - } - else - { - return new NamespaceTypeName(fullName); - } - - // Compat: Ignore leading '.' for type names without namespace. .NET Framework historically ignored leading '.' here. It is likely - // that code out there depends on this behavior. For example, type names formed by concatenating namespace and name, without checking for - // empty namespace (bug), are going to have superfluous leading '.'. - // This behavior means that types that start with '.' are not round-trippable via type name. - static string ApplyLeadingDotCompatQuirk(string typeName) - { -#if NETCOREAPP - return (typeName.StartsWith('.') && !typeName.AsSpan(1).Contains('.')) ? typeName.Substring(1) : typeName; -#else - return ((typeName.Length > 0) && (typeName[0] == '.') && typeName.LastIndexOf('.') == 0) ? typeName.Substring(1) : typeName; -#endif - } - } - - // - // Parse a generic argument. In particular, generic arguments can take the special form [,]. - // - private TypeName? ParseGenericTypeArgument() - { - TokenType token = GetNextToken(); - if (token == TokenType.Other) - { - return ParseNonQualifiedTypeName(); - } - if (token != TokenType.OpenSqBracket) - { - ParseError(); - return null; - } - string? assemblyName = null; - TypeName? typeName = ParseNonQualifiedTypeName(); - if (typeName is null) - return null; - - token = GetNextToken(); - if (token == TokenType.Comma) - { - assemblyName = GetNextEmbeddedAssemblyName(); - token = GetNextToken(); - } - if (token != TokenType.CloseSqBracket) - { - ParseError(); - return null; - } - - return (assemblyName != null) ? new AssemblyQualifiedTypeName(typeName, assemblyName) : typeName; - } - - // - // String tokenizer for type names passed to the GetType() APIs. - // - - private TokenType Peek - { - get - { - SkipWhiteSpace(); - char c = (_index < _input.Length) ? _input[_index] : '\0'; - return CharToToken(c); - } - } - - private TokenType PeekSecond - { - get - { - SkipWhiteSpace(); - int index = _index + 1; - while (index < _input.Length && char.IsWhiteSpace(_input[index])) - index++; - char c = (index < _input.Length) ? _input[index] : '\0'; - return CharToToken(c); - } - } - - private void Skip() - { - SkipWhiteSpace(); - if (_index < _input.Length) - _index++; - } - - // Return the next token and skip index past it unless already at end of string - // or the token is not a reserved token. - private TokenType GetNextToken() - { - _errorIndex = _index; - - TokenType tokenType = Peek; - if (tokenType == TokenType.End || tokenType == TokenType.Other) - return tokenType; - Skip(); - return tokenType; - } - - // - // Lex the next segment as part of a type name. (Do not use for assembly names.) - // - // Note that unescaped "."'s do NOT terminate the identifier, but unescaped "+"'s do. - // - // Terminated by the first non-escaped reserved character ('[', ']', '+', '&', '*' or ',') - // - private string? GetNextIdentifier() - { - SkipWhiteSpace(); - - ValueStringBuilder sb = new ValueStringBuilder(stackalloc char[64]); - - int src = _index; - while (true) - { - if (src >= _input.Length) - break; - char c = _input[src]; - TokenType token = CharToToken(c); - if (token != TokenType.Other) - break; - src++; - if (c == '\\') // Check for escaped character - { - // Update error location - _errorIndex = src - 1; - - c = (src < _input.Length) ? _input[src++] : '\0'; - - if (!NeedsEscapingInTypeName(c)) - { - // If we got here, a backslash was used to escape a character that is not legal to escape inside a type name. - ParseError(); - return null; - } - } - sb.Append(c); - } - _index = src; - - if (sb.Length == 0) - { - // The identifier has to be non-empty - _errorIndex = src; - ParseError(); - return null; - } - - return sb.ToString(); - } - - // - // Lex the next segment as the assembly name at the end of an assembly-qualified type name. (Do not use for - // assembly names embedded inside generic type arguments.) - // - private string? GetNextAssemblyName() - { - if (!StartAssemblyName()) - return null; - - string assemblyName = _input.Slice(_index).ToString(); - _index = _input.Length; - return assemblyName; - } - - // - // Lex the next segment as an assembly name embedded inside a generic argument type. - // - // Terminated by an unescaped ']'. - // - private string? GetNextEmbeddedAssemblyName() - { - if (!StartAssemblyName()) - return null; - - ValueStringBuilder sb = new ValueStringBuilder(stackalloc char[64]); - - int src = _index; - while (true) - { - if (src >= _input.Length) - { - ParseError(); - return null; - } - char c = _input[src]; - if (c == ']') - break; - src++; - - // Backslash can be used to escape a ']' - any other backslash character is left alone (along with the backslash) - // for the AssemblyName parser to handle. - if (c == '\\' && (src < _input.Length) && _input[src] == ']') - { - c = _input[src++]; - } - sb.Append(c); - } - _index = src; - - if (sb.Length == 0) - { - // The assembly name has to be non-empty - _errorIndex = src; - ParseError(); - return null; - } - - return sb.ToString(); - } - - private bool StartAssemblyName() - { - // Compat: Treat invalid starting token of assembly name as type name parsing error instead of assembly name parsing error. This only affects - // exception returned by the parser. - if (Peek is TokenType.End or TokenType.Comma) - { - ParseError(); - return false; - } - return true; - } - - // - // Classify a character as a TokenType. (Fortunately, all tokens in type name strings other than identifiers are single-character tokens.) - // - private static TokenType CharToToken(char c) - { - return c switch - { - '\0' => TokenType.End, - '[' => TokenType.OpenSqBracket, - ']' => TokenType.CloseSqBracket, - ',' => TokenType.Comma, - '+' => TokenType.Plus, - '*' => TokenType.Asterisk, - '&' => TokenType.Ampersand, - _ => TokenType.Other, - }; - } - - // - // The type name parser has a strange attitude towards whitespace. It throws away whitespace between punctuation tokens and whitespace - // preceding identifiers or assembly names (and this cannot be escaped away). But whitespace between the end of an identifier - // and the punctuation that ends it is *not* ignored. - // - // In other words, GetType(" Foo") searches for "Foo" but GetType("Foo ") searches for "Foo ". - // - // Whitespace between the end of an assembly name and the punction mark that ends it is also not ignored by this parser, - // but this is irrelevant since the assembly name is then turned over to AssemblyName for parsing, which *does* ignore trailing whitespace. - // - private void SkipWhiteSpace() - { - while (_index < _input.Length && char.IsWhiteSpace(_input[_index])) - _index++; - } - - private enum TokenType - { - End = 0, //At end of string - OpenSqBracket = 1, //'[' - CloseSqBracket = 2, //']' - Comma = 3, //',' - Plus = 4, //'+' - Asterisk = 5, //'*' - Ampersand = 6, //'&' - Other = 7, //Type identifier, AssemblyName or embedded AssemblyName. - } - - // - // The TypeName class is the base class for a family of types that represent the nodes in a parse tree for - // assembly-qualified type names. - // - private abstract class TypeName - { - /// - /// Helper for the Type.GetType() family of APIs. "containingAssemblyIsAny" is the assembly to search for (as determined - /// by a qualifying assembly string in the original type string passed to Type.GetType(). If null, it means the type stream - /// didn't specify an assembly name. How to respond to that is up to the type resolver delegate in getTypeOptions - this class - /// is just a middleman. - /// - public abstract Type? ResolveType(ref TypeNameParser parser, string? containingAssemblyIfAny); - } - - // - // Represents a parse of a type name qualified by an assembly name. - // - private sealed class AssemblyQualifiedTypeName : TypeName - { - private readonly string _assemblyName; - private readonly TypeName _nonQualifiedTypeName; - - public AssemblyQualifiedTypeName(TypeName nonQualifiedTypeName, string assemblyName) - { - _nonQualifiedTypeName = nonQualifiedTypeName; - _assemblyName = assemblyName; - } - - public override Type? ResolveType(ref TypeNameParser parser, string? containingAssemblyIfAny) - { - return _nonQualifiedTypeName.ResolveType(ref parser, _assemblyName); - } - } - - // - // Non-nested named type. The full name is the namespace-qualified name. For example, the FullName for - // System.Collections.Generic.IList<> is "System.Collections.Generic.IList`1". - // - private sealed partial class NamespaceTypeName : TypeName - { - private readonly string _fullName; - public NamespaceTypeName(string fullName) - { - _fullName = fullName; - } - - public override Type? ResolveType(ref TypeNameParser parser, string? containingAssemblyIfAny) - { - return parser.GetType(_fullName, default, containingAssemblyIfAny); - } - } - - // - // Nested type name. - // - private sealed partial class NestedNamespaceTypeName : TypeName - { - private readonly string _fullName; - private readonly string[] _nestedNames; - private readonly int _nestedNamesCount; - - public NestedNamespaceTypeName(string fullName, string[] nestedNames, int nestedNamesCount) - { - _fullName = fullName; - _nestedNames = nestedNames; - _nestedNamesCount = nestedNamesCount; - } - - public override Type? ResolveType(ref TypeNameParser parser, string? containingAssemblyIfAny) - { - return parser.GetType(_fullName, _nestedNames.AsSpan(0, _nestedNamesCount), containingAssemblyIfAny); - } - } - - // - // Array, byref or pointer type name. - // - private sealed class ModifierTypeName : TypeName - { - private readonly TypeName _elementTypeName; - - // Positive value is multi-dimensional array rank. - // Negative value is modifier encoded using constants below. - private readonly int _rankOrModifier; - - public const int Array = -1; - public const int Pointer = -2; - public const int ByRef = -3; - - public ModifierTypeName(TypeName elementTypeName, int rankOrModifier) - { - _elementTypeName = elementTypeName; - _rankOrModifier = rankOrModifier; - } - -#if NETCOREAPP - [UnconditionalSuppressMessage("AotAnalysis", "IL3050:AotUnfriendlyApi", - Justification = "Used to implement resolving types from strings.")] -#endif - public override Type? ResolveType(ref TypeNameParser parser, string? containingAssemblyIfAny) - { - Type? elementType = _elementTypeName.ResolveType(ref parser, containingAssemblyIfAny); - if (elementType is null) - return null; - - return _rankOrModifier switch - { - Array => elementType.MakeArrayType(), - Pointer => elementType.MakePointerType(), - ByRef => elementType.MakeByRefType(), - _ => elementType.MakeArrayType(_rankOrModifier) - }; - } - } - - // - // Constructed generic type name. - // - private sealed class GenericTypeName : TypeName - { - private readonly TypeName _typeDefinition; - private readonly TypeName[] _typeArguments; - private readonly int _typeArgumentsCount; - - public GenericTypeName(TypeName genericTypeDefinition, TypeName[] typeArguments, int typeArgumentsCount) - { - _typeDefinition = genericTypeDefinition; - _typeArguments = typeArguments; - _typeArgumentsCount = typeArgumentsCount; - } - -#if NETCOREAPP - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", - Justification = "Used to implement resolving types from strings.")] - [UnconditionalSuppressMessage("AotAnalysis", "IL3050:AotUnfriendlyApi", - Justification = "Used to implement resolving types from strings.")] -#endif - public override Type? ResolveType(ref TypeNameParser parser, string? containingAssemblyIfAny) - { - Type? typeDefinition = _typeDefinition.ResolveType(ref parser, containingAssemblyIfAny); - if (typeDefinition is null) - return null; - - Type[] arguments = new Type[_typeArgumentsCount]; - for (int i = 0; i < arguments.Length; i++) - { - Type? typeArgument = _typeArguments[i].ResolveType(ref parser, null); - if (typeArgument is null) - return null; - arguments[i] = typeArgument; - } - - return typeDefinition.MakeGenericType(arguments); - } - } - - // - // Type name escaping helpers - // - -#if NETCOREAPP - private static ReadOnlySpan CharsToEscape => "\\[]+*&,"; - - private static bool NeedsEscapingInTypeName(char c) - => CharsToEscape.Contains(c); -#else - private static char[] CharsToEscape { get; } = "\\[]+*&,".ToCharArray(); - - private static bool NeedsEscapingInTypeName(char c) - => Array.IndexOf(CharsToEscape, c) >= 0; -#endif - - private static string EscapeTypeName(string name) - { - if (name.AsSpan().IndexOfAny(CharsToEscape) < 0) - return name; - - var sb = new ValueStringBuilder(stackalloc char[64]); - foreach (char c in name) - { - if (NeedsEscapingInTypeName(c)) - sb.Append('\\'); - sb.Append(c); - } - - return sb.ToString(); - } - - private static string EscapeTypeName(string typeName, ReadOnlySpan nestedTypeNames) - { - string fullName = EscapeTypeName(typeName); - if (nestedTypeNames.Length > 0) - { - var sb = new StringBuilder(fullName); - for (int i = 0; i < nestedTypeNames.Length; i++) - { - sb.Append('+'); - sb.Append(EscapeTypeName(nestedTypeNames[i])); - } - fullName = sb.ToString(); - } - return fullName; - } - - private static (string typeNamespace, string name) SplitFullTypeName(string typeName) - { - string typeNamespace, name; - - // Matches algorithm from ns::FindSep in src\coreclr\utilcode\namespaceutil.cpp - int separator = typeName.LastIndexOf('.'); - if (separator <= 0) - { - typeNamespace = ""; - name = typeName; - } - else - { - if (typeName[separator - 1] == '.') - separator--; - typeNamespace = typeName.Substring(0, separator); - name = typeName.Substring(separator + 1); - } - - return (typeNamespace, name); - } - -#if SYSTEM_PRIVATE_CORELIB - private void ParseError() - { - if (_throwOnError) - throw new ArgumentException(SR.Arg_ArgumentException, $"typeName@{_errorIndex}"); - } -#endif - } -} diff --git a/src/libraries/Common/src/System/Resources/ResourceWriter.cs b/src/libraries/Common/src/System/Resources/ResourceWriter.cs index 1f93de2776395b..81a70e7ae2f521 100644 --- a/src/libraries/Common/src/System/Resources/ResourceWriter.cs +++ b/src/libraries/Common/src/System/Resources/ResourceWriter.cs @@ -488,7 +488,7 @@ private static ResourceTypeCode FindTypeCode(object? value, List types) if (typeName.StartsWith("ResourceTypeCode.", StringComparison.Ordinal)) { typeName = typeName.Substring(17); // Remove through '.' -#if NETCOREAPP +#if NET ResourceTypeCode typeCode = Enum.Parse(typeName); #else ResourceTypeCode typeCode = (ResourceTypeCode)Enum.Parse(typeof(ResourceTypeCode), typeName); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AsnXml.targets b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AsnXml.targets index 940c73ca57237c..eb285cc2cfc279 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AsnXml.targets +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AsnXml.targets @@ -1,9 +1,6 @@ - <_AsnXmlDiffCmd>%24%28command -v diff%29 -q -a - <_AsnXmlDiffCmd Condition="$([MSBuild]::IsOsPlatform('windows')) == 'true'">$(SystemRoot)\System32\fc.exe /a - <_AsnXmlDiffCmd Condition="$([MSBuild]::IsOsPlatform('osx')) == 'true'">diff @@ -11,6 +8,27 @@ + + + + + + + + + + + + + + + - - - + + + - + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.manual.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.manual.cs index 71b8fe421f58e7..da7c9d3d8d0d80 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.manual.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.manual.cs @@ -7,7 +7,7 @@ internal partial struct AttributeAsn { public AttributeAsn(AsnEncodedData attribute) { -#if NET5_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(attribute); #else if (attribute is null) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs12/PfxAsn.manual.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs12/PfxAsn.manual.cs index f299c936232547..38e60abcebc640 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs12/PfxAsn.manual.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs12/PfxAsn.manual.cs @@ -63,7 +63,7 @@ internal bool VerifyMac( throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } -#if NETCOREAPP +#if NET Debug.Assert(expectedOutputSize <= 64); // SHA512 is the largest digest size we know about Span derived = stackalloc byte[expectedOutputSize]; #else diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.manual.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.manual.cs index e4d19d760700b2..543656905c4f7c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.manual.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.manual.cs @@ -9,7 +9,7 @@ internal partial struct X509ExtensionAsn { public X509ExtensionAsn(X509Extension extension) { -#if NET5_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(extension); #else if (extension is null) diff --git a/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs b/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs index dd3a37c32237bf..e4b71ded239f2d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CryptoPool.cs @@ -27,7 +27,7 @@ internal static void Return(byte[] array, int clearSize = ClearAll) if (!clearWholeArray && clearSize != 0) { -#if (NETCOREAPP || NETSTANDARD2_1) && !CP_NO_ZEROMEMORY +#if (NET || NETSTANDARD2_1) && !CP_NO_ZEROMEMORY CryptographicOperations.ZeroMemory(array.AsSpan(0, clearSize)); #else Array.Clear(array, 0, clearSize); diff --git a/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs b/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs index 3081a8bc239bad..e7cd24e0eeb1f8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/CryptoThrowHelper.Windows.cs @@ -5,7 +5,7 @@ using System.ComponentModel; using System.Security.Cryptography; -#if !NETCOREAPP3_1_OR_GREATER +#if !NET using System.Diagnostics; using System.Runtime.Serialization; #endif @@ -25,7 +25,7 @@ public static CryptographicException ToCryptographicException(this int hr) hr = (hr & 0x0000FFFF) | unchecked((int)0x80070000); } -#if NETCOREAPP3_1_OR_GREATER +#if NET return new CryptographicException(message) { HResult = hr @@ -40,7 +40,7 @@ public static CryptographicException ToCryptographicException(this int hr) #endif } -#if !NETCOREAPP3_1_OR_GREATER +#if !NET [Serializable] private sealed class WindowsCryptographicException : CryptographicException { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs index 0071c345d1d20a..462e4d26a8f64d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs @@ -12,13 +12,13 @@ internal static partial class Helpers { [UnsupportedOSPlatformGuard("browser")] internal static bool HasSymmetricEncryption { get; } = -#if NETCOREAPP +#if NET !OperatingSystem.IsBrowser(); #else true; #endif -#if NETCOREAPP +#if NET [UnsupportedOSPlatformGuard("ios")] [UnsupportedOSPlatformGuard("tvos")] public static bool IsDSASupported => !OperatingSystem.IsIOS() && !OperatingSystem.IsTvOS(); @@ -26,7 +26,7 @@ internal static partial class Helpers public static bool IsDSASupported => true; #endif -#if NETCOREAPP +#if NET [UnsupportedOSPlatformGuard("android")] [UnsupportedOSPlatformGuard("browser")] public static bool IsRC2Supported => !OperatingSystem.IsAndroid() && !OperatingSystem.IsBrowser(); @@ -36,7 +36,7 @@ internal static partial class Helpers [UnsupportedOSPlatformGuard("browser")] internal static bool HasMD5 { get; } = -#if NETCOREAPP +#if NET !OperatingSystem.IsBrowser(); #else true; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs b/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs index 69f5b96dee02db..2f584a0bbfd7f8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs @@ -8,38 +8,38 @@ namespace System.Security.Cryptography { internal static partial class Oids { - private static volatile Oid? s_rsaOid; - private static volatile Oid? s_ecPublicKeyOid; - private static volatile Oid? s_tripleDesCbcOid; - private static volatile Oid? s_aes256CbcOid; - private static volatile Oid? s_secp256R1Oid; - private static volatile Oid? s_secp384R1Oid; - private static volatile Oid? s_secp521R1Oid; - private static volatile Oid? s_sha256Oid; - private static volatile Oid? s_pkcs7DataOid; - private static volatile Oid? s_contentTypeOid; - private static volatile Oid? s_documentDescriptionOid; - private static volatile Oid? s_documentNameOid; - private static volatile Oid? s_localKeyIdOid; - private static volatile Oid? s_messageDigestOid; - private static volatile Oid? s_signingTimeOid; - private static volatile Oid? s_pkcs9ExtensionRequestOid; - private static volatile Oid? s_basicConstraints2Oid; - private static volatile Oid? s_enhancedKeyUsageOid; - private static volatile Oid? s_keyUsageOid; - private static volatile Oid? s_subjectAltNameOid; - private static volatile Oid? s_subjectKeyIdentifierOid; - private static volatile Oid? s_authorityKeyIdentifierOid; - private static volatile Oid? s_authorityInformationAccessOid; - private static volatile Oid? s_crlNumberOid; - private static volatile Oid? s_crlDistributionPointOid; - private static volatile Oid? s_commonNameOid; - private static volatile Oid? s_countryOrRegionOid; - private static volatile Oid? s_localityNameOid; - private static volatile Oid? s_stateOrProvinceNameOid; - private static volatile Oid? s_organizationOid; - private static volatile Oid? s_organizationalUnitOid; - private static volatile Oid? s_emailAddressOid; + private static Oid? s_rsaOid; + private static Oid? s_ecPublicKeyOid; + private static Oid? s_tripleDesCbcOid; + private static Oid? s_aes256CbcOid; + private static Oid? s_secp256R1Oid; + private static Oid? s_secp384R1Oid; + private static Oid? s_secp521R1Oid; + private static Oid? s_sha256Oid; + private static Oid? s_pkcs7DataOid; + private static Oid? s_contentTypeOid; + private static Oid? s_documentDescriptionOid; + private static Oid? s_documentNameOid; + private static Oid? s_localKeyIdOid; + private static Oid? s_messageDigestOid; + private static Oid? s_signingTimeOid; + private static Oid? s_pkcs9ExtensionRequestOid; + private static Oid? s_basicConstraints2Oid; + private static Oid? s_enhancedKeyUsageOid; + private static Oid? s_keyUsageOid; + private static Oid? s_subjectAltNameOid; + private static Oid? s_subjectKeyIdentifierOid; + private static Oid? s_authorityKeyIdentifierOid; + private static Oid? s_authorityInformationAccessOid; + private static Oid? s_crlNumberOid; + private static Oid? s_crlDistributionPointOid; + private static Oid? s_commonNameOid; + private static Oid? s_countryOrRegionOid; + private static Oid? s_localityNameOid; + private static Oid? s_stateOrProvinceNameOid; + private static Oid? s_organizationOid; + private static Oid? s_organizationalUnitOid; + private static Oid? s_emailAddressOid; internal static Oid RsaOid => s_rsaOid ??= InitializeOid(Rsa); internal static Oid EcPublicKeyOid => s_ecPublicKeyOid ??= InitializeOid(EcPublicKey); diff --git a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationManaged.cs b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationManaged.cs index f7928c69251585..60c64aa520e4be 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationManaged.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/SP800108HmacCounterKdfImplementationManaged.cs @@ -10,9 +10,6 @@ namespace System.Security.Cryptography { -#if !NET7_0_OR_GREATER && NET - [UnsupportedOSPlatform("browser")] -#endif internal sealed partial class SP800108HmacCounterKdfImplementationManaged : SP800108HmacCounterKdfImplementationBase { private byte[] _key; diff --git a/src/libraries/Common/src/System/Text/Json/PooledByteBufferWriter.cs b/src/libraries/Common/src/System/Text/Json/PooledByteBufferWriter.cs index 75424aed0d3cc3..51e1cccb43e305 100644 --- a/src/libraries/Common/src/System/Text/Json/PooledByteBufferWriter.cs +++ b/src/libraries/Common/src/System/Text/Json/PooledByteBufferWriter.cs @@ -27,7 +27,7 @@ internal sealed class PooledByteBufferWriter : IBufferWriter, IDisposable private PooledByteBufferWriter() { -#if NETCOREAPP +#if NET // Ensure we are in sync with the Array.MaxLength implementation. Debug.Assert(MaximumBufferSize == Array.MaxLength); #endif @@ -147,7 +147,7 @@ public Span GetSpan(int sizeHint = MinimumBufferSize) return _rentedBuffer.AsSpan(_index); } -#if NETCOREAPP +#if NET internal ValueTask WriteToStreamAsync(Stream destination, CancellationToken cancellationToken) { return destination.WriteAsync(WrittenMemory, cancellationToken); diff --git a/src/libraries/Common/src/System/Text/ValueStringBuilder.AppendSpanFormattable.cs b/src/libraries/Common/src/System/Text/ValueStringBuilder.AppendSpanFormattable.cs index 04e9fcbdb55240..3e9cf2c56d3ea6 100644 --- a/src/libraries/Common/src/System/Text/ValueStringBuilder.AppendSpanFormattable.cs +++ b/src/libraries/Common/src/System/Text/ValueStringBuilder.AppendSpanFormattable.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable + namespace System.Text { internal ref partial struct ValueStringBuilder diff --git a/src/libraries/Common/src/System/Text/ValueStringBuilder.cs b/src/libraries/Common/src/System/Text/ValueStringBuilder.cs index a0844b04664248..14aa77db3e57b0 100644 --- a/src/libraries/Common/src/System/Text/ValueStringBuilder.cs +++ b/src/libraries/Common/src/System/Text/ValueStringBuilder.cs @@ -161,7 +161,7 @@ public void Insert(int index, string? s) int remaining = _pos - index; _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); s -#if !NETCOREAPP +#if !NET .AsSpan() #endif .CopyTo(_chars.Slice(index)); @@ -213,7 +213,7 @@ private void AppendSlow(string s) } s -#if !NETCOREAPP +#if !NET .AsSpan() #endif .CopyTo(_chars.Slice(pos)); diff --git a/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs b/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs index 0075f897ff4625..7c9bd9073e6d3c 100644 --- a/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs +++ b/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs @@ -31,7 +31,7 @@ static class TaskToAsyncResult /// public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state) { -#if NET6_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(task); #else if (task is null) @@ -68,7 +68,7 @@ public static TResult End(IAsyncResult asyncResult) => /// was not produced by a call to . public static Task Unwrap(IAsyncResult asyncResult) { -#if NET6_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(asyncResult); #else if (asyncResult is null) @@ -97,7 +97,7 @@ public static Task Unwrap(IAsyncResult asyncResult) /// public static Task Unwrap(IAsyncResult asyncResult) { -#if NET6_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(asyncResult); #else if (asyncResult is null) diff --git a/src/libraries/Common/src/System/ThrowHelper.cs b/src/libraries/Common/src/System/ThrowHelper.cs index 4257c05891e32c..098b8321492764 100644 --- a/src/libraries/Common/src/System/ThrowHelper.cs +++ b/src/libraries/Common/src/System/ThrowHelper.cs @@ -15,7 +15,7 @@ internal static partial class ThrowHelper /// The reference type argument to validate as non-null. /// The name of the parameter with which corresponds. internal static void ThrowIfNull( -#if NETCOREAPP3_0_OR_GREATER +#if NET [NotNull] #endif object? argument, @@ -27,7 +27,7 @@ internal static void ThrowIfNull( } } -#if NETCOREAPP3_0_OR_GREATER +#if NET [DoesNotReturn] #endif private static void Throw(string? paramName) => throw new ArgumentNullException(paramName); @@ -40,17 +40,17 @@ internal static void ThrowIfNull( /// The name of the parameter being checked. /// The original value of . [MethodImpl(MethodImplOptions.AggressiveInlining)] -#if NETCOREAPP3_0_OR_GREATER +#if NET [return: NotNull] #endif public static string IfNullOrWhitespace( -#if NETCOREAPP3_0_OR_GREATER +#if NET [NotNull] #endif string? argument, [CallerArgumentExpression(nameof(argument))] string paramName = "") { -#if !NETCOREAPP3_1_OR_GREATER +#if !NET if (argument == null) { throw new ArgumentNullException(paramName); @@ -74,7 +74,7 @@ public static string IfNullOrWhitespace( } } -#if !NETCOREAPP3_0_OR_GREATER +#if !NET namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] diff --git a/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs b/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs index e67289721d8af9..e1c53d3b8aa16e 100644 --- a/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs +++ b/src/libraries/Common/tests/SourceGenerators/RoslynTestUtils.cs @@ -349,7 +349,7 @@ private static async Task RecreateDocumentAsync(Document document) } private static string ReplaceLineEndings(string text) => -#if NETCOREAPP +#if NET text.ReplaceLineEndings("\n"); #else text.Replace("\r\n", "\n"); diff --git a/src/libraries/Common/tests/System/Collections/TestBase.Generic.cs b/src/libraries/Common/tests/System/Collections/TestBase.Generic.cs index 73d382893d2898..0a22540b6588b9 100644 --- a/src/libraries/Common/tests/System/Collections/TestBase.Generic.cs +++ b/src/libraries/Common/tests/System/Collections/TestBase.Generic.cs @@ -255,7 +255,7 @@ protected IEnumerable CreateHashSet(IEnumerable enumerableToMatchTo, int c return set; } -#if NETCOREAPP +#if NET /// /// Create a HashSet with a specific initial capacity and fill it with a specific number of elements. /// diff --git a/src/libraries/Common/tests/System/GenericMathHelpers.cs b/src/libraries/Common/tests/System/GenericMathHelpers.cs index 277580dc5920d8..a02f8a4e162a6e 100644 --- a/src/libraries/Common/tests/System/GenericMathHelpers.cs +++ b/src/libraries/Common/tests/System/GenericMathHelpers.cs @@ -151,6 +151,12 @@ public static class FloatingPointHelper { public static TSelf Ceiling(TSelf x) => TSelf.Ceiling(x); + public static TInteger ConvertToInteger(TSelf x) + where TInteger : IBinaryInteger => TSelf.ConvertToInteger(x); + + public static TInteger ConvertToIntegerNative(TSelf x) + where TInteger : IBinaryInteger => TSelf.ConvertToIntegerNative(x); + public static TSelf Floor(TSelf x) => TSelf.Floor(x); public static TSelf Round(TSelf x) => TSelf.Round(x); diff --git a/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs b/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs index 6d194788762fa4..9666a16e2fb3ce 100644 --- a/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs +++ b/src/libraries/Common/tests/System/IO/Compression/ZipTestHelper.cs @@ -233,7 +233,7 @@ public static void IsZipSameAsDir(Stream archiveFile, string directory, ZipArchi using (Stream entrystream = entry.Open()) { ReadAllBytes(entrystream, buffer, 0, buffer.Length); -#if NETCOREAPP +#if NET uint zipcrc = entry.Crc32; Assert.Equal(CRC.CalculateCRC(buffer), zipcrc); #endif diff --git a/src/libraries/Common/tests/System/Net/Configuration.Http.cs b/src/libraries/Common/tests/System/Net/Configuration.Http.cs index ae1481c56061c7..460b7893cc635d 100644 --- a/src/libraries/Common/tests/System/Net/Configuration.Http.cs +++ b/src/libraries/Common/tests/System/Net/Configuration.Http.cs @@ -58,12 +58,19 @@ public static partial class Http public static readonly Uri RemoteEchoServer = new Uri("http://" + Host + "/" + EchoHandler); public static readonly Uri SecureRemoteEchoServer = new Uri("https://" + SecureHost + "/" + EchoHandler); public static readonly Uri Http2RemoteEchoServer = new Uri("https://" + Http2Host + "/" + EchoHandler); - public static readonly Uri[] EchoServerList = new Uri[] { RemoteEchoServer, SecureRemoteEchoServer, Http2RemoteEchoServer }; + public static Uri[] GetEchoServerList() + { + if (PlatformDetection.IsFirefox) + { + // https://github.com/dotnet/runtime/issues/101115 + return [RemoteEchoServer]; + } + return [RemoteEchoServer, SecureRemoteEchoServer, Http2RemoteEchoServer]; + } public static readonly Uri RemoteVerifyUploadServer = new Uri("http://" + Host + "/" + VerifyUploadHandler); public static readonly Uri SecureRemoteVerifyUploadServer = new Uri("https://" + SecureHost + "/" + VerifyUploadHandler); public static readonly Uri Http2RemoteVerifyUploadServer = new Uri("https://" + Http2Host + "/" + VerifyUploadHandler); - public static readonly Uri[] VerifyUploadServerList = new Uri[] { RemoteVerifyUploadServer, SecureRemoteVerifyUploadServer, Http2RemoteVerifyUploadServer }; public static readonly Uri RemoteEmptyContentServer = new Uri("http://" + Host + "/" + EmptyContentHandler); public static readonly Uri RemoteDeflateServer = new Uri("http://" + Host + "/" + DeflateHandler); @@ -72,7 +79,7 @@ public static partial class Http public static readonly Uri Http2RemoteGZipServer = new Uri("https://" + Http2Host + "/" + GZipHandler); public static Uri RemoteLoopServer => new Uri("ws://" + RemoteLoopHost + "/" + RemoteLoopHandler); - public static readonly object[][] EchoServers = EchoServerList.Select(x => new object[] { x }).ToArray(); + public static readonly object[][] EchoServers = GetEchoServerList().Select(x => new object[] { x }).ToArray(); public static readonly object[][] VerifyUploadServers = { new object[] { RemoteVerifyUploadServer }, new object[] { SecureRemoteVerifyUploadServer }, new object[] { Http2RemoteVerifyUploadServer } }; public static readonly object[][] CompressedServers = { new object[] { RemoteDeflateServer }, new object[] { RemoteGZipServer }, new object[] { Http2RemoteDeflateServer }, new object[] { Http2RemoteGZipServer } }; @@ -83,9 +90,17 @@ public static partial class Http public static readonly RemoteServer RemoteSecureHttp11Server = new RemoteServer(new Uri("https://" + SecureHost + "/"), HttpVersion.Version11); public static readonly RemoteServer RemoteHttp2Server = new RemoteServer(new Uri("https://" + Http2Host + "/"), new Version(2, 0)); - public static readonly IEnumerable RemoteServers = new RemoteServer[] { RemoteHttp11Server, RemoteSecureHttp11Server, RemoteHttp2Server }; + public static IEnumerable GetRemoteServers() + { + if (PlatformDetection.IsFirefox) + { + // https://github.com/dotnet/runtime/issues/101115 + return new RemoteServer[] { RemoteHttp11Server }; + } + return new RemoteServer[] { RemoteHttp11Server, RemoteSecureHttp11Server, RemoteHttp2Server }; + } - public static readonly IEnumerable RemoteServersMemberData = RemoteServers.Select(s => new object[] { s }); + public static readonly IEnumerable RemoteServersMemberData = GetRemoteServers().Select(s => new object[] { s }); public sealed class RemoteServer { diff --git a/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs b/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs index a24512ce3b4a58..c5686be67b4ef9 100644 --- a/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs +++ b/src/libraries/Common/tests/System/Net/Configuration.WebSockets.cs @@ -22,8 +22,35 @@ public static partial class WebSockets public static readonly Uri RemoteEchoHeadersServer = new Uri("ws://" + Host + "/" + EchoHeadersHandler); public static readonly Uri SecureRemoteEchoHeadersServer = new Uri("wss://" + SecureHost + "/" + EchoHeadersHandler); - public static readonly object[][] EchoServers = { new object[] { RemoteEchoServer }, new object[] { SecureRemoteEchoServer } }; - public static readonly object[][] EchoHeadersServers = { new object[] { RemoteEchoHeadersServer }, new object[] { SecureRemoteEchoHeadersServer } }; + public static object[][] GetEchoServers() + { + if (PlatformDetection.IsFirefox) + { + // https://github.com/dotnet/runtime/issues/101115 + return new object[][] { + new object[] { RemoteEchoServer }, + }; + } + return new object[][] { + new object[] { RemoteEchoServer }, + new object[] { SecureRemoteEchoServer }, + }; + } + + public static object[][] GetEchoHeadersServers() + { + if (PlatformDetection.IsFirefox) + { + // https://github.com/dotnet/runtime/issues/101115 + return new object[][] { + new object[] { RemoteEchoHeadersServer }, + }; + } + return new object[][] { + new object[] { RemoteEchoHeadersServer }, + new object[] { SecureRemoteEchoHeadersServer }, + }; + } } } } diff --git a/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs b/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs index d1b54ece613db1..e0407d918acc4d 100644 --- a/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs +++ b/src/libraries/Common/tests/System/Net/Http/ByteAtATimeContent.cs @@ -24,7 +24,7 @@ public ByteAtATimeContent(int length, Task waitToSend, TaskCompletionSource SerializeToStreamAsync(stream, context).GetAwaiter().GetResult(); #endif diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index 9d6fef5fb3a720..5635b753a5f6cf 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -198,7 +198,6 @@ public async Task DisposeCurrentStream() await _currentStream.DisposeAsync().ConfigureAwait(false); _openStreams.Remove((int)_currentStreamId); _currentStream = null; - _currentStreamId = -4; } public override async Task ReadRequestBodyAsync() diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs index b19c02b52ebc01..430cfeb2d47295 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs @@ -546,7 +546,7 @@ public static IEnumerable ServerUsesWindowsAuthentication_MemberData() public static IEnumerable EchoServersData() { - foreach (Uri serverUri in Configuration.Http.EchoServerList) + foreach (Uri serverUri in Configuration.Http.GetEchoServerList()) { yield return new object[] { serverUri }; } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs index b2f03bfbc930e5..6ecd7261ca2d97 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs @@ -44,7 +44,7 @@ private static CookieContainer CreateSingleCookieContainer(Uri uri, string cooki private static string GetCookieHeaderValue(string cookieName, string cookieValue) => $"{cookieName}={cookieValue}"; [Fact] - public async Task GetAsync_DefaultCoookieContainer_NoCookieSent() + public virtual async Task GetAsync_DefaultCoookieContainer_NoCookieSent() { await LoopbackServerFactory.CreateClientAndServerAsync( async uri => @@ -216,10 +216,15 @@ private string GetCookieValue(HttpRequestData request) return cookieHeaderValue; } - [Fact] + [ConditionalFact] [SkipOnPlatform(TestPlatforms.Browser, "CookieContainer is not supported on Browser")] public async Task GetAsync_SetCookieContainerAndCookieHeader_BothCookiesSent() { + if (UseVersion == HttpVersion30) + { + throw new SkipTestException("https://github.com/dotnet/runtime/issues/101377"); + } + await LoopbackServerFactory.CreateServerAsync(async (server, url) => { HttpClientHandler handler = CreateHttpClientHandler(); @@ -313,7 +318,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async url => using (HttpClient client = CreateHttpClient(handler)) { client.DefaultRequestHeaders.ConnectionClose = true; // to avoid issues with connection pooling - await client.GetAsync(url1); + await client.GetAsync(url1); } }, async server => diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs index 4da9edc2ca2147..f45206e9941dfe 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Decompression.cs @@ -200,7 +200,7 @@ await server.AcceptConnectionAsync(async connection => } [Theory] -#if NETCOREAPP +#if NET [InlineData(DecompressionMethods.Brotli, "br", "")] [InlineData(DecompressionMethods.Brotli, "br", "br")] [InlineData(DecompressionMethods.Brotli, "br", "gzip")] @@ -264,7 +264,7 @@ await LoopbackServer.CreateServerAsync(async (server, url) => } [Theory] -#if NETCOREAPP +#if NET [InlineData(DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli, "gzip; q=1.0, deflate; q=1.0, br; q=1.0", "")] #endif [InlineData(DecompressionMethods.GZip | DecompressionMethods.Deflate, "gzip; q=1.0, deflate; q=1.0", "")] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.RemoteServer.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.RemoteServer.cs index a264482a5549be..dd9db9bbe1f087 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.RemoteServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.RemoteServer.cs @@ -47,7 +47,7 @@ private static IEnumerable GetMethods(params string[] methods) { foreach (string method in methods) { - foreach (Uri serverUri in Configuration.Http.EchoServerList) + foreach (Uri serverUri in Configuration.Http.GetEchoServerList()) { yield return new object[] { method, serverUri }; } @@ -164,6 +164,7 @@ public async Task GetAsync_ServerNeedsAuthAndSetCredential_StatusCodeOK(Configur [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [Theory, MemberData(nameof(RemoteServersMemberData))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task GetAsync_ServerNeedsAuthAndNoCredential_StatusCodeUnauthorized(Configuration.Http.RemoteServer remoteServer) { using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer)) @@ -275,7 +276,7 @@ public static IEnumerable RemoteServersHeaderValuesAndUris() public static IEnumerable<(Configuration.Http.RemoteServer remoteServer, Uri uri)> RemoteServersAndHeaderEchoUris() { - foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.GetRemoteServers()) { yield return (remoteServer, remoteServer.EchoUri); yield return (remoteServer, remoteServer.RedirectUriForDestinationUri( @@ -464,7 +465,7 @@ public static IEnumerable VerifyUploadServersStreamsAndExpectedData { get { - foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) // target server + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.GetRemoteServers()) // target server foreach (bool syncCopy in BoolValues) // force the content copy to happen via Read/Write or ReadAsync/WriteAsync { byte[] data = new byte[1234]; @@ -868,7 +869,7 @@ public async Task SendAsync_SendRequestUsingNoBodyMethodToEchoServerWithContent_ public static IEnumerable SendAsync_SendSameRequestMultipleTimesDirectlyOnHandler_Success_MemberData() { - foreach (var server in Configuration.Http.RemoteServers) + foreach (var server in Configuration.Http.GetRemoteServers()) { yield return new object[] { server, "12345678910", 0 }; yield return new object[] { server, "12345678910", 5 }; @@ -909,7 +910,7 @@ public async Task SendAsync_SendSameRequestMultipleTimesDirectlyOnHandler_Succes public static IEnumerable RemoteServersAndRedirectStatusCodes() { - foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.GetRemoteServers()) { yield return new object[] { remoteServer, 300 }; yield return new object[] { remoteServer, 301 }; @@ -1228,7 +1229,7 @@ public async Task DefaultHeaders_SetCredentials_ClearedOnRedirect(Configuration. public static IEnumerable RemoteServersAndCompressionUris() { - foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.GetRemoteServers()) { yield return new object[] { remoteServer, remoteServer.GZipUri }; @@ -1329,6 +1330,7 @@ public async Task GetAsync_SetAutomaticDecompression_HeadersRemoved(Configuratio [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [Theory] [MemberData(nameof(Http2Servers))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task SendAsync_RequestVersion20_ResponseVersion20IfHttp2Supported(Uri server) { // Sync API supported only up to HTTP/1.1 diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs index eca2101b78edbb..236af85b26035d 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs @@ -116,7 +116,7 @@ public async Task UseCallback_NotSecureConnection_CallbackNotCalled() public static IEnumerable UseCallback_ValidCertificate_ExpectedValuesDuringCallback_Urls() { - foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.GetRemoteServers()) { if (remoteServer.IsSecure) { diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 0ffd0d4ae82eda..31d8d9f154fc4f 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -6,6 +6,9 @@ using System.Linq; using System.Net.Http.Headers; using System.Net.Sockets; +#if !NETFRAMEWORK +using System.Net.Quic; +#endif using System.Net.Test.Common; using System.Security.Authentication; using System.Security.Cryptography; @@ -267,7 +270,7 @@ await LoopbackServer.CreateClientAndServerAsync(async proxyUri => public static IEnumerable SecureAndNonSecure_IPBasedUri_MemberData() => from address in new[] { IPAddress.Loopback, IPAddress.IPv6Loopback } from useSsl in BoolValues - // we could not create SslStream in browser, [ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)] + // we could not create SslStream in browser, [ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)] where PlatformDetection.IsNotBrowser || !useSsl select new object[] { address, useSsl }; @@ -409,6 +412,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/86317", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task PostAsync_ManyDifferentRequestHeaders_SentCorrectly() { if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) @@ -823,6 +827,7 @@ await TestHelper.WhenAllCompletedOrAnyFailed( [InlineData("7gibberish")] // valid size then gibberish [InlineData("7\v\f")] // unacceptable whitespace [ActiveIssue("https://github.com/dotnet/runtime/issues/86317", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task GetAsync_InvalidChunkSize_ThrowsHttpRequestException(string chunkSize) { if (UseVersion != HttpVersion.Version11) @@ -856,6 +861,7 @@ await LoopbackServer.CreateServerAsync(async (server, url) => [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/86317", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task GetAsync_InvalidChunkTerminator_ThrowsHttpRequestException() { if (UseVersion != HttpVersion.Version11) @@ -877,14 +883,15 @@ await LoopbackServer.CreateClientAndServerAsync(async url => "\r\n" + "5\r\n" + "hello" + // missing \r\n terminator - //"5\r\n" + - //"world" + // missing \r\n terminator + //"5\r\n" + + //"world" + // missing \r\n terminator "0\r\n" + "\r\n")); } [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/86317", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task GetAsync_InfiniteChunkSize_ThrowsHttpRequestException() { if (UseVersion != HttpVersion.Version11) @@ -982,7 +989,7 @@ await connection.WriteStringAsync( }); } - [Theory] + [ConditionalTheory] [InlineData(true, true, true)] [InlineData(true, true, false)] [InlineData(true, false, false)] @@ -992,6 +999,11 @@ await connection.WriteStringAsync( [ActiveIssue("https://github.com/dotnet/runtime/issues/65429", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked, bool enableWasmStreaming, bool slowChunks) { + if (UseVersion == HttpVersion30) + { + throw new SkipTestException("https://github.com/dotnet/runtime/issues/91757"); + } + if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) { return; @@ -1003,9 +1015,9 @@ public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(boo return; } - if (enableWasmStreaming && !PlatformDetection.IsBrowser) + if (enableWasmStreaming && !PlatformDetection.IsChromium) { - // enableWasmStreaming makes only sense on Browser platform + // enableWasmStreaming makes only sense on Chrome return; } @@ -1091,7 +1103,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => if (PlatformDetection.IsBrowser) { #if !NETFRAMEWORK - if(slowChunks) + if (slowChunks) { Assert.Equal(1, await responseStream.ReadAsync(new Memory(buffer2))); Assert.Equal((byte)'h', buffer2[0]); @@ -1201,7 +1213,7 @@ await server.AcceptConnectionAsync(async connection => { case true: await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Transfer-Encoding", "chunked") }, isFinal: false); - if(PlatformDetection.IsBrowser && slowChunks) + if (PlatformDetection.IsBrowser && slowChunks) { await connection.SendResponseBodyAsync("1\r\nh\r\n", false); await tcs.Task; @@ -1216,12 +1228,12 @@ await server.AcceptConnectionAsync(async connection => break; case false: - await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", "11")}, content: "hello world"); + await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", "11") }, content: "hello world"); break; case null: // This inject Content-Length header with null value to hint Loopback code to not include one automatically. - await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", null)}, isFinal: false); + await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", null) }, isFinal: false); await connection.SendResponseBodyAsync("hello world"); break; } @@ -1323,7 +1335,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => server => server.AcceptConnectionSendResponseAndCloseAsync()); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsChromium))] [ActiveIssue("https://github.com/dotnet/runtime/issues/65429", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] public async Task ReadAsStreamAsync_StreamingCancellation() { @@ -1396,6 +1408,12 @@ await server.AcceptConnectionAsync(async connection => await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Transfer-Encoding", "chunked") }, isFinal: false); await connection.SendResponseBodyAsync("1\r\nh\r\n", false); } +#if !NETFRAMEWORK + catch (QuicException ex) when (ex.ApplicationErrorCode == 0x10c /*H3_REQUEST_CANCELLED*/) + { + // The request was cancelled before we sent the body, ignore + } +#endif catch (IOException ex) { // when testing in the browser, we are using the WebSocket for the loopback @@ -1411,6 +1429,7 @@ await server.AcceptConnectionAsync(async connection => } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task Dispose_DisposingHandlerCancelsActiveOperationsWithoutResponses() { if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) @@ -1450,10 +1469,10 @@ await LoopbackServerFactory.CreateServerAsync(async (server3, url3) => Task serverTask3 = server3.AcceptConnectionAsync(async connection3 => { await connection3.ReadRequestDataAsync(); - await connection3.SendResponseAsync(HttpStatusCode.OK, new HttpHeaderData[] { new HttpHeaderData("Content-Length", "20") }, isFinal : false); - await connection3.SendResponseBodyAsync("1234567890", isFinal : false); + await connection3.SendResponseAsync(HttpStatusCode.OK, new HttpHeaderData[] { new HttpHeaderData("Content-Length", "20") }, isFinal: false); + await connection3.SendResponseBodyAsync("1234567890", isFinal: false); await unblockServers.Task; - await connection3.SendResponseBodyAsync("1234567890", isFinal : true); + await connection3.SendResponseBodyAsync("1234567890", isFinal: true); }); // Make three requests @@ -1527,7 +1546,7 @@ public async Task GetAsync_UnicodeHostName_SuccessStatusCodeInResponse() } } -#region Post Methods Tests + #region Post Methods Tests [Fact] [SkipOnPlatform(TestPlatforms.Browser, "ExpectContinue not supported on Browser")] @@ -1571,13 +1590,13 @@ await server.AcceptConnectionAsync(async connection => public static IEnumerable Interim1xxStatusCode() { - yield return new object[] { (HttpStatusCode) 100 }; // 100 Continue. + yield return new object[] { (HttpStatusCode)100 }; // 100 Continue. // 101 SwitchingProtocols will be treated as a final status code. - yield return new object[] { (HttpStatusCode) 102 }; // 102 Processing. - yield return new object[] { (HttpStatusCode) 103 }; // 103 EarlyHints. - yield return new object[] { (HttpStatusCode) 150 }; - yield return new object[] { (HttpStatusCode) 180 }; - yield return new object[] { (HttpStatusCode) 199 }; + yield return new object[] { (HttpStatusCode)102 }; // 102 Processing. + yield return new object[] { (HttpStatusCode)103 }; // 103 EarlyHints. + yield return new object[] { (HttpStatusCode)150 }; + yield return new object[] { (HttpStatusCode)180 }; + yield return new object[] { (HttpStatusCode)199 }; } [Theory] @@ -1638,7 +1657,7 @@ await server.AcceptConnectionAsync(async connection => new HttpHeaderData("Content-type", "text/xml"), new HttpHeaderData("Set-Cookie", SetCookieIgnored1)}, isFinal: false); - await connection.SendResponseAsync(responseStatusCode, headers: new HttpHeaderData[] { + await connection.SendResponseAsync(responseStatusCode, headers: new HttpHeaderData[] { new HttpHeaderData("Cookie", "ignore_cookie=choco2"), new HttpHeaderData("Content-type", "text/plain"), new HttpHeaderData("Set-Cookie", SetCookieIgnored2)}, isFinal: false); @@ -1742,7 +1761,7 @@ await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestDataAsync(readBody: false); // Send multiple 100-Continue responses. - for (int count = 0 ; count < 4; count++) + for (int count = 0; count < 4; count++) { await connection.SendResponseAsync(HttpStatusCode.Continue, isFinal: false); } @@ -1846,7 +1865,7 @@ await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestDataAsync(readBody: false); - await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] {new HttpHeaderData("Content-Length", $"{ResponseString.Length}")}, isFinal : false); + await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", $"{ResponseString.Length}") }, isFinal: false); byte[] body = await connection.ReadRequestBodyAsync(); Assert.Equal(RequestString, Encoding.ASCII.GetString(body)); @@ -2127,7 +2146,7 @@ await LoopbackServerFactory.CreateServerAsync(async (server, rootUrl) => } }); } -#endregion + #endregion [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowserDomSupported))] public async Task GetAsync_InvalidUrl_ExpectedExceptionThrown() diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs index fdf301a809b863..689a6d6821eb62 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTestBase.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -#if !NETCOREAPP +#if !NET using System.Diagnostics; #endif using System.IO; @@ -90,7 +90,7 @@ public VersionCheckerHttpHandler(HttpMessageHandler innerHandler, Version expect _expectedVersion = expectedVersion; } -#if NETCOREAPP +#if NET protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { if (request.Version != _expectedVersion) @@ -138,7 +138,7 @@ public static Task SendAsync(this HttpClient client, bool a } else { -#if NETCOREAPP +#if NET // Note that the sync call must be done on a different thread because it blocks until the server replies. // However, the server-side of the request handling is in many cases invoked after the client, thus deadlocking the test. return Task.Run(() => client.Send(request, completionOption, cancellationToken)); @@ -159,7 +159,7 @@ public static Task SendAsync(this HttpMessageInvoker invoke } else { -#if NETCOREAPP +#if NET // Note that the sync call must be done on a different thread because it blocks until the server replies. // However, the server-side of the request handling is in many cases invoked after the client, thus deadlocking the test. return Task.Run(() => invoker.Send(request, cancellationToken)); @@ -176,7 +176,7 @@ public static Task ReadAsStreamAsync(this HttpContent content, bool asyn { if (async) { -#if NETCOREAPP +#if NET // No CancellationToken accepting overload on NETFX. return content.ReadAsStreamAsync(cancellationToken); #else @@ -186,7 +186,7 @@ public static Task ReadAsStreamAsync(this HttpContent content, bool asyn } else { -#if NETCOREAPP +#if NET return Task.FromResult(content.ReadAsStream(cancellationToken)); #else // Framework won't ever have the sync API. @@ -199,7 +199,7 @@ public static Task ReadAsStreamAsync(this HttpContent content, bool asyn public static Task GetByteArrayAsync(this HttpClient client, bool async, bool useCopyTo, Uri uri) { -#if NETCOREAPP +#if NET return Task.Run(async () => { var m = new HttpRequestMessage(HttpMethod.Get, uri); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpMessageHandlerLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/HttpMessageHandlerLoopbackServer.cs index 9d9d412511ac6e..4b6a326cf6f585 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpMessageHandlerLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpMessageHandlerLoopbackServer.cs @@ -60,7 +60,7 @@ public LoopbackServerHttpMessageHandler(Func RemoteServersAndLargeContentSizes() { - foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.GetRemoteServers()) { yield return new object[] { remoteServer, 5 * 1024 }; yield return new object[] { remoteServer, 63 * 1024 }; diff --git a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs index e38204ffc031e3..6e532aa23d959b 100644 --- a/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs @@ -21,7 +21,7 @@ public ResponseStreamTest(ITestOutputHelper output) : base(output) { } public static IEnumerable RemoteServersAndReadModes() { - foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.RemoteServers) + foreach (Configuration.Http.RemoteServer remoteServer in Configuration.Http.GetRemoteServers()) { for (int i = 0; i < 8; i++) { @@ -228,9 +228,9 @@ await client.GetAsync(remoteServer.EchoUri, HttpCompletionOption.ResponseHeaders } } -#if NETCOREAPP +#if NET - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsChromium))] public async Task BrowserHttpHandler_Streaming() { var WebAssemblyEnableStreamingRequestKey = new HttpRequestOptionsKey("WebAssemblyEnableStreamingRequest"); @@ -287,7 +287,7 @@ public async Task BrowserHttpHandler_Streaming() } [OuterLoop] - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsChromium))] public async Task BrowserHttpHandler_StreamingRequest() { var WebAssemblyEnableStreamingRequestKey = new HttpRequestOptionsKey("WebAssemblyEnableStreamingRequest"); @@ -330,7 +330,7 @@ public async Task BrowserHttpHandler_StreamingRequest() // Duplicate of PostAsync_ThrowFromContentCopy_RequestFails using remote server [OuterLoop] - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsChromium))] [InlineData(false)] [InlineData(true)] public async Task BrowserHttpHandler_StreamingRequest_ThrowFromContentCopy_RequestFails(bool syncFailure) @@ -368,7 +368,7 @@ public static TheoryData CancelRequestReadFunctions }; [OuterLoop] - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsChromium))] [MemberData(nameof(CancelRequestReadFunctions))] public async Task BrowserHttpHandler_StreamingRequest_CancelRequest(bool cancelAsync, Func> readFunc) { @@ -438,7 +438,7 @@ public async Task BrowserHttpHandler_StreamingRequest_Http1Fails() } [OuterLoop] - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsChromium))] public async Task BrowserHttpHandler_StreamingResponse() { var WebAssemblyEnableStreamingResponseKey = new HttpRequestOptionsKey("WebAssemblyEnableStreamingResponse"); @@ -477,6 +477,7 @@ public async Task BrowserHttpHandler_StreamingResponse() [InlineData(TransferType.ContentLength, TransferError.ContentLengthTooLarge)] [InlineData(TransferType.Chunked, TransferError.MissingChunkTerminator)] [InlineData(TransferType.Chunked, TransferError.ChunkSizeTooLarge)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task ReadAsStreamAsync_InvalidServerResponse_ThrowsIOException( TransferType transferType, TransferError transferError) diff --git a/src/libraries/Common/tests/System/Net/Http/TestHelper.cs b/src/libraries/Common/tests/System/Net/Http/TestHelper.cs index c1d7a047070e6c..455f9581df335f 100644 --- a/src/libraries/Common/tests/System/Net/Http/TestHelper.cs +++ b/src/libraries/Common/tests/System/Net/Http/TestHelper.cs @@ -96,7 +96,7 @@ public static Task WhenAllCompletedOrAnyFailedWithTimeout(int timeoutInMilliseco return TaskTimeoutExtensions.WhenAllOrAnyFailed(tasks, timeoutInMilliseconds); } -#if NETCOREAPP +#if NET public static Func AllowAllCertificates = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; #else public static Func AllowAllCertificates = (_, __, ___, ____) => true; @@ -149,7 +149,7 @@ public static X509Certificate2 CreateServerSelfSignedCertificate(string name = " } } -#if NETCOREAPP +#if NET public static SocketsHttpHandler CreateSocketsHttpHandler(bool allowAllCertificates = false) { var handler = new SocketsHttpHandler(); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs index cd8bf922227cd6..6ad596a040c4b3 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSASignVerify.cs @@ -75,7 +75,7 @@ public void InvalidArrayArguments_Throws() } } -#if NETCOREAPP +#if NET [SkipOnPlatform(TestPlatforms.Browser | TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.MacCatalyst, "Not supported on Browser/iOS/tvOS/MacCatalyst")] public sealed class DSASignVerify_Span : DSASignVerify { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs index a49b2c3329b725..b0c5823145a87b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs @@ -5,7 +5,7 @@ namespace System.Security.Cryptography.Tests { public class CurveDef { -#if NETCOREAPP +#if NET public CurveDef() { } public ECCurve Curve; public ECCurve.ECCurveType CurveType; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs index 5f9dae4c8fcefb..8cc2391ba8dce8 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs @@ -15,7 +15,7 @@ namespace System.Security.Cryptography.Tests /// public abstract class EccTestBase { -#if NETCOREAPP +#if NET internal const string ECDSA_P224_OID_VALUE = "1.3.132.0.33"; // Also called nistP224 or secP224r1 internal const string ECDSA_P256_OID_VALUE = "1.2.840.10045.3.1.7"; // Also called nistP256, secP256r1 or prime256v1(OpenSsl) internal const string ECDSA_P384_OID_VALUE = "1.3.132.0.34"; // Also called nistP384 or secP384r1 diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs index 84bbea4587eef4..9a2de091ab3b42 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs @@ -7,7 +7,7 @@ public interface IECDiffieHellmanProvider { ECDiffieHellman Create(); ECDiffieHellman Create(int keySize); -#if NETCOREAPP +#if NET ECDiffieHellman Create(ECCurve curve); #endif bool IsCurveValid(Oid oid); @@ -29,7 +29,7 @@ public static ECDiffieHellman Create(int keySize) return s_provider.Create(keySize); } -#if NETCOREAPP +#if NET public static ECDiffieHellman Create(ECCurve curve) { return s_provider.Create(curve); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs index 0065092e52aad1..ae8d32b02cc665 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs @@ -290,7 +290,7 @@ public static IEnumerable HashDerivationTestCases() } } -#if NETCOREAPP +#if NET [Theory] [MemberData(nameof(HashDerivationTestCases))] public static void HashDerivation_KnownResults( diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs index f95fb64aafd3a4..575a9d853fe266 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs @@ -349,7 +349,7 @@ public static IEnumerable HmacDerivationTestCases() } } -#if NETCOREAPP +#if NET [Theory] [MemberData(nameof(HmacDerivationTestCases))] public static void HmacDerivation_KnownResults( diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs index 82f78094bb1000..1c507beee0d8d7 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs @@ -8,7 +8,7 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests { -#if NETCOREAPP +#if NET public partial class ECDiffieHellmanTests { // On CentOS, secp224r1 (also called nistP224) appears to be disabled. To prevent test failures on that platform, diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs index d79d8de3edba17..ce07c475bec5fd 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs @@ -8,7 +8,7 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests { -#if NETCOREAPP +#if NET // These test cases are from http://csrc.nist.gov/groups/STM/cavp/component-testing.html#test-vectors // SP 800-56A ECCCDH Primitive test vectors // ecccdhtestvectors.zip diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs index 4bffb87b2dd1da..d8c6e8f0ff0641 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs @@ -189,7 +189,7 @@ public static IEnumerable TlsDerivationTestCases() }; } -#if NETCOREAPP +#if NET [Theory] [MemberData(nameof(TlsDerivationTestCases))] public static void TlsDerivation_KnownResults(string labelText, string answerHex) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs index 0b41aa08ea28c7..dc7a757d6e5373 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs @@ -172,7 +172,7 @@ public static void UseAfterDispose(bool importKey) pubKey.Dispose(); } -#if NETCOREAPP +#if NET private static ECDiffieHellman OpenKnownKey() { ECParameters ecParams = new ECParameters diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs index 59d45d3de99c7e..01e5dfe6701f48 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs @@ -7,7 +7,7 @@ public interface IECDsaProvider { ECDsa Create(); ECDsa Create(int keySize); -#if NETCOREAPP +#if NET ECDsa Create(ECCurve curve); #endif bool IsCurveValid(Oid oid); @@ -26,7 +26,7 @@ public static ECDsa Create(int keySize) return s_provider.Create(keySize); } -#if NETCOREAPP +#if NET public static ECDsa Create(ECCurve curve) { return s_provider.Create(curve); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs index 1925320e66ab5a..058b626c62c89a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs @@ -15,7 +15,7 @@ public class ECDsaImportExportTests : ECDsaTestsBase internal static bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.ECDiffieHellmanFactory.CanDeriveNewPublicKey; -#if NETCOREAPP +#if NET [Fact] public static void DiminishedCoordsRoundtrip() { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaStub.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaStub.cs index b40f4e721a497d..43c44b71a2a288 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaStub.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaStub.cs @@ -30,7 +30,7 @@ protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) throw new NotImplementedException(); } -#if NETCOREAPP +#if NET public override void ImportParameters(ECParameters parameters) { throw new NotImplementedException(); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs index d0c596935ef092..e0da3f3e75a811 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs @@ -13,7 +13,7 @@ public abstract partial class ECDsaTests : ECDsaTestsBase // FIPS 186-4 ECDSA test vectors // 186-3ecdsatestvectors.zip // SigGen.txt -#if NETCOREAPP +#if NET [Fact] public void ValidateNistP256Sha256() { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs index 9da985adfd21fb..9c2e3fc0b44abd 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs @@ -15,7 +15,7 @@ namespace System.Security.Cryptography.EcDsa.Tests [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public abstract class ECDsaTestsBase : EccTestBase { -#if NETCOREAPP +#if NET internal static void Verify256(ECDsa e, bool expected) { byte[] sig = ("998791331eb2e1f4259297f5d9cb82fa20dec98e1cb0900e6b8f014a406c3d02cbdbf5238bde471c3155fc25565524301429" diff --git a/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs b/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs index ae9f09caf23a5d..7be1321023e2bf 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/PlatformSupport.cs @@ -74,7 +74,7 @@ static bool DetermineAlgorithmFunctional(CngAlgorithm algorithm) // Whether or not the current platform supports RC2 internal static readonly bool IsRC2Supported = !PlatformDetection.IsAndroid; -#if NETCOREAPP +#if NET internal static readonly bool IsAndroidVersionAtLeast31 = OperatingSystem.IsAndroidVersionAtLeast(31); #else internal static readonly bool IsAndroidVersionAtLeast31 = false; diff --git a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs index 232c05afb8d271..cdab35da2b134b 100644 --- a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs +++ b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if NET6_0_OR_GREATER +#if NET using System.Runtime.Intrinsics; #endif using System.Threading; @@ -27,7 +27,7 @@ public static class AssertExtensions public static void ThrowsOnAot(Action action) where T : Exception { -#if NETCOREAPP // Dynamic code is always supported on .NET Framework +#if NET // Dynamic code is always supported on .NET Framework if (!RuntimeFeature.IsDynamicCodeSupported) { Assert.Throws(action); @@ -710,7 +710,7 @@ static unsafe bool IsPositiveZero(double value) return (*(ulong*)(&value)) == 0x0000000000000000; } -#if NET6_0_OR_GREATER +#if NET static unsafe bool IsNegativeZero(Half value) { return (*(ushort*)(&value)) == 0x8000; @@ -780,7 +780,7 @@ static string ToStringPadded(double value) } } -#if NET6_0_OR_GREATER +#if NET static string ToStringPadded(Half value) { if (Half.IsNaN(value)) @@ -1036,7 +1036,7 @@ public static void Equal(float expected, float actual, float variance) } } -#if NET6_0_OR_GREATER +#if NET /// Verifies that two values are equal, within the . /// The expected value /// The value to be compared against @@ -1196,7 +1196,7 @@ static unsafe int SingleToInt32Bits(float value) throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual)); } -#if NET6_0_OR_GREATER +#if NET /// Verifies that two values's binary representations are identical. /// The expected value /// The value to be compared against diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index ec6645cec0c319..8aac8589611098 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -125,7 +125,7 @@ public static int SlowRuntimeTimeoutModifier public static bool IsCaseInsensitiveOS => IsWindows || IsOSX || IsMacCatalyst; public static bool IsCaseSensitiveOS => !IsCaseInsensitiveOS; -#if NETCOREAPP +#if NET public static bool FileCreateCaseSensitive => IsCaseSensitiveOS && !RuntimeInformation.RuntimeIdentifier.StartsWith("iossimulator") && !RuntimeInformation.RuntimeIdentifier.StartsWith("tvossimulator"); #else @@ -181,7 +181,7 @@ private static bool GetLinqExpressionsBuiltWithIsInterpretingOnly() public static bool IsNotInContainer => !IsInContainer; public static bool SupportsComInterop => IsWindows && IsNotMonoRuntime && !IsNativeAot; // matches definitions in clr.featuredefines.props -#if NETCOREAPP +#if NET public static bool IsBuiltInComEnabled => SupportsComInterop && (AppContext.TryGetSwitch("System.Runtime.InteropServices.BuiltInComInterop.IsSupported", out bool isEnabled) ? isEnabled @@ -198,7 +198,7 @@ private static bool GetLinqExpressionsBuiltWithIsInterpretingOnly() public static bool SupportsSsl3 => GetSsl3Support(); public static bool SupportsSsl2 => IsWindows && !PlatformDetection.IsWindows10Version1607OrGreater; -#if NETCOREAPP +#if NET public static bool IsReflectionEmitSupported => RuntimeFeature.IsDynamicCodeSupported; public static bool IsNotReflectionEmitSupported => !IsReflectionEmitSupported; #else @@ -668,7 +668,7 @@ private static bool GetSendsCAListByDefault() private static bool GetIsRunningOnMonoInterpreter() { -#if NETCOREAPP +#if NET return IsMonoRuntime && RuntimeFeature.IsDynamicCodeSupported && !RuntimeFeature.IsDynamicCodeCompiled; #else return false; diff --git a/src/libraries/Common/tests/TestUtilities/System/Runtime/InteropServices/SafeBufferUtil.cs b/src/libraries/Common/tests/TestUtilities/System/Runtime/InteropServices/SafeBufferUtil.cs index f667b1e26cec55..d3ff55aa515635 100644 --- a/src/libraries/Common/tests/TestUtilities/System/Runtime/InteropServices/SafeBufferUtil.cs +++ b/src/libraries/Common/tests/TestUtilities/System/Runtime/InteropServices/SafeBufferUtil.cs @@ -19,7 +19,7 @@ private sealed class AllocHGlobalSafeHandle : SafeBuffer { public AllocHGlobalSafeHandle(nuint cb) : base(ownsHandle: true) { -#if !NETCOREAPP +#if !NET RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs b/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs index b4d9be2a52744d..2817d305e6d0a1 100644 --- a/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs +++ b/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Net; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif using System.Security.Cryptography; @@ -127,7 +127,7 @@ private void CreateUser() [LibraryImport("netapi32.dll")] internal static partial uint NetUserDel([MarshalAs(UnmanagedType.LPWStr)] string servername, [MarshalAs(UnmanagedType.LPWStr)] string username); -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(USER_INFO_1.Marshaller))] #endif [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -142,7 +142,7 @@ internal struct USER_INFO_1 public uint usri1_flags; public string usri1_script_path; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(USER_INFO_1), MarshalMode.Default, typeof(Marshaller))] public static class Marshaller { diff --git a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs index bd7b633ba6f822..8cb70ee3cbd8c9 100644 --- a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs +++ b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs @@ -55,41 +55,51 @@ public TestEventListener(ITestOutputHelper output, params string[] sourceNames) public TestEventListener(Action writeFunc, params string[] sourceNames) { + List eventSources = _eventSources; + lock (this) { _writeFunc = writeFunc; _sourceNames = new HashSet(sourceNames); - foreach (EventSource eventSource in _eventSources) + _eventSources = null; + } + + // eventSources were populated in the base ctor and are now owned by this thread, enable them now. + foreach (EventSource eventSource in eventSources) + { + if (_sourceNames.Contains(eventSource.Name)) { - OnEventSourceCreated(eventSource); + EnableEvents(eventSource, EventLevel.LogAlways); } - _eventSources = null; } } protected override void OnEventSourceCreated(EventSource eventSource) { - lock (this) + // We're likely called from base ctor, if so, just save the event source for later initialization. + if (_sourceNames is null) { - // We're called from base ctor, just save the event source for later initialization. - if (_sourceNames is null) + lock (this) { - _eventSources.Add(eventSource); - return; + if (_sourceNames is null) + { + _eventSources.Add(eventSource); + return; + } } + } - // Second pass called from our ctor, allow logging for specified source names. - if (_sourceNames.Contains(eventSource.Name)) - { - EnableEvents(eventSource, EventLevel.LogAlways); - } + // Second pass called after our ctor, allow logging for specified source names. + if (_sourceNames.Contains(eventSource.Name)) + { + EnableEvents(eventSource, EventLevel.LogAlways); } } protected override void OnEventWritten(EventWrittenEventArgs eventData) { StringBuilder sb = new StringBuilder(). -#if NETCOREAPP2_2_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER Append($"{eventData.TimeStamp:HH:mm:ss.fffffff}[{eventData.EventName}] "); #else Append($"[{eventData.EventName}] "); @@ -102,7 +112,7 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) } try { - _writeFunc(sb.ToString()); + _writeFunc?.Invoke(sb.ToString()); } catch { } } diff --git a/src/libraries/Common/tests/Tests/System/StringTests.cs b/src/libraries/Common/tests/Tests/System/StringTests.cs index f21dbe3baad6a6..8e465475a5200e 100644 --- a/src/libraries/Common/tests/Tests/System/StringTests.cs +++ b/src/libraries/Common/tests/Tests/System/StringTests.cs @@ -314,6 +314,7 @@ void Validate(string result) } Validate(string.Concat(values)); + Validate(string.Concat((ReadOnlySpan)values)); Validate(string.Concat((IEnumerable)values)); Validate(string.Concat((IEnumerable)values)); // Call the generic IEnumerable-based overload } @@ -418,6 +419,7 @@ public static void Concat_Objects(object[] values, string expected) Assert.Equal(expected, string.Concat(values[0], values[1], values[2], values[3])); } Assert.Equal(expected, string.Concat(values)); + Assert.Equal(expected, string.Concat((ReadOnlySpan)values)); Assert.Equal(expected, string.Concat((IEnumerable)values)); } @@ -2730,9 +2732,11 @@ public static IEnumerable Format_Valid_TestData() public static void Format_Valid(IFormatProvider provider, string format, object[] values, string expected) { Assert.Equal(expected, string.Format(provider, format, values)); + Assert.Equal(expected, string.Format(provider, format, (ReadOnlySpan)values)); if (provider is null) { Assert.Equal(expected, string.Format(format, values)); + Assert.Equal(expected, string.Format(format, (ReadOnlySpan)values)); } switch (values.Length) @@ -3967,6 +3971,7 @@ public static void Join_StringArray(string separator, string[] values, int start if (startIndex + count == values.Length && count != 0) { Assert.Equal(expected, string.Join(separator, values)); + Assert.Equal(expected, string.Join(separator, (ReadOnlySpan)values)); var iEnumerableStringOptimized = new List(values); Assert.Equal(expected, string.Join(separator, iEnumerableStringOptimized)); @@ -3984,6 +3989,44 @@ public static void Join_StringArray(string separator, string[] values, int start { var arrayOfObjects = (object[])values; Assert.Equal(expected, string.Join(separator, arrayOfObjects)); + Assert.Equal(expected, string.Join(separator, (ReadOnlySpan)arrayOfObjects)); + } + } + Assert.Equal(expected, string.Join(separator, values, startIndex, count)); + } + + [Theory] + [InlineData('$', new string[] { }, 0, 0, "")] + [InlineData('$', new string[] { null }, 0, 1, "")] + [InlineData('$', new string[] { null, "Bar", null }, 0, 3, "$Bar$")] + [InlineData('$', new string[] { "", "", "" }, 0, 3, "$$")] + [InlineData('$', new string[] { "Foo", "Bar", "Baz" }, 0, 3, "Foo$Bar$Baz")] + [InlineData('$', new string[] { "Foo", "Bar", "Baz" }, 3, 0, "")] + [InlineData('$', new string[] { "Foo", "Bar", "Baz" }, 1, 1, "Bar")] + public static void Join_CharSeparator_StringArray(char separator, string[] values, int startIndex, int count, string expected) + { + if (startIndex + count == values.Length && count != 0) + { + Assert.Equal(expected, string.Join(separator, values)); + Assert.Equal(expected, string.Join(separator, (ReadOnlySpan)values)); + + var iEnumerableStringOptimized = new List(values); + Assert.Equal(expected, string.Join(separator, iEnumerableStringOptimized)); + Assert.Equal(expected, string.Join(separator, iEnumerableStringOptimized)); // Call the generic IEnumerable-based overload + + var iEnumerableStringNotOptimized = new Queue(values); + Assert.Equal(expected, string.Join(separator, iEnumerableStringNotOptimized)); + Assert.Equal(expected, string.Join(separator, iEnumerableStringNotOptimized)); + + var iEnumerableObject = new List(values); + Assert.Equal(expected, string.Join(separator, iEnumerableObject)); + + // Bug/Documented behavior: Join(string, object[]) returns "" when the first item in the array is null + if (values.Length == 0 || values[0] != null) + { + var arrayOfObjects = (object[])values; + Assert.Equal(expected, string.Join(separator, arrayOfObjects)); + Assert.Equal(expected, string.Join(separator, (ReadOnlySpan)arrayOfObjects)); } } Assert.Equal(expected, string.Join(separator, values, startIndex, count)); @@ -4038,6 +4081,31 @@ public static void Join_ObjectArray(string separator, object[] values, string ex { Assert.Equal(expected, string.Join(separator, values)); Assert.Equal(expected, string.Join(separator, (IEnumerable)values)); + Assert.Equal(expected, string.Join(separator, (ReadOnlySpan)values)); + } + + public static IEnumerable Join_CharSeparator_ObjectArray_TestData() + { + yield return new object[] { '$', new object[] { }, "" }; + yield return new object[] { '$', new object[] { new ObjectWithNullToString() }, "" }; + yield return new object[] { '$', new object[] { "Foo" }, "Foo" }; + yield return new object[] { '$', new object[] { "Foo", "Bar", "Baz" }, "Foo$Bar$Baz" }; + yield return new object[] { '$', new object[] { "Foo", null, "Baz" }, "Foo$$Baz" }; + + // Test join when first value is null + yield return new object[] { '$', new object[] { null, "Bar", "Baz" }, "$Bar$Baz" }; + + // Join should ignore objects that have a null ToString() value + yield return new object[] { "|", new object[] { new ObjectWithNullToString(), "Foo", new ObjectWithNullToString(), "Bar", new ObjectWithNullToString() }, "|Foo||Bar|" }; + } + + [Theory] + [MemberData(nameof(Join_CharSeparator_ObjectArray_TestData))] + public static void Join_CharSeparator_ObjectArray(char separator, object[] values, string expected) + { + Assert.Equal(expected, string.Join(separator, values)); + Assert.Equal(expected, string.Join(separator, (IEnumerable)values)); + Assert.Equal(expected, string.Join(separator, (ReadOnlySpan)values)); } [Fact] @@ -6098,6 +6166,7 @@ public static void Trim(string s, char[] trimChars, string expected) } Assert.Equal(expected, s.Trim(trimChars)); + Assert.Equal(expected, s.Trim((ReadOnlySpan)trimChars)); Assert.Equal(expected, s.AsSpan().Trim(trimChars).ToString()); } @@ -6128,6 +6197,7 @@ public static void TrimEnd(string s, char[] trimChars, string expected) } Assert.Equal(expected, s.TrimEnd(trimChars)); + Assert.Equal(expected, s.TrimEnd((ReadOnlySpan)trimChars)); Assert.Equal(expected, s.AsSpan().TrimEnd(trimChars).ToString()); } @@ -6158,6 +6228,7 @@ public static void TrimStart(string s, char[] trimChars, string expected) } Assert.Equal(expected, s.TrimStart(trimChars)); + Assert.Equal(expected, s.TrimStart((ReadOnlySpan)trimChars)); Assert.Equal(expected, s.AsSpan().TrimStart(trimChars).ToString()); } @@ -6388,18 +6459,27 @@ public static void ZeroLengthTrimCharacters() Assert.True(s1.SequenceEqual(s1.Trim(trimCharsString))); Assert.True(s1.SequenceEqual(s1.TrimStart(trimCharsString))); Assert.True(s1.SequenceEqual(s1.TrimEnd(trimCharsString))); + Assert.True(s1.SequenceEqual(s1.Trim((ReadOnlySpan)trimCharsString))); + Assert.True(s1.SequenceEqual(s1.TrimStart((ReadOnlySpan)trimCharsString))); + Assert.True(s1.SequenceEqual(s1.TrimEnd((ReadOnlySpan)trimCharsString))); char[] chars = { 'a', 'b', 'c', 'd', 'e' }; trimCharsString = chars; Assert.True(s1.SequenceEqual(s1.Trim(trimCharsString))); Assert.True(s1.SequenceEqual(s1.TrimStart(trimCharsString))); Assert.True(s1.SequenceEqual(s1.TrimEnd(trimCharsString))); + Assert.True(s1.SequenceEqual(s1.Trim((ReadOnlySpan)trimCharsString))); + Assert.True(s1.SequenceEqual(s1.TrimStart((ReadOnlySpan)trimCharsString))); + Assert.True(s1.SequenceEqual(s1.TrimEnd((ReadOnlySpan)trimCharsString))); string emptyString = string.Empty; char[] trimCharsArrayFromString = "abcde".ToCharArray(); Assert.True(emptyString.SequenceEqual(emptyString.Trim(trimCharsArrayFromString))); Assert.True(emptyString.SequenceEqual(emptyString.TrimStart(trimCharsArrayFromString))); Assert.True(emptyString.SequenceEqual(emptyString.TrimEnd(trimCharsArrayFromString))); + Assert.True(emptyString.SequenceEqual(emptyString.Trim((ReadOnlySpan)trimCharsArrayFromString))); + Assert.True(emptyString.SequenceEqual(emptyString.TrimStart((ReadOnlySpan)trimCharsArrayFromString))); + Assert.True(emptyString.SequenceEqual(emptyString.TrimEnd((ReadOnlySpan)trimCharsArrayFromString))); ReadOnlySpan span = s1.AsSpan(); ReadOnlySpan trimChars = trimCharsString.AsSpan(); @@ -6435,6 +6515,9 @@ public static void NoTrimCharacters() Assert.True(s1.SequenceEqual(s1.Trim(trimCharsString))); Assert.True(s1.SequenceEqual(s1.TrimStart(trimCharsString))); Assert.True(s1.SequenceEqual(s1.TrimEnd(trimCharsString))); + Assert.True(s1.SequenceEqual(s1.Trim((ReadOnlySpan)trimCharsString))); + Assert.True(s1.SequenceEqual(s1.TrimStart((ReadOnlySpan)trimCharsString))); + Assert.True(s1.SequenceEqual(s1.TrimEnd((ReadOnlySpan)trimCharsString))); ReadOnlySpan span = s1.AsSpan(); Assert.True(span.SequenceEqual(span.Trim(trimChars))); @@ -6454,6 +6537,9 @@ public static void NoTrimCharacters() Assert.True(s2.SequenceEqual(s2.Trim(chars))); Assert.True(s2.SequenceEqual(s2.TrimStart(chars))); Assert.True(s2.SequenceEqual(s2.TrimEnd(chars))); + Assert.True(s2.SequenceEqual(s2.Trim((ReadOnlySpan)chars))); + Assert.True(s2.SequenceEqual(s2.TrimStart((ReadOnlySpan)chars))); + Assert.True(s2.SequenceEqual(s2.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan span = s2.AsSpan(); Assert.True(span.SequenceEqual(span.Trim(chars))); @@ -6466,6 +6552,9 @@ public static void NoTrimCharacters() Assert.True(s3.SequenceEqual(s3.Trim(trimCharsFromString))); Assert.True(s3.SequenceEqual(s3.TrimStart(trimCharsFromString))); Assert.True(s3.SequenceEqual(s3.TrimEnd(trimCharsFromString))); + Assert.True(s3.SequenceEqual(s3.Trim((ReadOnlySpan)trimCharsFromString))); + Assert.True(s3.SequenceEqual(s3.TrimStart((ReadOnlySpan)trimCharsFromString))); + Assert.True(s3.SequenceEqual(s3.TrimEnd((ReadOnlySpan)trimCharsFromString))); ReadOnlySpan stringSpan = s3.AsSpan(); ReadOnlySpan trimCharsFromStringSpan = trimCharsFromString.AsSpan(); @@ -6490,6 +6579,9 @@ public static void OnlyTrimCharacters() Assert.True(string.Empty.SequenceEqual(s1.Trim(chars)), "G: " + length); Assert.True(string.Empty.SequenceEqual(s1.TrimStart(chars)), "H: " + length); Assert.True(string.Empty.SequenceEqual(s1.TrimEnd(chars)), "I: " + length); + Assert.True(string.Empty.SequenceEqual(s1.Trim((ReadOnlySpan)chars)), "G: " + length); + Assert.True(string.Empty.SequenceEqual(s1.TrimStart((ReadOnlySpan)chars)), "H: " + length); + Assert.True(string.Empty.SequenceEqual(s1.TrimEnd((ReadOnlySpan)chars)), "I: " + length); ReadOnlySpan span = s1.AsSpan(); Assert.True(ReadOnlySpan.Empty.SequenceEqual(span.Trim(chars)), "G: " + length); @@ -6502,6 +6594,9 @@ public static void OnlyTrimCharacters() Assert.True(string.Empty.SequenceEqual(s2.Trim(trimCharsString)), "J"); Assert.True(string.Empty.SequenceEqual(s2.TrimStart(trimCharsString)), "K"); Assert.True(string.Empty.SequenceEqual(s2.TrimEnd(trimCharsString)), "L"); + Assert.True(string.Empty.SequenceEqual(s2.Trim((ReadOnlySpan)trimCharsString)), "J"); + Assert.True(string.Empty.SequenceEqual(s2.TrimStart((ReadOnlySpan)trimCharsString)), "K"); + Assert.True(string.Empty.SequenceEqual(s2.TrimEnd((ReadOnlySpan)trimCharsString)), "L"); ReadOnlySpan stringSpan = s2.AsSpan(); ReadOnlySpan trimChars = trimCharsString.AsSpan(); @@ -6526,6 +6621,9 @@ public static void TrimCharactersAtStart() Assert.True(s1.Substring(1).SequenceEqual(s1.Trim(chars)), "A: " + length); Assert.True(s1.Substring(1).SequenceEqual(s1.TrimStart(chars)), "B: " + length); Assert.True(s1.SequenceEqual(s1.TrimEnd(chars)), "C: " + length); + Assert.True(s1.Substring(1).SequenceEqual(s1.Trim((ReadOnlySpan)chars)), "A: " + length); + Assert.True(s1.Substring(1).SequenceEqual(s1.TrimStart((ReadOnlySpan)chars)), "B: " + length); + Assert.True(s1.SequenceEqual(s1.TrimEnd((ReadOnlySpan)chars)), "C: " + length); ReadOnlySpan span = s1.AsSpan(); Assert.True(span.Slice(1).SequenceEqual(span.Trim(chars)), "A: " + length); @@ -6538,6 +6636,9 @@ public static void TrimCharactersAtStart() Assert.True(s2.Substring(3).SequenceEqual(s2.Trim(trimCharsString)), "D"); Assert.True(s2.Substring(3).SequenceEqual(s2.TrimStart(trimCharsString)), "E"); Assert.True(s2.SequenceEqual(s2.TrimEnd(trimCharsString)), "F"); + Assert.True(s2.Substring(3).SequenceEqual(s2.Trim((ReadOnlySpan)trimCharsString)), "D"); + Assert.True(s2.Substring(3).SequenceEqual(s2.TrimStart((ReadOnlySpan)trimCharsString)), "E"); + Assert.True(s2.SequenceEqual(s2.TrimEnd((ReadOnlySpan)trimCharsString)), "F"); ReadOnlySpan stringSpan = s2.AsSpan(); ReadOnlySpan trimChars = trimCharsString.AsSpan(); @@ -6563,6 +6664,9 @@ public static void TrimCharactersAtEnd() Assert.True(s1.Substring(0, length - 1).SequenceEqual(s1.Trim(chars))); Assert.True(s1.SequenceEqual(s1.TrimStart(chars))); Assert.True(s1.Substring(0, length - 1).SequenceEqual(s1.TrimEnd(chars))); + Assert.True(s1.Substring(0, length - 1).SequenceEqual(s1.Trim((ReadOnlySpan)chars))); + Assert.True(s1.SequenceEqual(s1.TrimStart((ReadOnlySpan)chars))); + Assert.True(s1.Substring(0, length - 1).SequenceEqual(s1.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan span = new ReadOnlySpan(a); Assert.True(span.Slice(0, length - 1).SequenceEqual(span.Trim(chars))); @@ -6600,6 +6704,9 @@ public static void TrimCharactersAtStartAndEnd() Assert.True(s1.Substring(1, length - 2).SequenceEqual(s1.Trim(chars))); Assert.True(s1.Substring(1).SequenceEqual(s1.TrimStart(chars))); Assert.True(s1.Substring(0, length - 1).SequenceEqual(s1.TrimEnd(chars))); + Assert.True(s1.Substring(1, length - 2).SequenceEqual(s1.Trim((ReadOnlySpan)chars))); + Assert.True(s1.Substring(1).SequenceEqual(s1.TrimStart((ReadOnlySpan)chars))); + Assert.True(s1.Substring(0, length - 1).SequenceEqual(s1.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan span = s1.AsSpan(); Assert.True(span.Slice(1, length - 2).SequenceEqual(span.Trim(chars))); @@ -6608,13 +6715,15 @@ public static void TrimCharactersAtStartAndEnd() } string s2 = "ccedafffffbdaa"; - char[] trimCharsString = "abcde".ToCharArray(); - Assert.True(s2.Substring(5, 5).SequenceEqual(s2.Trim(trimCharsString))); - Assert.True(s2.Substring(5).SequenceEqual(s2.TrimStart(trimCharsString))); - Assert.True(s2.Substring(0, 10).SequenceEqual(s2.TrimEnd(trimCharsString))); + Assert.True(s2.Substring(5, 5).SequenceEqual(s2.Trim(chars))); + Assert.True(s2.Substring(5).SequenceEqual(s2.TrimStart(chars))); + Assert.True(s2.Substring(0, 10).SequenceEqual(s2.TrimEnd(chars))); + Assert.True(s2.Substring(5, 5).SequenceEqual(s2.Trim((ReadOnlySpan)chars))); + Assert.True(s2.Substring(5).SequenceEqual(s2.TrimStart((ReadOnlySpan)chars))); + Assert.True(s2.Substring(0, 10).SequenceEqual(s2.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan stringSpan = s2.AsSpan(); - ReadOnlySpan trimChars = trimCharsString.AsSpan(); + ReadOnlySpan trimChars = chars.AsSpan(); Assert.True(stringSpan.Slice(5, 5).SequenceEqual(stringSpan.Trim(trimChars))); Assert.True(stringSpan.Slice(5).SequenceEqual(stringSpan.TrimStart(trimChars))); Assert.True(stringSpan.Slice(0, 10).SequenceEqual(stringSpan.TrimEnd(trimChars))); @@ -6637,6 +6746,9 @@ public static void TrimCharactersInMiddle() Assert.True(s1.SequenceEqual(s1.Trim(chars))); Assert.True(s1.SequenceEqual(s1.TrimStart(chars))); Assert.True(s1.SequenceEqual(s1.TrimEnd(chars))); + Assert.True(s1.SequenceEqual(s1.Trim((ReadOnlySpan)chars))); + Assert.True(s1.SequenceEqual(s1.TrimStart((ReadOnlySpan)chars))); + Assert.True(s1.SequenceEqual(s1.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan span = s1.AsSpan(); Assert.True(span.SequenceEqual(span.Trim(chars))); @@ -6645,13 +6757,15 @@ public static void TrimCharactersInMiddle() } string s2 = "fabbacddeeddef"; - char[] trimCharsString = "abcde".ToCharArray(); - Assert.True(s2.SequenceEqual(s2.Trim(trimCharsString))); - Assert.True(s2.SequenceEqual(s2.TrimStart(trimCharsString))); - Assert.True(s2.SequenceEqual(s2.TrimEnd(trimCharsString))); + Assert.True(s2.SequenceEqual(s2.Trim(chars))); + Assert.True(s2.SequenceEqual(s2.TrimStart(chars))); + Assert.True(s2.SequenceEqual(s2.TrimEnd(chars))); + Assert.True(s2.SequenceEqual(s2.Trim((ReadOnlySpan)chars))); + Assert.True(s2.SequenceEqual(s2.TrimStart((ReadOnlySpan)chars))); + Assert.True(s2.SequenceEqual(s2.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan stringSpan = s2.AsSpan(); - ReadOnlySpan trimChars = trimCharsString.AsSpan(); + ReadOnlySpan trimChars = chars.AsSpan(); Assert.True(stringSpan.SequenceEqual(stringSpan.Trim(trimChars))); Assert.True(stringSpan.SequenceEqual(stringSpan.TrimStart(trimChars))); Assert.True(stringSpan.SequenceEqual(stringSpan.TrimEnd(trimChars))); @@ -6684,6 +6798,19 @@ public static void TrimCharactersMultipleTimes() Assert.True(trimStartResultString.SequenceEqual(trimStartResultString.TrimStart(chars))); Assert.True(trimEndResultString.SequenceEqual(trimEndResultString.TrimEnd(chars))); + s1 = new string(a); + trimResultString = s1.Trim((ReadOnlySpan)chars); + trimStartResultString = s1.TrimStart((ReadOnlySpan)chars); + trimEndResultString = s1.TrimEnd((ReadOnlySpan)chars); + Assert.True(s1.Substring(1, length - 2).SequenceEqual(trimResultString)); + Assert.True(s1.Substring(1).SequenceEqual(trimStartResultString)); + Assert.True(s1.Substring(0, length - 1).SequenceEqual(trimEndResultString)); + + // 2nd attempt should do nothing + Assert.True(trimResultString.SequenceEqual(trimResultString.Trim((ReadOnlySpan)chars))); + Assert.True(trimStartResultString.SequenceEqual(trimStartResultString.TrimStart((ReadOnlySpan)chars))); + Assert.True(trimEndResultString.SequenceEqual(trimEndResultString.TrimEnd((ReadOnlySpan)chars))); + ReadOnlySpan span = s1.AsSpan(); ReadOnlySpan trimResult = span.Trim(chars); ReadOnlySpan trimStartResult = span.TrimStart(chars); @@ -6699,21 +6826,33 @@ public static void TrimCharactersMultipleTimes() } string s2 = "ccedafffffbdaa"; - char[] trimCharsString = "abcde".ToCharArray(); - string trimStringResultString = s2.Trim(trimCharsString); - string trimStartStringResultString = s2.TrimStart(trimCharsString); - string trimEndStringResultString = s2.TrimEnd(trimCharsString); + string trimStringResultString = s2.Trim(chars); + string trimStartStringResultString = s2.TrimStart(chars); + string trimEndStringResultString = s2.TrimEnd(chars); + Assert.True(s2.Substring(5, 5).SequenceEqual(trimStringResultString)); + Assert.True(s2.Substring(5).SequenceEqual(trimStartStringResultString)); + Assert.True(s2.Substring(0, 10).SequenceEqual(trimEndStringResultString)); + + // 2nd attempt should do nothing + Assert.True(trimStringResultString.SequenceEqual(trimStringResultString.Trim(chars))); + Assert.True(trimStartStringResultString.SequenceEqual(trimStartStringResultString.TrimStart(chars))); + Assert.True(trimEndStringResultString.SequenceEqual(trimEndStringResultString.TrimEnd(chars))); + + s2 = "ccedafffffbdaa"; + trimStringResultString = s2.Trim((ReadOnlySpan)chars); + trimStartStringResultString = s2.TrimStart((ReadOnlySpan)chars); + trimEndStringResultString = s2.TrimEnd((ReadOnlySpan)chars); Assert.True(s2.Substring(5, 5).SequenceEqual(trimStringResultString)); Assert.True(s2.Substring(5).SequenceEqual(trimStartStringResultString)); Assert.True(s2.Substring(0, 10).SequenceEqual(trimEndStringResultString)); // 2nd attempt should do nothing - Assert.True(trimStringResultString.SequenceEqual(trimStringResultString.Trim(trimCharsString))); - Assert.True(trimStartStringResultString.SequenceEqual(trimStartStringResultString.TrimStart(trimCharsString))); - Assert.True(trimEndStringResultString.SequenceEqual(trimEndStringResultString.TrimEnd(trimCharsString))); + Assert.True(trimStringResultString.SequenceEqual(trimStringResultString.Trim((ReadOnlySpan)chars))); + Assert.True(trimStartStringResultString.SequenceEqual(trimStartStringResultString.TrimStart((ReadOnlySpan)chars))); + Assert.True(trimEndStringResultString.SequenceEqual(trimEndStringResultString.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan stringSpan = s2.AsSpan(); - ReadOnlySpan trimChars = trimCharsString.AsSpan(); + ReadOnlySpan trimChars = chars.AsSpan(); ReadOnlySpan trimStringResult = stringSpan.Trim(trimChars); ReadOnlySpan trimStartStringResult = stringSpan.TrimStart(trimChars); @@ -6739,27 +6878,31 @@ public static void MakeSureNoTrimCharactersChecksGoOutOfRange() first[length - 1] = 'f'; string s1 = new string(first, 1, length - 2); Assert.Equal(s1.ToArray().Length, s1.Trim(chars).ToArray().Length); - Assert.True(s1.SequenceEqual(s1.Trim(chars)), "A : " + s1.Length); - Assert.True(s1.SequenceEqual(s1.TrimStart(chars)), "B :" + s1.Length); - Assert.True(s1.SequenceEqual(s1.TrimEnd(chars))); + Assert.True(s1.SequenceEqual(s1.Trim(chars)), "A: " + s1.Length); + Assert.True(s1.SequenceEqual(s1.TrimStart(chars)), "B: " + s1.Length); + Assert.True(s1.SequenceEqual(s1.TrimEnd(chars)), "C: " + s1.Length); ReadOnlySpan span = s1.AsSpan(); Assert.Equal(span.ToArray().Length, span.Trim(chars).ToArray().Length); - Assert.True(span.SequenceEqual(span.Trim(chars)), "A : " + span.Length); - Assert.True(span.SequenceEqual(span.TrimStart(chars)), "B :" + span.Length); - Assert.True(span.SequenceEqual(span.TrimEnd(chars))); + Assert.True(span.SequenceEqual(span.Trim(chars)), "A: " + span.Length); + Assert.True(span.SequenceEqual(span.TrimStart(chars)), "B: " + span.Length); + Assert.True(span.SequenceEqual(span.TrimEnd(chars)), "C: " + s1.Length); } string testString = "afghijklmnopqrstfe"; string s2 = testString.Substring(1, testString.Length - 2); - char[] trimCharsString = "abcde".ToCharArray(); - Assert.True(s2.SequenceEqual(s2.Trim(trimCharsString))); - Assert.True(s2.SequenceEqual(s2.TrimStart(trimCharsString))); - Assert.True(s2.SequenceEqual(s2.TrimEnd(trimCharsString))); + Assert.True(s2.SequenceEqual(s2.Trim(chars))); + Assert.True(s2.SequenceEqual(s2.TrimStart(chars))); + Assert.True(s2.SequenceEqual(s2.TrimEnd(chars))); + + s2 = testString.Substring(1, testString.Length - 2); + Assert.True(s2.SequenceEqual(s2.Trim((ReadOnlySpan)chars))); + Assert.True(s2.SequenceEqual(s2.TrimStart((ReadOnlySpan)chars))); + Assert.True(s2.SequenceEqual(s2.TrimEnd((ReadOnlySpan)chars))); ReadOnlySpan stringSpan = s2.AsSpan(); - ReadOnlySpan trimChars = trimCharsString.AsSpan(); + ReadOnlySpan trimChars = chars.AsSpan(); Assert.True(stringSpan.SequenceEqual(stringSpan.Trim(trimChars))); Assert.True(stringSpan.SequenceEqual(stringSpan.TrimStart(trimChars))); Assert.True(stringSpan.SequenceEqual(stringSpan.TrimEnd(trimChars))); diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index c8d1737bea1307..7ccc19377a2efb 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -25,7 +25,7 @@ - + diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index b219e7cf41a913..5a3fff449e7bba 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -131,7 +131,7 @@ - + @@ -170,6 +170,7 @@ diff --git a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/IMemoryCache.cs b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/IMemoryCache.cs index ccce249b23d958..8388a9f0433eb1 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/IMemoryCache.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Abstractions/src/IMemoryCache.cs @@ -31,7 +31,7 @@ public interface IMemoryCache : IDisposable /// An object identifying the entry. void Remove(object key); -#if NET6_0_OR_GREATER +#if NET /// /// Gets a snapshot of the cache statistics if available. /// diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheGetCurrentStatisticsTests.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheGetCurrentStatisticsTests.cs index cee6245f3e9c6b..576b7e103aebae 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheGetCurrentStatisticsTests.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheGetCurrentStatisticsTests.cs @@ -106,7 +106,7 @@ public void GetCurrentStatistics_UpdateAfterExistingItemExpired_CurrentEstimated } } -#if NET6_0_OR_GREATER +#if NET [Fact] public void GetCurrentStatistics_DIMReturnsNull() { diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs index d8c5a8925b46b2..1dceb31a0cc8aa 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs @@ -15,6 +15,7 @@ private sealed partial class Emitter private readonly TypeIndex _typeIndex; private readonly bool _emitEnumParseMethod; private readonly bool _emitGenericParseEnum; + private readonly bool _emitNotNullIfNotNull; private readonly bool _emitThrowIfNullMethod; private readonly SourceWriter _writer = new(); @@ -26,6 +27,7 @@ public Emitter(SourceGenerationSpec sourceGenSpec) _typeIndex = new TypeIndex(sourceGenSpec.ConfigTypes); _emitEnumParseMethod = sourceGenSpec.EmitEnumParseMethod; _emitGenericParseEnum = sourceGenSpec.EmitGenericParseEnum; + _emitNotNullIfNotNull = sourceGenSpec.EmitNotNullIfNotNull; _emitThrowIfNullMethod = sourceGenSpec.EmitThrowIfNullMethod; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs index a569be384367eb..3d6e2b6503101a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs @@ -57,6 +57,7 @@ internal sealed partial class Parser(CompilationData compilationData) ConfigTypes = _createdTypeSpecs.Values.OrderBy(s => s.TypeRef.FullyQualifiedName).ToImmutableEquatableArray(), EmitEnumParseMethod = _emitEnumParseMethod, EmitGenericParseEnum = _emitGenericParseEnum, + EmitNotNullIfNotNull = _typeSymbols.NotNullIfNotNullAttribute is not null, EmitThrowIfNullMethod = IsThrowIfNullMethodToBeEmitted() }; } @@ -660,6 +661,12 @@ private ObjectSpec CreateObjectSpec(TypeParseInfo typeParseInfo) if (member is IPropertySymbol { IsIndexer: false, IsImplicitlyDeclared: false } property && !IsUnsupportedType(property.Type)) { string propertyName = property.Name; + + if (property.IsOverride || properties?.ContainsKey(propertyName) is true) + { + continue; + } + TypeRef propertyTypeRef = EnqueueTransitiveType(typeParseInfo, property.Type, DiagnosticDescriptors.PropertyNotSupported, propertyName); AttributeData? attributeData = property.GetAttributes().FirstOrDefault(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, _typeSymbols.ConfigurationKeyNameAttribute)); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs index c6f23779ec93d4..f49cabc8bfc0c5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs @@ -73,6 +73,7 @@ private void EmitGetValueMethods() if (ShouldEmitMethods(MethodsToGen.ConfigBinder_GetValue_T_key_defaultValue)) { EmitStartDefinition_Get_Or_GetValue_Overload(MethodsToGen.ConfigBinder_GetValue_T_key_defaultValue, documentation); + EmitNotNullIfNotNull(Identifier.defaultValue); _writer.WriteLine($"public static T? {Identifier.GetValue}(this {Identifier.IConfiguration} {Identifier.configuration}, string {Identifier.key}, T {Identifier.defaultValue}) => " + $"(T?)({expressionForGetValueCore}({Identifier.configuration}, typeof(T), {Identifier.key}) ?? {Identifier.defaultValue});"); } @@ -87,11 +88,20 @@ private void EmitGetValueMethods() if (ShouldEmitMethods(MethodsToGen.ConfigBinder_GetValue_TypeOf_key_defaultValue)) { EmitStartDefinition_Get_Or_GetValue_Overload(MethodsToGen.ConfigBinder_GetValue_TypeOf_key_defaultValue, documentation); + EmitNotNullIfNotNull(Identifier.defaultValue); _writer.WriteLine($"public static object? {Identifier.GetValue}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, string {Identifier.key}, object? {Identifier.defaultValue}) => " + $"{expressionForGetValueCore}({Identifier.configuration}, {Identifier.type}, {Identifier.key}) ?? {Identifier.defaultValue};"); } } + private void EmitNotNullIfNotNull(string parameterName) + { + if (_emitNotNullIfNotNull) + { + _writer.WriteLine($"[return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof({parameterName}))]"); + } + } + private void EmitBindMethods_ConfigurationBinder() { if (!ShouldEmitMethods(MethodsToGen.ConfigBinder_Bind)) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs index 89ff70db196b04..2f084ec7bdfce9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Parser/KnownTypeSymbols.cs @@ -64,6 +64,7 @@ internal sealed class KnownTypeSymbols public INamedTypeSymbol? MemberInfo { get; } public INamedTypeSymbol? ParameterInfo { get; } public INamedTypeSymbol? Delegate { get; } + public INamedTypeSymbol? NotNullIfNotNullAttribute { get; } public KnownTypeSymbols(CSharpCompilation compilation) { @@ -132,6 +133,9 @@ public KnownTypeSymbols(CSharpCompilation compilation) IntPtr = Compilation.GetSpecialType(SpecialType.System_IntPtr); UIntPtr = Compilation.GetSpecialType(SpecialType.System_UIntPtr); Delegate = Compilation.GetSpecialType(SpecialType.System_Delegate); + + // Only generate nullable attributes if available + NotNullIfNotNullAttribute = compilation.GetBestTypeByMetadataName("System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute"); } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs index c4fc5a6079ad99..e435ffa0cd0b23 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/SourceGenerationSpec.cs @@ -12,6 +12,7 @@ public sealed record SourceGenerationSpec public required ImmutableEquatableArray ConfigTypes { get; init; } public required bool EmitEnumParseMethod { get; set; } public required bool EmitGenericParseEnum { get; set; } + public required bool EmitNotNullIfNotNull { get; set; } public required bool EmitThrowIfNullMethod { get; set; } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs index 0f28d4f2fb9af8..c0ee592ed6b879 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/ref/Microsoft.Extensions.Configuration.Binder.cs @@ -32,10 +32,12 @@ public static void Bind(this Microsoft.Extensions.Configuration.IConfiguration c [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] public static object? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type type, string key) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] + [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] public static object? GetValue(this Microsoft.Extensions.Configuration.IConfiguration configuration, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type type, string key, object? defaultValue) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] public static T? GetValue<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] T>(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] + [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] public static T? GetValue<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] T>(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key, T defaultValue) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.")] diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs index c6783555ca4757..060d1f55d72a05 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs @@ -167,6 +167,7 @@ public static void Bind(this IConfiguration configuration, object? instance, Act /// The default value to use if no value is found. /// The converted value. [RequiresUnreferencedCode(TrimmingWarningMessage)] + [return: NotNullIfNotNull(nameof(defaultValue))] public static T? GetValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IConfiguration configuration, string key, T defaultValue) { return (T?)GetValue(configuration, typeof(T), key, defaultValue); @@ -198,6 +199,7 @@ public static void Bind(this IConfiguration configuration, object? instance, Act /// The default value to use if no value is found. /// The converted value. [RequiresUnreferencedCode(TrimmingWarningMessage)] + [return: NotNullIfNotNull(nameof(defaultValue))] public static object? GetValue( this IConfiguration configuration, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] @@ -950,7 +952,7 @@ private static bool TypeIsASetInterface(Type type) Type genericTypeDefinition = type.GetGenericTypeDefinition(); return genericTypeDefinition == typeof(ISet<>) -#if NETCOREAPP +#if NET || genericTypeDefinition == typeof(IReadOnlySet<>) #endif ; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Collections.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Collections.cs index 73afe160f28f2c..06b44553ab9fd5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Collections.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Collections.cs @@ -1532,7 +1532,7 @@ public void CanBindISetNoSetter() Assert.Equal("Yo2", options.ISetNoSetter.ElementAt(1)); } -#if NETCOREAPP +#if NET [Fact] public void CanBindInstantiatedIReadOnlySet() { @@ -2291,7 +2291,7 @@ public void TestOptionsWithDifferentCollectionInterfaces() Assert.True(3 == options.UnInstantiatedISet.Count(), $"UnInstantiatedISet count is {options.UnInstantiatedISet.Count()} .. {options.UnInstantiatedISet.ElementAt(options.UnInstantiatedISet.Count() - 1)}"); Assert.Equal(new string[] { "a", "A", "B" }, options.UnInstantiatedISet); -#if NETCOREAPP +#if NET Assert.True(3 == options.InstantiatedIReadOnlySet.Count(), $"InstantiatedIReadOnlySet count is {options.InstantiatedIReadOnlySet.Count()} .. {options.InstantiatedIReadOnlySet.ElementAt(options.InstantiatedIReadOnlySet.Count() - 1)}"); Assert.Equal(new string[] { "a", "b", "Z" }, options.InstantiatedIReadOnlySet); Assert.False(options.IsSameInstantiatedIReadOnlySet()); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs index d6521ed86dfdec..488e9b81c99d1f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.Helpers.cs @@ -109,7 +109,7 @@ public string ReadOnly public ISet UninstantiatedHashSetWithUnsupportedKey { get; set; } -#if NETCOREAPP +#if NET public IReadOnlySet InstantiatedIReadOnlySet { get; set; } = new HashSet(); public IReadOnlySet InstantiatedIReadOnlySetWithSomeValues { get; set; } = new HashSet(new[] { "existing1", "existing2" }); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.Collections.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.Collections.cs index c8f672eb7fdb75..30d1fc8dc5b8c0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.Collections.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.Collections.cs @@ -354,7 +354,7 @@ public class OptionsWithDifferentCollectionInterfaces public ISet InstantiatedISet { get; set; } = s_instantiatedISet; public bool IsSameInstantiatedISet() => object.ReferenceEquals(s_instantiatedISet, InstantiatedISet); -#if NETCOREAPP +#if NET private static IReadOnlySet s_instantiatedIReadOnlySet = new HashSet(StringComparer.OrdinalIgnoreCase) { "a", "A", "b" }; public IReadOnlySet InstantiatedIReadOnlySet { get; set; } = s_instantiatedIReadOnlySet; public bool IsSameInstantiatedIReadOnlySet() => object.ReferenceEquals(s_instantiatedIReadOnlySet, InstantiatedIReadOnlySet); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs index 9aad9566463aff..b7ef3cba018edb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs @@ -743,7 +743,7 @@ public record RecordWithPrimitives public Uri Prop25 { get; set; } public Version Prop26 { get; set; } public DayOfWeek Prop27 { get; set; } -#if NETCOREAPP +#if NET public Int128 Prop7 { get; set; } public Half Prop11 { get; set; } public UInt128 Prop12 { get; set; } @@ -930,5 +930,64 @@ public class SimplePoco public string B { get; set; } } + public class BaseForHiddenMembers + { + public string A { get; set; } + public string B { get; set; } + public TestSettingsEnum E {get; set;} + + public virtual string C { get => CBase; set => CBase = value; } + + public string CBase; + + public virtual string D { get; } + + public virtual string F { get => FBase; set => FBase = value; } + public string FBase; + + + public virtual int X { get => XBase; set => XBase = value; } + public int XBase; + } + + public enum TestSettingsEnum2 + { + // Note - the reflection binder will try to bind to every member + Option1 = TestSettingsEnum.Option1, + Option2 = TestSettingsEnum.Option2, + } + + public class IntermediateDerivedClass : BaseForHiddenMembers + { + public new virtual string D { get => DBase; set => DBase = value; } + public string DBase; + + public override string F { get => "IF"; } + + } + + public class DerivedClassWithHiddenMembers : IntermediateDerivedClass + { + public new string A { get; } = "ADerived"; + public new int B { get; set; } + public new TestSettingsEnum2 E + { + get => (TestSettingsEnum2)base.E; + set => base.E = (TestSettingsEnum)value; + } + + // only override get + public override string C { get => "DC"; } + + // override new only get + public override string D { get => "DD"; } + + // two overrides of only get + public override string F { get => "DF"; } + + // override only set + public override int X { set => base.X = value + 1; } + } + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index 7b0a8ca7e7e385..4986778a87ceeb 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -326,11 +326,15 @@ public void CanBindToObjectProperty() [Fact] public void GetNullValue() { - var dic = new Dictionary + #nullable enable + #pragma warning disable IDE0004 // Cast is redundant + + var dic = new Dictionary { {"Integer", null}, {"Boolean", null}, {"Nested:Integer", null}, + {"String", null}, {"Object", null } }; var configurationBuilder = new ConfigurationBuilder(); @@ -341,13 +345,16 @@ public void GetNullValue() Assert.False(config.GetValue("Boolean")); Assert.Equal(0, config.GetValue("Integer")); Assert.Equal(0, config.GetValue("Nested:Integer")); + Assert.Null(config.GetValue("String")); Assert.Null(config.GetValue("Object")); // Generic overloads with default value. - Assert.True(config.GetValue("Boolean", true)); - Assert.Equal(1, config.GetValue("Integer", 1)); - Assert.Equal(1, config.GetValue("Nested:Integer", 1)); - Assert.Equal(new NestedConfig(""), config.GetValue("Object", new NestedConfig(""))); + Assert.True((bool)config.GetValue("Boolean", true)); + Assert.Equal(1, (int)config.GetValue("Integer", 1)); + Assert.Equal(1, (int)config.GetValue("Nested:Integer", 1)); + // [NotNullIfNotNull] avoids CS8600: Converting possible null value to non-nullable type. + Assert.Equal("s", (string)config.GetValue("String", "s")); + Assert.Equal(new NestedConfig(""), (NestedConfig)config.GetValue("Object", new NestedConfig(""))); // Type overloads. Assert.Null(config.GetValue(typeof(bool), "Boolean")); @@ -356,16 +363,22 @@ public void GetNullValue() Assert.Null(config.GetValue(typeof(ComplexOptions), "Object")); // Type overloads with default value. + // [NotNullIfNotNull] avoids CS8605: Unboxing a possibly null value. Assert.True((bool)config.GetValue(typeof(bool), "Boolean", true)); Assert.Equal(1, (int)config.GetValue(typeof(int), "Integer", 1)); Assert.Equal(1, (int)config.GetValue(typeof(int), "Nested:Integer", 1)); - Assert.Equal(new NestedConfig(""), config.GetValue("Object", new NestedConfig(""))); + // [NotNullIfNotNull] avoids CS8600: Converting possible null value to non-nullable type. + Assert.Equal("s", (string)config.GetValue(typeof(string), "String", "s")); + Assert.Equal(new NestedConfig(""), (NestedConfig)config.GetValue("Object", new NestedConfig(""))); // GetSection tests. Assert.False(config.GetSection("Boolean").Get()); Assert.Equal(0, config.GetSection("Integer").Get()); Assert.Equal(0, config.GetSection("Nested:Integer").Get()); Assert.Null(config.GetSection("Object").Get()); + + #pragma warning restore IDE0004 + #nullable restore } [Fact] @@ -1958,7 +1971,7 @@ public void TypeWithPrimitives_Pass() #endif Assert.Equal(CultureInfo.GetCultureInfo("yo-NG"), obj.Prop17); -#if NETCOREAPP +#if NET data = @"{ ""Prop7"": 9, ""Prop11"": 65500, @@ -2133,10 +2146,10 @@ public void TraceSwitchTest() TraceSwitch ts = new(displayName: "TraceSwitch", description: "This switch is set via config."); ConfigurationBinder.Bind(config, "TraceSwitch", ts); Assert.Equal(TraceLevel.Info, ts.Level); -#if NETCOREAPP +#if NET // Value property is not publicly exposed in .NET Framework. Assert.Equal("Info", ts.Value); -#endif // NETCOREAPP +#endif // NET } #endif @@ -2471,5 +2484,67 @@ public MockConfigurationRoot(IList providers) : base(pro IConfigurationSection IConfiguration.GetSection(string key) => this[key] is null ? null : new ConfigurationSection(this, key); } + + [Fact] + public void CanBindToClassWithNewProperties() + { + /// the source generator will bind to the most derived property only. + /// the reflection binder will bind the same data to all properties (including hidden). + + var config = TestHelpers.GetConfigurationFromJsonString(""" + { + "A": "AVal", + "B": "5", + "C": "CVal", + "D": "DVal", + "E": "Option2", + "F": "FVal", + "X": "52" + } + """); + var obj = new DerivedClassWithHiddenMembers(); + + config.Bind(obj); + + BaseForHiddenMembers baseObj = obj; + IntermediateDerivedClass intermediateObj = obj; + + Assert.Equal("ADerived", obj.A); +#if BUILDING_SOURCE_GENERATOR_TESTS + // source generator will not set hidden property + Assert.Null(baseObj.A); +#else + // reflection binder will set hidden property + Assert.Equal("AVal", baseObj.A); +#endif + + Assert.Equal(5, obj.B); +#if BUILDING_SOURCE_GENERATOR_TESTS + // source generator will not set hidden property + Assert.Null(baseObj.B); +#else + // reflection binder will set hidden property + Assert.Equal("5", baseObj.B); +#endif + + Assert.Equal(TestSettingsEnum2.Option2, obj.E); + Assert.Equal(TestSettingsEnum.Option2, baseObj.E); + + Assert.Equal("DC", obj.C); + // The setter should still be called, even when only getter is overridden. + Assert.Equal("CVal", obj.CBase); + + // can hide a readonly property with r/w property + Assert.Null(baseObj.D); + Assert.Equal("DD", obj.D); + // The setter should still be called, even when only getter is overridden. + Assert.Equal("DVal", obj.DBase); + + Assert.Equal("DF", obj.F); + Assert.Equal("FVal", obj.FBase); + + Assert.Equal(53, obj.X); + Assert.Equal(53, obj.XBase); + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue.generated.txt index 67df05b508e896..72edaaf8c6fba6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue.generated.txt @@ -39,6 +39,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration /// Extracts the value with the specified key and converts it to the specified type. [InterceptsLocation(@"src-0.cs", 16, 24)] + [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] public static T? GetValue(this IConfiguration configuration, string key, T defaultValue) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? defaultValue); /// Extracts the value with the specified key and converts it to the specified type. @@ -47,6 +48,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration /// Extracts the value with the specified key and converts it to the specified type. [InterceptsLocation(@"src-0.cs", 17, 24)] + [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] public static object? GetValue(this IConfiguration configuration, Type type, string key, object? defaultValue) => BindingExtensions.GetValueCore(configuration, type, key) ?? defaultValue; #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt index b546b86ea1b9b6..c383398924de61 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_T_Key_DefaultValue.generated.txt @@ -35,6 +35,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IConfiguration extensions. /// Extracts the value with the specified key and converts it to the specified type. [InterceptsLocation(@"src-0.cs", 12, 20)] + [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] public static T? GetValue(this IConfiguration configuration, string key, T defaultValue) => (T?)(BindingExtensions.GetValueCore(configuration, typeof(T), key) ?? defaultValue); #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt index 772160a53bdd55..8371cd0b05ca1f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/GetValue_TypeOf_Key_DefaultValue.generated.txt @@ -35,6 +35,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration #region IConfiguration extensions. /// Extracts the value with the specified key and converts it to the specified type. [InterceptsLocation(@"src-0.cs", 11, 20)] + [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(defaultValue))] public static object? GetValue(this IConfiguration configuration, Type type, string key, object? defaultValue) => BindingExtensions.GetValueCore(configuration, type, key) ?? defaultValue; #endregion IConfiguration extensions. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs index 24285047fff900..e9dcad70de4f9d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.Helpers.cs @@ -106,7 +106,7 @@ private static async Task VerifyAgainstBaselineUsingF ExpectedDiagnostics expectedDiags = ExpectedDiagnostics.None) { string environmentSubFolder = -#if NETCOREAPP +#if NET "netcoreapp" #else "net462" @@ -138,7 +138,7 @@ private static async Task VerifyAgainstBaselineUsingF string source = string.Join(Environment.NewLine, lines).TrimEnd(Environment.NewLine.ToCharArray()) + Environment.NewLine; path = Path.Combine($"{repoRootDir}\\src\\libraries\\Microsoft.Extensions.Configuration.Binder\\tests\\SourceGenerationTests\\", path); -#if NETCOREAPP +#if NET await File.WriteAllTextAsync(path, source); #else File.WriteAllText(path, source); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj index eccbe7d759b411..c19f91354cba5a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Microsoft.Extensions.Configuration.Binder.SourceGeneration.Tests.csproj @@ -8,6 +8,9 @@ $(NoWarn);SYSLIB1103,SYSLIB1104 $(InterceptorsPreviewNamespaces);Microsoft.Extensions.Configuration.Binder.SourceGeneration true + + + true diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs index 77ac387d096077..f84c5c10eea771 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationExtensions.cs @@ -29,9 +29,6 @@ public static IConfigurationBuilder SetFileProvider(this IConfigurationBuilder b return builder; } - internal static IFileProvider? GetUserDefinedFileProvider(this IConfigurationBuilder builder) - => builder.Properties.TryGetValue(FileProviderKey, out object? provider) ? (IFileProvider)provider : null; - /// /// Gets the default to be used for file-based providers. /// @@ -41,7 +38,12 @@ public static IFileProvider GetFileProvider(this IConfigurationBuilder builder) { ThrowHelper.ThrowIfNull(builder); - return GetUserDefinedFileProvider(builder) ?? new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty); + if (builder.Properties.TryGetValue(FileProviderKey, out object? provider)) + { + return (IFileProvider)provider; + } + + return new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty); } /// diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs index c0d8c9f341278a..d226051b1ab838 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationProvider.cs @@ -162,11 +162,6 @@ private void HandleException(ExceptionDispatchInfo info) protected virtual void Dispose(bool disposing) { _changeTokenRegistration?.Dispose(); - - if (Source.OwnsFileProvider) - { - (Source.FileProvider as IDisposable)?.Dispose(); - } } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs index 60555b2c672558..d58c265f406a9a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.FileExtensions/src/FileConfigurationSource.cs @@ -18,11 +18,6 @@ public abstract class FileConfigurationSource : IConfigurationSource /// public IFileProvider? FileProvider { get; set; } - /// - /// Set to true when was not provided by user and can be safely disposed. - /// - internal bool OwnsFileProvider { get; private set; } - /// /// The path to the file. /// @@ -63,11 +58,6 @@ public abstract class FileConfigurationSource : IConfigurationSource /// The . public void EnsureDefaults(IConfigurationBuilder builder) { - if (FileProvider is null && builder.GetUserDefinedFileProvider() is null) - { - OwnsFileProvider = true; - } - FileProvider ??= builder.GetFileProvider(); OnLoadException ??= builder.GetFileLoadExceptionHandler(); } @@ -91,7 +81,6 @@ public void ResolveFileProvider() } if (Directory.Exists(directory)) { - OwnsFileProvider = true; FileProvider = new PhysicalFileProvider(directory); Path = pathToFile; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs index 4b08c918fb8981..08d59e30ea6ebc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/tests/JsonConfigurationTest.cs @@ -222,56 +222,26 @@ public void ThrowFormatExceptionWhenFileIsEmpty() Assert.Contains("Could not parse the JSON file.", exception.Message); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public void AddJsonFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User(bool disposeConfigRoot) + [Fact] + public void AddJsonFile_FileProvider_Is_Not_Disposed_When_SourcesGetReloaded() { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User)}.json"); + string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Is_Not_Disposed_When_SourcesGetReloaded)}.json"); File.WriteAllText(filePath, @"{ ""some"": ""value"" }"); - IConfigurationRoot config = new ConfigurationBuilder().AddJsonFile(filePath, optional: false).Build(); - JsonConfigurationProvider jsonConfigurationProvider = config.Providers.OfType().Single(); - - Assert.NotNull(jsonConfigurationProvider.Source.FileProvider); - PhysicalFileProvider fileProvider = (PhysicalFileProvider)jsonConfigurationProvider.Source.FileProvider; - Assert.False(GetIsDisposed(fileProvider)); - - if (disposeConfigRoot) - { - (config as IDisposable).Dispose(); // disposing ConfigurationRoot - } - else - { - jsonConfigurationProvider.Dispose(); // disposing JsonConfigurationProvider - } - - Assert.True(GetIsDisposed(fileProvider)); - } + IConfigurationBuilder builder = new ConfigurationManager(); - [Fact] - public void AddJsonFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User() - { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddJsonFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User)}.json"); - File.WriteAllText(filePath, @"{ ""some"": ""value"" }"); + builder.AddJsonFile(filePath, optional: false); - PhysicalFileProvider fileProvider = new(Path.GetDirectoryName(filePath)); - JsonConfigurationProvider configurationProvider = new(new JsonConfigurationSource() - { - Path = filePath, - FileProvider = fileProvider - }); - IConfigurationRoot config = new ConfigurationBuilder().AddJsonFile(configurationProvider.Source.FileProvider, filePath, optional: true, reloadOnChange: false).Build(); + FileConfigurationSource fileConfigurationSource = (FileConfigurationSource)builder.Sources.Last(); + PhysicalFileProvider fileProvider = (PhysicalFileProvider)fileConfigurationSource.FileProvider; Assert.False(GetIsDisposed(fileProvider)); - (config as IDisposable).Dispose(); // disposing ConfigurationRoot that does not own the provider - Assert.False(GetIsDisposed(fileProvider)); + builder.Properties.Add("simplest", "repro"); - configurationProvider.Dispose(); // disposing JsonConfigurationProvider that does not own the provider Assert.False(GetIsDisposed(fileProvider)); - fileProvider.Dispose(); // disposing PhysicalFileProvider itself + fileProvider.Dispose(); Assert.True(GetIsDisposed(fileProvider)); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs index d248d96d9d464f..4012d775afa5f2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/XmlConfigurationTest.cs @@ -3,13 +3,11 @@ using System; using System.IO; -using System.Linq; using System.Security.Cryptography; using System.Security.Cryptography.Xml; using System.Tests; using System.Xml; using Microsoft.Extensions.Configuration.Test; -using Microsoft.Extensions.FileProviders; using Xunit; namespace Microsoft.Extensions.Configuration.Xml.Test @@ -781,64 +779,5 @@ public void LoadKeyValuePairsFromValidEncryptedXml() Assert.Equal("AnotherTestConnectionString", xmlConfigSrc.Get("data.setting:inventory:connectionstring")); Assert.Equal("MySql", xmlConfigSrc.Get("Data.setting:Inventory:Provider")); } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void AddXmlFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User(bool disposeConfigRoot) - { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddXmlFile_FileProvider_Gets_Disposed_When_It_Was_Not_Created_By_The_User)}.xml"); - File.WriteAllText(filePath, @"Settings"); - - IConfigurationRoot config = new ConfigurationBuilder().AddXmlFile(filePath, optional: false).Build(); - XmlConfigurationProvider xmlConfigurationProvider = config.Providers.OfType().Single(); - - Assert.NotNull(xmlConfigurationProvider.Source.FileProvider); - PhysicalFileProvider fileProvider = (PhysicalFileProvider)xmlConfigurationProvider.Source.FileProvider; - Assert.False(GetIsDisposed(fileProvider)); - - if (disposeConfigRoot) - { - (config as IDisposable).Dispose(); // disposing ConfigurationRoot - } - else - { - xmlConfigurationProvider.Dispose(); // disposing XmlConfigurationProvider - } - - Assert.True(GetIsDisposed(fileProvider)); - } - - [Fact] - public void AddXmlFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User() - { - string filePath = Path.Combine(Path.GetTempPath(), $"{nameof(AddXmlFile_FileProvider_Is_Not_Disposed_When_It_Is_Owned_By_The_User)}.xml"); - File.WriteAllText(filePath, @"Settings"); - - PhysicalFileProvider fileProvider = new(Path.GetDirectoryName(filePath)); - XmlConfigurationProvider configurationProvider = new(new XmlConfigurationSource() - { - Path = filePath, - FileProvider = fileProvider - }); - IConfigurationRoot config = new ConfigurationBuilder().AddXmlFile(configurationProvider.Source.FileProvider, filePath, optional: true, reloadOnChange: false).Build(); - - Assert.False(GetIsDisposed(fileProvider)); - - (config as IDisposable).Dispose(); // disposing ConfigurationRoot that does not own the provider - Assert.False(GetIsDisposed(fileProvider)); - - configurationProvider.Dispose(); // disposing XmlConfigurationProvider - Assert.False(GetIsDisposed(fileProvider)); - - fileProvider.Dispose(); // disposing PhysicalFileProvider itself - Assert.True(GetIsDisposed(fileProvider)); - } - - private static bool GetIsDisposed(PhysicalFileProvider fileProvider) - { - System.Reflection.FieldInfo isDisposedField = typeof(PhysicalFileProvider).GetField("_disposed", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); - return (bool)isDisposedField.GetValue(fileProvider); - } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs index f00a9ab49f041d..274f4696dd94af 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationKeyComparer.cs @@ -69,7 +69,7 @@ static ReadOnlySpan SkipAheadOnDelimiter(ReadOnlySpan a) static int Compare(ReadOnlySpan a, ReadOnlySpan b) { -#if NETCOREAPP +#if NET bool aIsInt = int.TryParse(a, out int value1); bool bIsInt = int.TryParse(b, out int value2); #else diff --git a/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/DisposableFileSystem.cs b/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/DisposableFileSystem.cs index fffca558b0c74d..0c16295d5be547 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/DisposableFileSystem.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/DisposableFileSystem.cs @@ -14,7 +14,7 @@ public class DisposableFileSystem : IDisposable public DisposableFileSystem() { -#if NETCOREAPP +#if NET DirectoryInfo = Directory.CreateTempSubdirectory(); #else DirectoryInfo = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs index 0b8a0bacae59e6..6d8a30b6dd5d4e 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ActivatorUtilities.cs @@ -12,7 +12,7 @@ using System.Runtime.InteropServices; using Microsoft.Extensions.Internal; -#if NETCOREAPP +#if NET [assembly: System.Reflection.Metadata.MetadataUpdateHandler(typeof(Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ActivatorUtilitiesUpdateHandler))] #endif @@ -23,7 +23,7 @@ namespace Microsoft.Extensions.DependencyInjection /// public static class ActivatorUtilities { -#if NETCOREAPP +#if NET // Support caching of constructor metadata for the common case of types in non-collectible assemblies. private static readonly ConcurrentDictionary s_constructorInfos = new(); @@ -60,7 +60,7 @@ public static object CreateInstance( } ConstructorInfoEx[]? constructors; -#if NETCOREAPP +#if NET if (!s_constructorInfos.TryGetValue(instanceType, out constructors)) { constructors = GetOrAddConstructors(instanceType); @@ -135,7 +135,7 @@ public static object CreateInstance( if (bestLength < length) { bestLength = length; -#if NETCOREAPP +#if NET ctorArgs.CopyTo(bestCtorArgs); #else if (i == constructors.Length - 1) @@ -191,7 +191,7 @@ public static object CreateInstance( matcher.MapParameters(parameterMap, parameters); return matcher.CreateInstance(provider); -#if NETCOREAPP +#if NET int GetMaxArgCount() { int max = 0; @@ -222,7 +222,7 @@ static void InitializeCtorArgValues(ref object[] ctorArgs, int length) #endif } -#if NETCOREAPP +#if NET private static ConstructorInfoEx[] GetOrAddConstructors( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) { @@ -246,7 +246,7 @@ private static ConstructorInfoEx[] GetOrAddConstructors( s_collectibleConstructorInfos.Value.AddOrUpdate(type, value); return value; } -#endif // NETCOREAPP +#endif // NET private static ConstructorInfoEx[] CreateConstructorInfoExs( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) @@ -277,7 +277,7 @@ public static ObjectFactory CreateFactory( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes) { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP +#if NETSTANDARD2_1_OR_GREATER || NET if (!RuntimeFeature.IsDynamicCodeCompiled) { // Create a reflection-based factory when dynamic code is not compiled\jitted as would be the case with @@ -314,7 +314,7 @@ public static ObjectFactory CreateFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>( Type[] argumentTypes) { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP +#if NETSTANDARD2_1_OR_GREATER || NET if (!RuntimeFeature.IsDynamicCodeCompiled) { // See the comment above in the non-generic CreateFactory() for why we use 'IsDynamicCodeCompiled' here. @@ -437,7 +437,7 @@ private static BlockExpression BuildFactoryExpression( Expression.New(constructor, constructorArguments)); } -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP +#if NETSTANDARD2_1_OR_GREATER || NET [DoesNotReturn] private static void ThrowHelperArgumentNullExceptionServiceProvider() { @@ -451,7 +451,7 @@ private static ObjectFactory CreateFactoryReflection( FindApplicableConstructor(instanceType, argumentTypes, constructors: null, out ConstructorInfo constructor, out int?[] parameterMap); Type declaringType = constructor.DeclaringType!; -#if NETCOREAPP +#if NET ConstructorInvoker invoker = ConstructorInvoker.Create(constructor); ParameterInfo[] constructorParameters = constructor.GetParameters(); @@ -520,7 +520,7 @@ ObjectFactory InvokeCanonical() FactoryParameterContext[] parameters = GetFactoryParameterContext(); return (serviceProvider, arguments) => ReflectionFactoryCanonical(constructor, parameters, declaringType, serviceProvider, arguments); -#endif // NETCOREAPP +#endif // NET FactoryParameterContext[] GetFactoryParameterContext() { @@ -542,7 +542,7 @@ FactoryParameterContext[] GetFactoryParameterContext() return parameters; } } -#endif // NETSTANDARD2_1_OR_GREATER || NETCOREAPP +#endif // NETSTANDARD2_1_OR_GREATER || NET private readonly struct FactoryParameterContext { @@ -644,7 +644,7 @@ private static bool TryFindPreferredConstructor( if (constructors is null) { -#if NETCOREAPP +#if NET if (!s_constructorInfos.TryGetValue(instanceType, out constructors)) { constructors = GetOrAddConstructors(instanceType); @@ -725,7 +725,7 @@ private sealed class ConstructorInfoEx public readonly ParameterInfo[] Parameters; public readonly bool IsPreferred; private readonly object?[]? _parameterKeys; -#if NETCOREAPP +#if NET public ConstructorInvoker? _invoker; public ConstructorInvoker Invoker { @@ -801,7 +801,7 @@ private readonly ref struct ConstructorMatcher { private readonly ConstructorInfoEx _constructor; -#if NETCOREAPP +#if NET private readonly Span _parameterValues; public ConstructorMatcher(ConstructorInfoEx constructor, Span parameterValues) #else @@ -884,7 +884,7 @@ public object CreateInstance(IServiceProvider provider) } } -#if NETCOREAPP +#if NET return _constructor.Invoker.Invoke(_parameterValues.Slice(0, _constructor.Parameters.Length)); #else try @@ -922,7 +922,7 @@ private static void ThrowMarkedCtorDoesNotTakeAllProvidedArguments() throw new InvalidOperationException(SR.Format(SR.MarkedCtorMissingArgumentTypes, nameof(ActivatorUtilitiesConstructorAttribute))); } -#if NETCOREAPP // Use the faster ConstructorInvoker which also has alloc-free APIs when <= 4 parameters. +#if NET // Use the faster ConstructorInvoker which also has alloc-free APIs when <= 4 parameters. private static object ReflectionFactoryServiceOnlyFixed( ConstructorInvoker invoker, FactoryParameterContext[] parameters, @@ -1167,7 +1167,7 @@ private static void ThrowHelperNullReferenceException() { throw new NullReferenceException(); } -#elif NETSTANDARD2_1_OR_GREATER || NETCOREAPP +#elif NETSTANDARD2_1_OR_GREATER || NET private static object ReflectionFactoryCanonical( ConstructorInfo constructor, FactoryParameterContext[] parameters, @@ -1197,7 +1197,7 @@ private static object ReflectionFactoryCanonical( } #endif -#if NETCOREAPP +#if NET internal static class ActivatorUtilitiesUpdateHandler { public static void ClearCache(Type[]? _) diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs index 1144ff33a1c7b6..8e0d07c0b0acd4 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/tests/DI.Tests/ActivatorUtilitiesTests.cs @@ -8,7 +8,7 @@ using Xunit; using System.Runtime.CompilerServices; -#if NETCOREAPP +#if NET using System.Runtime.Loader; #endif @@ -332,7 +332,7 @@ public void CreateFactory_CreatesFactoryMethod_5Types_5Injected() [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_CreatesFactoryMethod_KeyedParams(bool useDynamicCode) @@ -363,7 +363,7 @@ public void CreateFactory_CreatesFactoryMethod_KeyedParams(bool useDynamicCode) [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_CreatesFactoryMethod_KeyedParams_5Types(bool useDynamicCode) @@ -396,7 +396,7 @@ public void CreateFactory_CreatesFactoryMethod_KeyedParams_5Types(bool useDynami [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_CreatesFactoryMethod_KeyedParams_1Injected(bool useDynamicCode) @@ -426,7 +426,7 @@ public void CreateFactory_CreatesFactoryMethod_KeyedParams_1Injected(bool useDyn [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool useDynamicCode) @@ -460,7 +460,7 @@ public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool useDynamicCod [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool useDynamicCode) @@ -483,7 +483,7 @@ public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool useDynamicCod [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool useDynamicCode) @@ -507,7 +507,7 @@ public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool us [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool useDynamicCode) @@ -531,7 +531,7 @@ public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool use [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool useDynamicCode) @@ -555,7 +555,7 @@ public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool useDy [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] -#if NETCOREAPP +#if NET [InlineData(false)] #endif public void CreateFactory_RemoteExecutor_NoParameters_Success(bool useDynamicCode) @@ -577,7 +577,7 @@ public void CreateFactory_RemoteExecutor_NoParameters_Success(bool useDynamicCod }, options); } -#if NETCOREAPP +#if NET [ActiveIssue("https://github.com/dotnet/runtime/issues/34072", TestRuntimes.Mono)] [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(true)] @@ -1008,7 +1008,7 @@ public ClassWithStringDefaultValue(string text = "DEFAULT") } } -#if NETCOREAPP +#if NET internal class MyLoadContext : AssemblyLoadContext { private MyLoadContext() : base(isCollectible: true) diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextPaths.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextPaths.cs index b5c6730eef3eec..298b704ac1c288 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextPaths.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextPaths.cs @@ -40,7 +40,7 @@ private static DependencyContextPaths GetCurrent() internal static DependencyContextPaths Create(string? depsFiles, string? sharedRuntime) { -#if NETCOREAPP +#if NET const char separator = ';'; #else // This method is only executed once at startup. No need to cache the char[]. diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/MockFileProvider.cs b/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/MockFileProvider.cs index c9ce31d6e276d5..eed6a5044e6aca 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/MockFileProvider.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Composite/tests/MockFileProvider.cs @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.FileProviders.Composite { public class MockFileProvider : IFileProvider { -#if NETCOREAPP +#if NET static MockFileProvider() { // Castle DynamicProxy hasn't been updated to ignore .net5 infrastructure attributes diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs index 6559d5d46c9fc1..4796d4a8b0a390 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs @@ -31,7 +31,7 @@ public static bool IsExcluded(FileSystemInfo fileSystemInfo, ExclusionFilters fi public static DateTime? GetFileLinkTargetLastWriteTimeUtc(string filePath) { -#if NETCOREAPP +#if NET var fileInfo = new FileInfo(filePath); if (fileInfo.Exists) { @@ -47,7 +47,7 @@ public static bool IsExcluded(FileSystemInfo fileSystemInfo, ExclusionFilters fi // If file is not a link, return null to inform the caller that file is not a link. public static DateTime? GetFileLinkTargetLastWriteTimeUtc(FileInfo fileInfo) { -#if NETCOREAPP +#if NET Debug.Assert(fileInfo.Exists); if (fileInfo.LinkTarget != null) { diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs index fb2306d56e9f9d..925df9892752b6 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs @@ -162,7 +162,7 @@ internal PhysicalFilesWatcher CreateFileWatcher() string root = PathUtils.EnsureTrailingSlash(Path.GetFullPath(Root)); FileSystemWatcher? watcher; -#if NETCOREAPP +#if NET // For browser/iOS/tvOS we will proactively fallback to polling since FileSystemWatcher is not supported. if (OperatingSystem.IsBrowser() || (OperatingSystem.IsIOS() && !OperatingSystem.IsMacCatalyst()) || OperatingSystem.IsTvOS()) { diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFilesWatcher.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFilesWatcher.cs index db0a767573a1e8..712a83a3ef2c6e 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFilesWatcher.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFilesWatcher.cs @@ -88,7 +88,7 @@ public PhysicalFilesWatcher( if (fileSystemWatcher != null) { -#if NETCOREAPP +#if NET if (OperatingSystem.IsBrowser() || (OperatingSystem.IsIOS() && !OperatingSystem.IsMacCatalyst()) || OperatingSystem.IsTvOS()) { throw new PlatformNotSupportedException(SR.Format(SR.FileSystemWatcher_PlatformNotSupported, typeof(FileSystemWatcher))); @@ -160,7 +160,7 @@ private IChangeToken GetOrAddChangeToken(string pattern) } IChangeToken changeToken; -#if NET5_0_OR_GREATER +#if NET bool isWildCard = pattern.Contains('*'); #else bool isWildCard = pattern.IndexOf('*') != -1; diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs index b213474c2bb823..5080120689d2ad 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs @@ -17,8 +17,8 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal public class MatcherContext { private readonly DirectoryInfoBase _root; - private readonly List _includePatternContexts; - private readonly List _excludePatternContexts; + private readonly IPatternContext[] _includePatternContexts; + private readonly IPatternContext[] _excludePatternContexts; private readonly List _files; private readonly HashSet _declaredLiteralFolderSegmentInString; @@ -39,8 +39,8 @@ public MatcherContext( _files = new List(); _comparisonType = comparison; - _includePatternContexts = includePatterns.Select(pattern => pattern.CreatePatternContextForInclude()).ToList(); - _excludePatternContexts = excludePatterns.Select(pattern => pattern.CreatePatternContextForExclude()).ToList(); + _includePatternContexts = includePatterns.Select(pattern => pattern.CreatePatternContextForInclude()).ToArray(); + _excludePatternContexts = excludePatterns.Select(pattern => pattern.CreatePatternContextForExclude()).ToArray(); _declaredLiteralFolderSegmentInString = new HashSet(StringComparisonHelper.GetStringComparer(comparison)); } @@ -67,10 +67,11 @@ private void Match(DirectoryInfoBase directory, string? parentRelativePath) } else { - IEnumerable candidates = directory.EnumerateFileSystemInfos().OfType(); - foreach (DirectoryInfoBase candidate in candidates) + IEnumerable candidates = directory.EnumerateFileSystemInfos(); + foreach (FileSystemInfoBase candidate in candidates) { - if (_declaredLiteralFolderSegmentInString.Contains(candidate.Name)) + if (candidate is DirectoryInfoBase && + _declaredLiteralFolderSegmentInString.Contains(candidate.Name)) { entities.Add(candidate); } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs index c400b6a665e90b..c7db2fc670345b 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections; using System.Collections.Generic; using System.IO; -using System.Linq; using Microsoft.Extensions.FileSystemGlobbing.Abstractions; namespace Microsoft.Extensions.FileSystemGlobbing @@ -51,9 +51,18 @@ public static void AddIncludePatterns(this Matcher matcher, params IEnumerableAbsolute file paths of all files matched. Empty enumerable if no files matched given patterns. public static IEnumerable GetResultsInFullPath(this Matcher matcher, string directoryPath) { - IEnumerable matches = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directoryPath))).Files; - string[] result = matches.Select(match => Path.GetFullPath(Path.Combine(directoryPath, match.Path))).ToArray(); + PatternMatchingResult patternMatchingResult = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directoryPath))); + if (!patternMatchingResult.HasMatches) + { + return Array.Empty(); + } + IEnumerable matches = patternMatchingResult.Files; + List result = matches is ICollection matchCollection ? new(matchCollection.Count) : new(); + foreach (FilePatternMatch match in matches) + { + result.Add(Path.GetFullPath(Path.Combine(directoryPath, match.Path))); + } return result; } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/TestUtility/DisposableFileSystem.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/TestUtility/DisposableFileSystem.cs index 50abfa57af42e3..1571b88402ec0b 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/TestUtility/DisposableFileSystem.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/TestUtility/DisposableFileSystem.cs @@ -10,7 +10,7 @@ public class DisposableFileSystem : IDisposable { public DisposableFileSystem() { -#if NETCOREAPP +#if NET DirectoryInfo = Directory.CreateTempSubdirectory(); #else DirectoryInfo = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); diff --git a/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/SystemdHelpers.cs b/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/SystemdHelpers.cs index c7887bc29b2302..53d382c5e7c913 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/SystemdHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.Systemd/src/SystemdHelpers.cs @@ -5,7 +5,7 @@ using System.Globalization; using System.IO; using System.Text; -#if !NETCOREAPP +#if !NET using System.Diagnostics; #endif @@ -37,7 +37,7 @@ private static bool GetIsSystemdService() // To support containerized systemd services, check if we're the main process (PID 1) // and if there are systemd environment variables defined for notifying the service // manager, or passing listen handles. -#if NETCOREAPP +#if NET int processId = Environment.ProcessId; #else int processId = Process.GetCurrentProcess().Id; diff --git a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs index 9de601ddebe7d5..05eed40ff6df48 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceHelpers.cs @@ -28,7 +28,7 @@ private static bool GetIsWindowsService() if ( #if NETFRAMEWORK Environment.OSVersion.Platform != PlatformID.Win32NT -#elif NET5_0_OR_GREATER +#elif NET !OperatingSystem.IsWindows() #else !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs b/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs index 7a965e0efc85f5..4a9806a2fcd787 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs @@ -190,11 +190,6 @@ internal static DiagnosticListener LogHostBuilding(HostApplicationBuilder hostAp return diagnosticListener; } -// Remove when https://github.com/dotnet/runtime/pull/78532 is merged and consumed by the used SDK. -#if NET7_0 - [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", - Justification = "DiagnosticSource is used here to pass objects in-memory to code using HostFactoryResolver. This won't require creating new generic types.")] -#endif [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "The values being passed into Write are being consumed by the application already.")] private static void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>( diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs index a0407b8c2ec7be..09274bad3a3cbb 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs @@ -275,7 +275,7 @@ internal static void AddDefaultServices(HostBuilderContext hostingContext, IServ services.AddLogging(logging => { bool isWindows = -#if NETCOREAPP +#if NET OperatingSystem.IsWindows(); #elif NETFRAMEWORK Environment.OSVersion.Platform == PlatformID.Win32NT; @@ -292,7 +292,7 @@ internal static void AddDefaultServices(HostBuilderContext hostingContext, IServ } logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); -#if NETCOREAPP +#if NET if (!OperatingSystem.IsBrowser()) #endif { diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs index d2167ae3697f82..f923221fdb7b6e 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs @@ -255,7 +255,7 @@ public void DisableDefaultIHostEnvironmentValues(CreateBuilderFunc createBuilder HostApplicationBuilder builder = createBuilder(); Assert.Equal(Environments.Production, builder.Environment.EnvironmentName); -#if NETCOREAPP +#if NET Assert.NotNull(builder.Environment.ApplicationName); #elif NETFRAMEWORK // Note GetEntryAssembly returns null for the net4x console test runner. @@ -270,7 +270,7 @@ public void DisableDefaultIHostEnvironmentValues(CreateBuilderFunc createBuilder var env = host.Services.GetRequiredService(); Assert.Equal(Environments.Production, env.EnvironmentName); -#if NETCOREAPP +#if NET Assert.NotNull(env.ApplicationName); #elif NETFRAMEWORK // Note GetEntryAssembly returns null for the net4x console test runner. @@ -382,7 +382,7 @@ public void DirectSettingsOverrideConfigurationSetting(CreateBuilderSettingsFunc private static string CreateTempSubdirectory() { -#if NETCOREAPP +#if NET DirectoryInfo directoryInfo = Directory.CreateTempSubdirectory(); #else DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs index 5d37dbd15ec333..da863fec653535 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostBuilderTests.cs @@ -174,7 +174,7 @@ public void DefaultIHostEnvironmentValues() { var env = hostContext.HostingEnvironment; Assert.Equal(Environments.Production, env.EnvironmentName); -#if NETCOREAPP +#if NET Assert.NotNull(env.ApplicationName); #elif NETFRAMEWORK // Note GetEntryAssembly returns null for the net4x console test runner. @@ -190,7 +190,7 @@ public void DefaultIHostEnvironmentValues() { var env = host.Services.GetRequiredService(); Assert.Equal(Environments.Production, env.EnvironmentName); -#if NETCOREAPP +#if NET Assert.NotNull(env.ApplicationName); #elif NETFRAMEWORK // Note GetEntryAssembly returns null for the net4x console test runner. diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/OptionsBuilderExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/OptionsBuilderExtensionsTests.cs index 74c2a1c0bfe92c..6a67cbcaa9508e 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/OptionsBuilderExtensionsTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/OptionsBuilderExtensionsTests.cs @@ -413,7 +413,7 @@ private static void ValidateFailure(Type type, OptionsValidationException e, int // Check for the error in any of the failures foreach (var error in errorsToMatch) { -#if NETCOREAPP +#if NET Assert.True(e.Failures.FirstOrDefault(predicate: f => f.Contains(error, StringComparison.CurrentCulture)) != null, "Did not find: " + error + " " + e.Failures.First()); #else Assert.True(e.Failures.FirstOrDefault(predicate: f => f.IndexOf(error, StringComparison.CurrentCulture) >= 0) != null, "Did not find: " + error + " " + e.Failures.First()); diff --git a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs index 51891e8ebcf754..8c791124208828 100644 --- a/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs +++ b/src/libraries/Microsoft.Extensions.Http/ref/Microsoft.Extensions.Http.cs @@ -28,7 +28,7 @@ public static partial class HttpClientBuilderExtensions public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder RedactLoggedHeaders(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Func shouldRedactHeaderValue) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder RemoveAllLoggers(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { throw null; } public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder SetHandlerLifetime(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.TimeSpan handlerLifetime) { throw null; } -#if NET5_0_OR_GREATER +#if NET [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static Microsoft.Extensions.DependencyInjection.IHttpClientBuilder UseSocketsHttpHandler(this Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder, System.Action? configureHandler = null) { throw null; } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] @@ -64,14 +64,14 @@ public partial interface IHttpClientBuilder string Name { get; } Microsoft.Extensions.DependencyInjection.IServiceCollection Services { get; } } -#if NET5_0_OR_GREATER +#if NET public partial interface ISocketsHttpHandlerBuilder { string Name { get; } Microsoft.Extensions.DependencyInjection.IServiceCollection Services { get; } } #endif -#if NET5_0_OR_GREATER +#if NET public static partial class SocketsHttpHandlerBuilderExtensions { [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] diff --git a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/DefaultSocketsHttpHandlerBuilder.cs b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/DefaultSocketsHttpHandlerBuilder.cs index 57b905c0f3e6e0..61986cedfbe1a3 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/DefaultSocketsHttpHandlerBuilder.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/DefaultSocketsHttpHandlerBuilder.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET5_0_OR_GREATER +#if NET namespace Microsoft.Extensions.DependencyInjection { internal sealed class DefaultSocketsHttpHandlerBuilder : ISocketsHttpHandlerBuilder diff --git a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs index a9adb32fc5d84c..758a989be3a8b2 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs @@ -265,7 +265,7 @@ public static IHttpClientBuilder ConfigureHttpMessageHandlerBuilder(this IHttpCl return builder; } -#if NET5_0_OR_GREATER +#if NET /// /// Adds or updates as a primary handler for a named . If provided, /// also adds a delegate that will be used to configure the primary . diff --git a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/ISocketsHttpHandlerBuilder.cs b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/ISocketsHttpHandlerBuilder.cs index d7509e009c9c47..75333f8d747c71 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/ISocketsHttpHandlerBuilder.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/ISocketsHttpHandlerBuilder.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET5_0_OR_GREATER +#if NET namespace Microsoft.Extensions.DependencyInjection { /// diff --git a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs index 0d56606b742bde..d3bb98c8a11620 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET5_0_OR_GREATER +#if NET using System; using System.Net; using System.Net.Http; diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpClientLoggerHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpClientLoggerHandler.cs index 087ec81fbb6cd9..a7aeebe8578f3e 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpClientLoggerHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpClientLoggerHandler.cs @@ -61,7 +61,7 @@ protected override async Task SendAsync(HttpRequestMessage } } -#if NET5_0_OR_GREATER +#if NET protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { ThrowHelper.ThrowIfNull(request); diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpHeadersLogValue.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpHeadersLogValue.cs index 802192c4a905c9..23b07adf7f503d 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpHeadersLogValue.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/HttpHeadersLogValue.cs @@ -103,7 +103,7 @@ public override string ToString() } else { -#if NETCOREAPP +#if NET builder.AppendJoin(", ", (IEnumerable)kvp.Value); builder.AppendLine(); #else diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs index 5056474e9ead2f..e592e7d236fbb4 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingHttpMessageHandler.cs @@ -62,7 +62,7 @@ async Task Core(HttpRequestMessage request, bool useAsync, var stopwatch = ValueStopwatch.StartNew(); HttpResponseMessage response = useAsync ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) -#if NET5_0_OR_GREATER +#if NET : base.Send(request, cancellationToken); #else : throw new NotImplementedException("Unreachable code"); @@ -78,7 +78,7 @@ async Task Core(HttpRequestMessage request, bool useAsync, protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => SendCoreAsync(request, useAsync: true, cancellationToken); -#if NET5_0_OR_GREATER +#if NET /// /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) diff --git a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs index e170acbfe83c80..1894a005f84a68 100644 --- a/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/src/Logging/LoggingScopeHttpMessageHandler.cs @@ -63,7 +63,7 @@ async Task Core(HttpRequestMessage request, bool useAsync, Log.RequestPipelineStart(_logger, request, shouldRedactHeaderValue); HttpResponseMessage response = useAsync ? await base.SendAsync(request, cancellationToken).ConfigureAwait(false) -#if NET5_0_OR_GREATER +#if NET : base.Send(request, cancellationToken); #else : throw new NotImplementedException("Unreachable code"); @@ -80,7 +80,7 @@ async Task Core(HttpRequestMessage request, bool useAsync, protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => SendCoreAsync(request, useAsync: true, cancellationToken); -#if NET5_0_OR_GREATER +#if NET /// /// Logs the request to and response from the sent . protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/HttpClientLoggerTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/HttpClientLoggerTest.cs index 6fb8e2dd8f7a98..039ba46b186251 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/HttpClientLoggerTest.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/HttpClientLoggerTest.cs @@ -156,7 +156,7 @@ private void AssertCounters(TestCountingLogger testLogger, int requestCount, boo } } -#if NET5_0_OR_GREATER +#if NET [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] [InlineData(false, false)] [InlineData(false, true)] @@ -588,7 +588,7 @@ private async Task SendAsyncCore(HttpRequestMessage request } else { -#if NET5_0_OR_GREATER +#if NET return base.Send(request, cancellationToken); #else throw new NotImplementedException("unreachable"); @@ -609,7 +609,7 @@ private async Task SendAsyncCore(HttpRequestMessage request protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => SendAsyncCore(request, async: true, cancellationToken); -#if NET5_0_OR_GREATER +#if NET protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) => SendAsyncCore(request, async: false, cancellationToken).GetAwaiter().GetResult(); #endif diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs index 8f6ca7a8c4e285..bdd204f709df39 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/LoggingUriOutputTests.cs @@ -91,7 +91,7 @@ public async Task LoggingScopeHttpMessageHandler_LogsAbsoluteUri() Assert.Equal("HTTP GET http://api.example.com/search?term=Western%20Australia", message.Scope.ToString()); } -#if NET5_0_OR_GREATER +#if NET [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] public void LoggingHttpMessageHandler_LogsAbsoluteUri_Sync() { diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/SocketsHttpHandlerConfigurationTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/SocketsHttpHandlerConfigurationTest.cs index 4473917ff728f0..059557a0784a70 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/SocketsHttpHandlerConfigurationTest.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/SocketsHttpHandlerConfigurationTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NET5_0_OR_GREATER +#if NET using System; using System.Collections.Generic; using System.Net; diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/TestMessageHandler.cs b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/TestMessageHandler.cs index 5cbb8eb168f302..6bf2050cbd15c5 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/TestMessageHandler.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/TestMessageHandler.cs @@ -26,7 +26,7 @@ protected override Task SendAsync(HttpRequestMessage reques return Task.FromResult(response); } -#if NET5_0_OR_GREATER +#if NET protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) => _responseFactory(request); #endif } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParsingLogConsole.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParsingLogConsole.cs index 8cab45f3ffc06b..563fcacac6dadf 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParsingLogConsole.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/AnsiParsingLogConsole.cs @@ -62,7 +62,7 @@ private void WriteToConsole(string message, int startIndex, int length, ConsoleC { ReadOnlySpan span = message.AsSpan(startIndex, length); var colorChanged = SetColor(background, foreground); -#if NETCOREAPP +#if NET _textWriter.Write(span); #else _textWriter.Write(span.ToString()); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs index 122556bbbe460c..3b613ac50e206a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/JsonConsoleFormatter.cs @@ -32,10 +32,16 @@ public override void Write(in LogEntry logEntry, IExternalScopeP { return; } - LogLevel logLevel = logEntry.LogLevel; - string category = logEntry.Category; - int eventId = logEntry.EventId.Id; - Exception? exception = logEntry.Exception; + + // We extract most of the work into a non-generic method to save code size. If this was left in the generic + // method, we'd get generic specialization for all TState parameters, but that's unnecessary. + WriteInternal(scopeProvider, textWriter, message, logEntry.LogLevel, logEntry.Category, logEntry.EventId.Id, logEntry.Exception, + logEntry.State != null, logEntry.State?.ToString(), logEntry.State as IReadOnlyCollection>); + } + + private void WriteInternal(IExternalScopeProvider? scopeProvider, TextWriter textWriter, string message, LogLevel logLevel, + string category, int eventId, Exception? exception, bool hasState, string? stateMessage, IReadOnlyCollection>? stateProperties) + { const int DefaultBufferSize = 1024; using (var output = new PooledByteBufferWriter(DefaultBufferSize)) { @@ -48,9 +54,9 @@ public override void Write(in LogEntry logEntry, IExternalScopeP DateTimeOffset dateTimeOffset = FormatterOptions.UseUtcTimestamp ? DateTimeOffset.UtcNow : DateTimeOffset.Now; writer.WriteString("Timestamp", dateTimeOffset.ToString(timestampFormat)); } - writer.WriteNumber(nameof(logEntry.EventId), eventId); - writer.WriteString(nameof(logEntry.LogLevel), GetLogLevelString(logLevel)); - writer.WriteString(nameof(logEntry.Category), category); + writer.WriteNumber(nameof(LogEntry.EventId), eventId); + writer.WriteString(nameof(LogEntry.LogLevel), GetLogLevelString(logLevel)); + writer.WriteString(nameof(LogEntry.Category), category); writer.WriteString("Message", message); if (exception != null) @@ -58,11 +64,11 @@ public override void Write(in LogEntry logEntry, IExternalScopeP writer.WriteString(nameof(Exception), exception.ToString()); } - if (logEntry.State != null) + if (hasState) { - writer.WriteStartObject(nameof(logEntry.State)); - writer.WriteString("Message", logEntry.State.ToString()); - if (logEntry.State is IReadOnlyCollection> stateProperties) + writer.WriteStartObject(nameof(LogEntry.State)); + writer.WriteString("Message", stateMessage); + if (stateProperties != null) { foreach (KeyValuePair item in stateProperties) { @@ -75,7 +81,7 @@ public override void Write(in LogEntry logEntry, IExternalScopeP writer.WriteEndObject(); writer.Flush(); } -#if NETCOREAPP +#if NET textWriter.Write(Encoding.UTF8.GetString(output.WrittenMemory.Span)); #else textWriter.Write(Encoding.UTF8.GetString(output.WrittenMemory.Span.ToArray())); @@ -139,7 +145,7 @@ private static void WriteItem(Utf8JsonWriter writer, KeyValuePair OperatingSystem.IsAndroid() || OperatingSystem.IsTvOS() || OperatingSystem.IsIOS(); // returns true on MacCatalyst @@ -51,7 +51,15 @@ public override void Write(in LogEntry logEntry, IExternalScopeP { return; } - LogLevel logLevel = logEntry.LogLevel; + + // We extract most of the work into a non-generic method to save code size. If this was left in the generic + // method, we'd get generic specialization for all TState parameters, but that's unnecessary. + WriteInternal(scopeProvider, textWriter, message, logEntry.LogLevel, logEntry.EventId.Id, logEntry.Exception, logEntry.Category); + } + + private void WriteInternal(IExternalScopeProvider? scopeProvider, TextWriter textWriter, string message, LogLevel logLevel, + int eventId, Exception? exception, string category) + { ConsoleColors logLevelColors = GetLogLevelConsoleColors(logLevel); string logLevelString = GetLogLevelString(logLevel); @@ -70,14 +78,8 @@ public override void Write(in LogEntry logEntry, IExternalScopeP { textWriter.WriteColoredMessage(logLevelString, logLevelColors.Background, logLevelColors.Foreground); } - CreateDefaultLogMessage(textWriter, logEntry, message, scopeProvider); - } - private void CreateDefaultLogMessage(TextWriter textWriter, in LogEntry logEntry, string message, IExternalScopeProvider? scopeProvider) - { bool singleLine = FormatterOptions.SingleLine; - int eventId = logEntry.EventId.Id; - Exception? exception = logEntry.Exception; // Example: // info: ConsoleApp.Program[10] @@ -85,10 +87,10 @@ private void CreateDefaultLogMessage(TextWriter textWriter, in LogEntry< // category and event id textWriter.Write(LoglevelPadding); - textWriter.Write(logEntry.Category); + textWriter.Write(category); textWriter.Write('['); -#if NETCOREAPP +#if NET Span span = stackalloc char[10]; if (eventId.TryFormat(span, out int charsWritten)) textWriter.Write(span.Slice(0, charsWritten)); diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs index 5c0626307db195..2d306fee1d0a4b 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/SystemdConsoleFormatter.cs @@ -41,10 +41,15 @@ public override void Write(in LogEntry logEntry, IExternalScopeP { return; } - LogLevel logLevel = logEntry.LogLevel; - string category = logEntry.Category; - int eventId = logEntry.EventId.Id; - Exception? exception = logEntry.Exception; + + // We extract most of the work into a non-generic method to save code size. If this was left in the generic + // method, we'd get generic specialization for all TState parameters, but that's unnecessary. + WriteInternal(scopeProvider, textWriter, message, logEntry.LogLevel, logEntry.Category, logEntry.EventId.Id, logEntry.Exception); + } + + private void WriteInternal(IExternalScopeProvider? scopeProvider, TextWriter textWriter, string message, LogLevel logLevel, string category, + int eventId, Exception? exception) + { // systemd reads messages from standard out line-by-line in a 'message' format. // newline characters are treated as message delimiters, so we must replace them. // Messages longer than the journal LineMax setting (default: 48KB) are cropped. diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs index 343036cca5b5ce..eb4f25eb34fc5d 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/tests/EventSourceLoggerTest.cs @@ -904,7 +904,7 @@ private static class EventTypes @"""FormattedMessage"":""Logger2 Event5 Critical bar 23 45") }, // Starting in netcoreapp3.0 Exception.ToString() puts a newline before inner exceptions -#if NETCOREAPP +#if NET { "E5JS", (e) => VerifySingleEvent(e, "Logger2", EventTypes.MessageJson, 5, null, LogLevel.Critical, @"""ArgumentsJson"":{""stringParam"":""bar"",""int1Param"":""23"",""int2Param"":""45""", @$"""ExceptionJson"":{{""TypeName"":""System.Exception"",""Message"":""oops"",""HResult"":""-2146233088"",""VerboseMessage"":""System.Exception: oops{EscapedNewline()} ---\u003E System.Exception: inner oops") }, diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs index 80d9e7ab1909a0..83dd9e8b619bff 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceLoggerProviderTest.cs @@ -66,7 +66,7 @@ public override void WriteLine(string message) } } } -#elif NETCOREAPP +#elif NET #else #error Target framework needs to be updated #endif diff --git a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs index 25bd315a8679b0..42c16ecd30bba7 100644 --- a/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs +++ b/src/libraries/Microsoft.Extensions.Logging/tests/Common/TraceSourceScopeTest.cs @@ -33,7 +33,7 @@ public static void DiagnosticsScope_PushesAndPops_LogicalOperationStack() Assert.Same(a, c); Assert.Same(state, b); } -#elif NETCOREAPP +#elif NET #else #error Target framework needs to be updated #endif diff --git a/src/libraries/Microsoft.Extensions.Options/src/UnnamedOptionsManager.cs b/src/libraries/Microsoft.Extensions.Options/src/UnnamedOptionsManager.cs index 27f6d6e92ac215..e6ce20b94d1871 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/UnnamedOptionsManager.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/UnnamedOptionsManager.cs @@ -11,7 +11,7 @@ internal sealed class UnnamedOptionsManager<[DynamicallyAccessedMembers(Options. where TOptions : class { private readonly IOptionsFactory _factory; - private volatile object? _syncObj; + private object? _syncObj; private volatile TOptions? _value; public UnnamedOptionsManager(IOptionsFactory factory) => _factory = factory; diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs index 618c751d281059..5a3479b42c3568 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGeneration.Unit.Tests/Main.cs @@ -56,11 +56,11 @@ public partial struct MyOptionsValidator : IValidateOptions Assert.Empty(diagnostics); _ = Assert.Single(generatedSources); -#if NETCOREAPP +#if NET string generatedSource = File.ReadAllText(@"Baselines/EmitterWithCustomValidator.netcore.g.cs"); #else string generatedSource = File.ReadAllText(@"Baselines/EmitterWithCustomValidator.netfx.g.cs"); -#endif // NETCOREAPP +#endif // NET Assert.Equal(generatedSource.Replace("\r\n", "\n"), generatedSources[0].SourceText.ToString().Replace("\r\n", "\n")); } @@ -1715,7 +1715,7 @@ private static CSharpCompilation CreateCompilationForOptionsSource(string assemb public async Task GeneratedAttributesTest(LanguageVersion languageVersion) { -#if NETCOREAPP +#if NET string lengthAttribute = $$""" [LengthAttribute(1, 3)] public string? P0 { get; set; } @@ -1728,7 +1728,7 @@ public async Task GeneratedAttributesTest(LanguageVersion languageVersion) """; #else string lengthAttribute = ""; -#endif //NETCOREAPP +#endif //NET string source = $$""" using System; @@ -1807,7 +1807,7 @@ public sealed partial class OptionsUsingGeneratedAttributesValidator : IValidate var diags = syntaxTree.GetDiagnostics().ToArray(); Assert.Empty(diags); -#if NETCOREAPP +#if NET string generatedSource = File.ReadAllText(languageVersion == LanguageVersion.CSharp10 ? @"Baselines/GeneratedAttributesTest.netcore.lang10.g.cs" : @"Baselines/GeneratedAttributesTest.netcore.lang11.g.cs"); #else string generatedSource = File.ReadAllText(languageVersion == LanguageVersion.CSharp10 ? @"Baselines/GeneratedAttributesTest.netfx.lang10.g.cs" : @"Baselines/GeneratedAttributesTest.netfx.lang11.g.cs"); @@ -1857,11 +1857,11 @@ public partial class MyOptionsValidator : IValidateOptions Assert.Empty(diagnostics); Assert.Single(generatedSources); -#if NETCOREAPP +#if NET string generatedSource = File.ReadAllText(@"Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netcore.g.cs"); #else string generatedSource = File.ReadAllText(@"Baselines/UsingInterfaceAsPropertyTypeForLengthAttributesTests.netfx.g.cs"); -#endif // NETCOREAPP +#endif // NET Assert.Equal(generatedSource.Replace("\r\n", "\n"), generatedSources[0].SourceText.ToString().Replace("\r\n", "\n")); } @@ -1907,11 +1907,11 @@ public sealed class EndPointsOptions var (diagnostics, src) = await RunGenerator(source); Assert.Empty(diagnostics); Assert.Single(src); -#if NETCOREAPP +#if NET string generatedSource = File.ReadAllText(@"Baselines/OptionsExtendingSystemClassTest.netcore.g.cs"); #else string generatedSource = File.ReadAllText(@"Baselines/OptionsExtendingSystemClassTest.netfx.g.cs"); -#endif // NETCOREAPP +#endif // NET Assert.Equal(generatedSource.Replace("\r\n", "\n"), src[0].SourceText.ToString().Replace("\r\n", "\n")); } } diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/EmitterTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/EmitterTests.cs index af91cab872c88f..1f54faf77d7fef 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/EmitterTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/EmitterTests.cs @@ -24,8 +24,8 @@ public async Task TestEmitter() #pragma warning disable RS1035 // To allow using the File IO APIs inside the analyzer test foreach (var file in Directory.GetFiles("TestClasses")) { -#if NETCOREAPP3_1_OR_GREATER - sources.Add("#define NETCOREAPP3_1_OR_GREATER\n" + File.ReadAllText(file)); +#if NET + sources.Add("#define NET\n" + File.ReadAllText(file)); #else sources.Add(File.ReadAllText(file)); #endif @@ -46,7 +46,7 @@ public async Task TestEmitter() Assert.Empty(d); _ = Assert.Single(r); -#if NETCOREAPP3_1_OR_GREATER +#if NET string baseline = File.ReadAllText(@"Baselines/NetCoreApp/Validators.g.cs"); #else string baseline = File.ReadAllText(@"Baselines/NetFX/Validators.g.cs"); diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs index 4f9770ce7a17ca..01519b780eba1e 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/OptionsValidationTests.cs @@ -186,7 +186,7 @@ public void RangeAttributeModelDoubleInvalid() [Fact] public void RangeAttributeModelDateValid() { -#if NETCOREAPP3_1_OR_GREATER +#if NET // Setting non-invariant culture to check that // attribute's "ParseLimitsInInvariantCulture" property // was set up correctly in the validator: diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/Utils.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/Utils.cs index 7412374f18a56f..eb6bf661490995 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/Utils.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/Generated/Utils.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NETCOREAPP3_1_OR_GREATER +#if NET using System.Linq; #endif using Microsoft.Extensions.Options; @@ -15,7 +15,7 @@ public static void VerifyValidateOptionsResult(ValidateOptionsResult vr, int exp { Assert.NotNull(vr); -#if NETCOREAPP3_1_OR_GREATER +#if NET var failures = vr.Failures!.ToArray(); #else var failures = vr.FailureMessage!.Split(';'); diff --git a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs index c245ebd783bdcf..bc76114ab62944 100644 --- a/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs +++ b/src/libraries/Microsoft.Extensions.Options/tests/SourceGenerationTests/TestClasses/Models.cs @@ -76,7 +76,7 @@ public class RangeAttributeModelDouble public class RangeAttributeModelDate { -#if NETCOREAPP3_1_OR_GREATER +#if NET [Range(typeof(DateTime), "1/2/2004", "3/4/2004", ParseLimitsInInvariantCulture = true)] #else [Range(typeof(DateTime), "1/2/2004", "3/4/2004")] diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/StringSegment.cs b/src/libraries/Microsoft.Extensions.Primitives/src/StringSegment.cs index c78527db921b5d..f91f2314439cae 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/StringSegment.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/src/StringSegment.cs @@ -271,7 +271,7 @@ public bool Equals(string? text, StringComparison comparisonType) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { -#if NETCOREAPP +#if NET return string.GetHashCode(AsSpan()); #elif (NETSTANDARD2_0 || NETFRAMEWORK) // This GetHashCode is expensive since it allocates on every call. diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/StringSegmentComparer.cs b/src/libraries/Microsoft.Extensions.Primitives/src/StringSegmentComparer.cs index 9942f7959f5bdf..f1c645483da8f4 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/StringSegmentComparer.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/src/StringSegmentComparer.cs @@ -61,7 +61,7 @@ public bool Equals(StringSegment x, StringSegment y) /// A hash code for a , suitable for use in hashing algorithms and data structures like a hash table. public int GetHashCode(StringSegment obj) { -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 return string.GetHashCode(obj.AsSpan(), Comparison); #else if (!obj.HasValue) diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs b/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs index 45cfea152227dc..591830f3bec384 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs @@ -219,7 +219,7 @@ static string GetJoinedStringValueFromArray(string?[] values) length += value.Length; } } -#if NETCOREAPP +#if NET // Create the new string return string.Create(length, values, (span, strings) => { int offset = 0; diff --git a/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs b/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs index 1fedc0ec5c6a1e..400d16af590bc6 100644 --- a/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs +++ b/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs @@ -66,8 +66,8 @@ public sealed partial class RegistryKey : MarshalByRefObject, IDisposable private const int MaxKeyLength = 255; private const int MaxValueLength = 16383; - private volatile SafeRegistryHandle _hkey; - private volatile string _keyName; + private SafeRegistryHandle _hkey; + private string _keyName; private readonly bool _remoteKey; private volatile StateFlags _state; private volatile RegistryKeyPermissionCheck _checkMode; diff --git a/src/libraries/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs b/src/libraries/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs index e83798d5d6e2c2..58f468d7c8fa97 100644 --- a/src/libraries/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs +++ b/src/libraries/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs @@ -865,7 +865,7 @@ protected override void GenerateArrayCreateExpression(CodeArrayCreateExpression string typeName = GetTypeOutput(e.CreateType); Output.Write(typeName); -#if NETCOREAPP +#if NET if (!typeName.Contains('(')) #else if (typeName.IndexOf('(') == -1) @@ -892,7 +892,7 @@ protected override void GenerateArrayCreateExpression(CodeArrayCreateExpression } else { -#if NETCOREAPP +#if NET Output.Write(typeName.AsSpan(0, index + 1)); #else Output.Write(typeName.Substring(0, index + 1)); @@ -917,7 +917,7 @@ protected override void GenerateArrayCreateExpression(CodeArrayCreateExpression } else { -#if NETCOREAPP +#if NET Output.Write(typeName.AsSpan(index + 1)); #else Output.Write(typeName.Substring(index + 1)); diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs index 7162c9358fdd3c..0fce53d4f8772d 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/TempFileCollectionTests.cs @@ -277,7 +277,7 @@ private static string TempDirectory() { if (s_tempDirectory == null) { -#if NETCOREAPP +#if NET string tempDirectory = Directory.CreateTempSubdirectory().FullName; #else string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs index 3c2f745f3c0c3c..8a6933a4039bf8 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs @@ -572,7 +572,7 @@ public static partial class ImmutableHashSet } [System.Runtime.CompilerServices.CollectionBuilderAttribute(typeof(System.Collections.Immutable.ImmutableHashSet), "Create")] -#if NETCOREAPP +#if NET public sealed partial class ImmutableHashSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.Immutable.IImmutableSet #else public sealed partial class ImmutableHashSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.ISet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.Immutable.IImmutableSet @@ -1073,7 +1073,7 @@ public static partial class ImmutableSortedSet } [System.Runtime.CompilerServices.CollectionBuilderAttribute(typeof(System.Collections.Immutable.ImmutableSortedSet), "Create")] -#if NETCOREAPP +#if NET public sealed partial class ImmutableSortedSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Immutable.IImmutableSet #else public sealed partial class ImmutableSortedSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.ISet, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Immutable.IImmutableSet diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/Constants.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/Constants.cs index 5371a0354aeac6..ed797f8fae7bba 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/Constants.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/Constants.cs @@ -61,19 +61,13 @@ public static bool IsKnownComparable() => typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTimeOffset) || typeof(T) == typeof(Guid) || -#if NETCOREAPP3_0_OR_GREATER +#if NET typeof(T) == typeof(Rune) || -#endif -#if NET5_0_OR_GREATER typeof(T) == typeof(Half) || typeof(T) == typeof(nint) || typeof(T) == typeof(nuint) || -#endif -#if NET6_0_OR_GREATER typeof(T) == typeof(DateOnly) || typeof(T) == typeof(TimeOnly) || -#endif -#if NET7_0_OR_GREATER typeof(T) == typeof(Int128) || typeof(T) == typeof(UInt128) || #endif diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenHashTable.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenHashTable.cs index afb4785147391f..2bda7b2c76e70a 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenHashTable.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenHashTable.cs @@ -159,7 +159,7 @@ private static int CalcNumBuckets(ReadOnlySpan hashCodes, bool hashCodesAre if (!hashCodesAreUnique) { codes = -#if NETCOREAPP2_0_OR_GREATER +#if NET new HashSet(hashCodes.Length); #else new HashSet(); diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs index 50bbdeb18aad64..79acea67bd100c 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs @@ -202,7 +202,7 @@ private static FrozenSet CreateFromSet(HashSet source) [DebuggerTypeProxy(typeof(ImmutableEnumerableDebuggerProxy<>))] [DebuggerDisplay("Count = {Count}")] public abstract class FrozenSet : ISet, -#if NET5_0_OR_GREATER +#if NET IReadOnlySet, #endif IReadOnlyCollection, ICollection diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/Hashing.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/Hashing.cs index 4db4d2f03d9e01..8e9a7db1dd3198 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/Hashing.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/Hashing.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; +using System.Diagnostics; using System.Numerics; using System.Runtime.InteropServices; @@ -76,6 +77,8 @@ public static unsafe int GetHashCodeOrdinal(ReadOnlySpan s) // useful if the string only contains ASCII characters public static unsafe int GetHashCodeOrdinalIgnoreCaseAscii(ReadOnlySpan s) { + Debug.Assert(KeyAnalyzer.IsAllAscii(s)); + // We "normalize to lowercase" every char by ORing with 0x20. This casts // a very wide net because it will change, e.g., '^' to '~'. But that should // be ok because we expect this to be very rare in practice. @@ -138,6 +141,9 @@ public static unsafe int GetHashCodeOrdinalIgnoreCaseAscii(ReadOnlySpan s) public static unsafe int GetHashCodeOrdinalIgnoreCase(ReadOnlySpan s) { +#if NET + return string.GetHashCode(s, StringComparison.OrdinalIgnoreCase); +#else int length = s.Length; char[]? rentedArray = null; @@ -145,7 +151,7 @@ public static unsafe int GetHashCodeOrdinalIgnoreCase(ReadOnlySpan s) stackalloc char[256] : (rentedArray = ArrayPool.Shared.Rent(length)); - length = s.ToUpperInvariant(scratch); // NOTE: this really should be the (non-existent) ToUpperOrdinal + length = s.ToUpperInvariant(scratch); // NOTE: this both allocates and really should be the (non-existent) ToUpperOrdinal int hash = GetHashCodeOrdinal(scratch.Slice(0, length)); if (rentedArray is not null) @@ -154,6 +160,7 @@ public static unsafe int GetHashCodeOrdinalIgnoreCase(ReadOnlySpan s) } return hash; +#endif } } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs index 9f6094edb97763..0793b3d12f7315 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs @@ -32,31 +32,40 @@ public static AnalysisResults Analyze( ReadOnlySpan uniqueStrings, bool ignoreCase, int minLength, int maxLength) { Debug.Assert(!uniqueStrings.IsEmpty); + bool allUniqueStringsAreConfirmedAscii = ignoreCase && AreAllAscii(uniqueStrings); // Try to pick a substring comparer. If we can't find a good substring comparer, fallback to a full string comparer. AnalysisResults results; - if (minLength == 0 || !TryUseSubstring(uniqueStrings, ignoreCase, minLength, maxLength, out results)) + if (minLength == 0 || !TryUseSubstring(uniqueStrings, allUniqueStringsAreConfirmedAscii, ignoreCase, minLength, maxLength, out results)) { - results = CreateAnalysisResults(uniqueStrings, ignoreCase, minLength, maxLength, 0, 0, static (s, _, _) => s.AsSpan()); + results = CreateAnalysisResults(uniqueStrings, allUniqueStringsAreConfirmedAscii, ignoreCase, minLength, maxLength, 0, 0, static (s, _, _) => s.AsSpan()); } return results; } /// Try to find the minimal unique substring index/length to use for comparisons. - private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool ignoreCase, int minLength, int maxLength, out AnalysisResults results) + private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool allUniqueStringsAreConfirmedAscii, bool ignoreCase, int minLength, int maxLength, out AnalysisResults results) { const int MaxSubstringLengthLimit = 8; // arbitrary small-ish limit... it's not worth the increase in algorithmic complexity to analyze longer substrings - int uniqueStringsLength = uniqueStrings.Length; // Sufficient uniqueness factor of 95% is good enough. // Instead of ensuring that 95% of data is good, we stop when we know that at least 5% is bad. - int acceptableNonUniqueCount = uniqueStringsLength / 20; + int acceptableNonUniqueCount = uniqueStrings.Length / 20; + + // If we're case-sensitive, we can just use a case-sensitive substring comparer, which is cheap. + // For case-insensitive / ignoreCase, we don't know which portion of the input strings we're going to care about. + // However, if all of the strings are entirely ASCII, we know that no portion of any will be non-ASCII and thus can + // use a comparer that only knows how to do ASCII-based ordinal casing, which is cheaper than full Unicode casing, + // in particular for GetHashCode. + SubstringComparer comparer = + !ignoreCase ? new JustifiedSubstringComparer() : + allUniqueStringsAreConfirmedAscii ? new JustifiedCaseInsensitiveAsciiSubstringComparer() : + new JustifiedCaseInsensitiveSubstringComparer(); - SubstringComparer comparer = ignoreCase ? new JustifiedCaseInsensitiveSubstringComparer() : new JustifiedSubstringComparer(); HashSet set = new HashSet( -#if NET6_0_OR_GREATER - uniqueStringsLength, +#if NET + uniqueStrings.Length, #endif comparer); @@ -77,7 +86,7 @@ private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool ign if (HasSufficientUniquenessFactor(set, uniqueStrings, acceptableNonUniqueCount)) { results = CreateAnalysisResults( - uniqueStrings, ignoreCase, minLength, maxLength, index, count, + uniqueStrings, allUniqueStringsAreConfirmedAscii, ignoreCase, minLength, maxLength, index, count, static (string s, int index, int count) => s.AsSpan(index, count)); return true; } @@ -101,7 +110,7 @@ private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool ign if (HasSufficientUniquenessFactor(set, uniqueStrings, acceptableNonUniqueCount)) { results = CreateAnalysisResults( - uniqueStrings, ignoreCase, minLength, maxLength, comparer.Index, count, + uniqueStrings, allUniqueStringsAreConfirmedAscii, ignoreCase, minLength, maxLength, comparer.Index, count, static (string s, int index, int count) => s.AsSpan(s.Length + index, count)); return true; } @@ -115,7 +124,7 @@ private static bool TryUseSubstring(ReadOnlySpan uniqueStrings, bool ign } private static AnalysisResults CreateAnalysisResults( - ReadOnlySpan uniqueStrings, bool ignoreCase, int minLength, int maxLength, int index, int count, GetSpan getHashString) + ReadOnlySpan uniqueStrings, bool allUniqueStringsAreConfirmedAscii, bool ignoreCase, int minLength, int maxLength, int index, int count, GetSpan getHashString) { // Start off by assuming all strings are ASCII bool allAsciiIfIgnoreCase = true; @@ -134,10 +143,9 @@ private static AnalysisResults CreateAnalysisResults( foreach (string uniqueString in uniqueStrings) { // Get a span representing the slice of the uniqueString which will be hashed. - ReadOnlySpan hashString = getHashString(uniqueString, index, count); - // If the slice isn't ASCII, bail out to return the results. - if (!IsAllAscii(hashString)) + if (!allUniqueStringsAreConfirmedAscii && + !IsAllAscii(getHashString(uniqueString, index, count))) { allAsciiIfIgnoreCase = false; canSwitchIgnoreCaseHashToCaseSensitive = false; @@ -153,13 +161,14 @@ private static AnalysisResults CreateAnalysisResults( // and as we have just checked that IsAllAscii(hashString) is true // then we know IsAllAscii(uniqueString) must be true, // so we can skip the check. - if (count > 0 && !IsAllAscii(uniqueString.AsSpan())) - { - canSwitchIgnoreCaseHashToCaseSensitive = false; - } - else if (ContainsAnyAsciiLetters(uniqueString.AsSpan())) + if ((count > 0 && !allUniqueStringsAreConfirmedAscii && !IsAllAscii(uniqueString.AsSpan())) || + ContainsAnyAsciiLetters(uniqueString.AsSpan())) { canSwitchIgnoreCaseHashToCaseSensitive = false; + if (allUniqueStringsAreConfirmedAscii) + { + break; + } } } } @@ -177,6 +186,19 @@ private static AnalysisResults CreateAnalysisResults( private delegate ReadOnlySpan GetSpan(string s, int index, int count); + private static bool AreAllAscii(ReadOnlySpan strings) + { + foreach (string s in strings) + { + if (!IsAllAscii(s.AsSpan())) + { + return false; + } + } + + return true; + } + internal static unsafe bool IsAllAscii(ReadOnlySpan s) { #if NET8_0_OR_GREATER @@ -296,5 +318,11 @@ private sealed class JustifiedCaseInsensitiveSubstringComparer : SubstringCompar public override bool Equals(string? x, string? y) => x.AsSpan(IsLeft ? Index : (x!.Length + Index), Count).Equals(y.AsSpan(IsLeft ? Index : (y!.Length + Index), Count), StringComparison.OrdinalIgnoreCase); public override int GetHashCode(string s) => Hashing.GetHashCodeOrdinalIgnoreCase(s.AsSpan(IsLeft ? Index : (s.Length + Index), Count)); } + + private sealed class JustifiedCaseInsensitiveAsciiSubstringComparer : SubstringComparer + { + public override bool Equals(string? x, string? y) => x.AsSpan(IsLeft ? Index : (x!.Length + Index), Count).Equals(y.AsSpan(IsLeft ? Index : (y!.Length + Index), Count), StringComparison.OrdinalIgnoreCase); + public override int GetHashCode(string s) => Hashing.GetHashCodeOrdinalIgnoreCaseAscii(s.AsSpan(IsLeft ? Index : (s.Length + Index), Count)); + } } } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs index 97659c5479365c..626b21a8bf1212 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs @@ -28,7 +28,7 @@ internal static class LengthBuckets } int arraySize = spread * MaxPerLength; -#if NET6_0_OR_GREATER +#if NET if (arraySize > Array.MaxLength) #else if (arraySize > 0X7FFFFFC7) @@ -87,7 +87,7 @@ internal static class LengthBuckets return null; } -#if NET6_0_OR_GREATER +#if NET // We don't need an array with every value initialized to zero if we are just about to overwrite every value anyway. int[] copy = GC.AllocateUninitializedArray(arraySize); Array.Copy(buckets, copy, arraySize); diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs index ad22b0bbab6952..1f1b1be4c5bf37 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/AllocFreeConcurrentStack.cs @@ -10,7 +10,7 @@ internal static class AllocFreeConcurrentStack { private const int MaxSize = 35; -#if NETCOREAPP +#if NET [ThreadStatic] private static Stack>? t_stack; #else @@ -20,7 +20,7 @@ internal static class AllocFreeConcurrentStack public static void TryAdd(T item) { Stack> localStack = -#if NETCOREAPP +#if NET t_stack ??= new Stack>(MaxSize); #else ThreadLocalStack; @@ -36,7 +36,7 @@ public static void TryAdd(T item) public static bool TryTake([MaybeNullWhen(false)] out T item) { -#if NETCOREAPP +#if NET Stack>? localStack = t_stack; // cache in a local to avoid unnecessary TLS hits on repeated accesses #else Stack> localStack = ThreadLocalStack; @@ -51,7 +51,7 @@ public static bool TryTake([MaybeNullWhen(false)] out T item) return false; } -#if !NETCOREAPP +#if !NET private static Stack> ThreadLocalStack { get @@ -73,7 +73,7 @@ private static Stack> ThreadLocalStack #endif } -#if !NETCOREAPP +#if !NET internal static class AllocFreeConcurrentStack { // Workaround for https://github.com/dotnet/runtime/issues/4731. diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray.cs index f2743d3f16f8c9..aafe4316eb7503 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray.cs @@ -87,7 +87,7 @@ public static ImmutableArray Create(T item1, T item2, T item3, T item4) /// The type of element stored in the array. /// The elements to store in the array. /// An immutable array containing the specified items. - public static ImmutableArray Create(ReadOnlySpan items) + public static ImmutableArray Create(/*params*/ ReadOnlySpan items) { if (items.IsEmpty) { diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs index 8af78d72a063e0..459a3889d30af8 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs @@ -430,7 +430,7 @@ public void AddRange(ImmutableArray items, int length) /// Adds the specified items to the end of the array. /// /// The items to add at the end of the array. - public void AddRange(ReadOnlySpan items) + public void AddRange(/*params*/ ReadOnlySpan items) { int offset = this.Count; this.Count += items.Length; @@ -443,7 +443,7 @@ public void AddRange(ReadOnlySpan items) /// /// The type that derives from the type of item already in the array. /// The items to add at the end of the array. - public void AddRange(ReadOnlySpan items) where TDerived : T + public void AddRange(/*params*/ ReadOnlySpan items) where TDerived : T { int offset = this.Count; this.Count += items.Length; @@ -589,7 +589,7 @@ public void RemoveRange(int index, int length) if (index + length < this._count) { -#if NET6_0_OR_GREATER +#if NET if (RuntimeHelpers.IsReferenceOrContainsReferences()) { Array.Clear(_elements, index, length); // Clear the elements so that the gc can reclaim the references. @@ -919,7 +919,7 @@ public int LastIndexOf(T item, int startIndex, int count, IEqualityComparer? /// public void Reverse() { -#if NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER Array.Reverse(_elements, 0, _count); #else // The non-generic Array.Reverse is not used because it does not perform @@ -963,7 +963,7 @@ public void Sort(Comparison comparison) if (Count > 1) { -#if NET6_0_OR_GREATER +#if NET // MemoryExtensions.Sort is not available in .NET Framework / Standard 2.0. // But the overload with a Comparison argument doesn't allocate. _elements.AsSpan(0, _count).Sort(comparison); diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs index 2d203d015b828a..04e05477e0ff7c 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs @@ -880,7 +880,7 @@ public IEnumerable OfType() /// /// The values to add. /// A new list with the elements added. - public ImmutableArray AddRange(ReadOnlySpan items) + public ImmutableArray AddRange(/*params*/ ReadOnlySpan items) { ImmutableArray self = this; return self.InsertRange(self.Length, items); @@ -949,7 +949,7 @@ public ImmutableArray InsertRange(int index, T[] items) /// The index at which to insert the value. /// The elements to insert. /// The new immutable collection. - public ImmutableArray InsertRange(int index, ReadOnlySpan items) + public ImmutableArray InsertRange(int index, /*params*/ ReadOnlySpan items) { ImmutableArray self = this; self.ThrowNullRefIfNotInitialized(); diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs index 823c5e04cd279d..8d941eb0bcec12 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs @@ -16,7 +16,7 @@ internal static partial class ImmutableExtensions { internal static bool IsValueType() { -#if NETCOREAPP +#if NET return typeof(T).IsValueType; #else if (default(T) != null) diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet.cs index 9630bb33b5c0fe..13742785d7d81e 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet.cs @@ -98,7 +98,7 @@ public static ImmutableHashSet Create(params T[] items) /// The type of items stored by the collection. /// The items to prepopulate. /// The new immutable collection. - public static ImmutableHashSet Create(ReadOnlySpan items) + public static ImmutableHashSet Create(/*params*/ ReadOnlySpan items) { return ImmutableHashSet.Empty.Union(items); } @@ -124,7 +124,7 @@ public static ImmutableHashSet Create(IEqualityComparer? equalityCompar /// The equality comparer. /// The items to prepopulate. /// The new immutable collection. - public static ImmutableHashSet Create(IEqualityComparer? equalityComparer, ReadOnlySpan items) + public static ImmutableHashSet Create(IEqualityComparer? equalityComparer, /*params*/ ReadOnlySpan items) { return ImmutableHashSet.Empty.WithComparer(equalityComparer).Union(items); } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet_1.cs index b2e073484bb4ad..2ff4b68d19af36 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableHashSet_1.cs @@ -15,7 +15,7 @@ namespace System.Collections.Immutable [CollectionBuilder(typeof(ImmutableHashSet), nameof(ImmutableHashSet.Create))] [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy(typeof(ImmutableEnumerableDebuggerProxy<>))] -#if NETCOREAPP +#if NET public sealed partial class ImmutableHashSet : IImmutableSet, IHashKeyCollection, IReadOnlyCollection, ICollection, ISet, IReadOnlySet, ICollection, IStrongEnumerable.Enumerator> #else public sealed partial class ImmutableHashSet : IImmutableSet, IHashKeyCollection, IReadOnlyCollection, ICollection, ISet, ICollection, IStrongEnumerable.Enumerator> diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList.cs index f3004e3fd0199f..977686b880cc8c 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList.cs @@ -52,7 +52,7 @@ public static ImmutableList Create(params T[] items) /// The type of items stored by the collection. /// A span that contains the items to prepopulate the list with. /// A new immutable list that contains the specified items. - public static ImmutableList Create(ReadOnlySpan items) => ImmutableList.Empty.AddRange(items); + public static ImmutableList Create(/*params*/ ReadOnlySpan items) => ImmutableList.Empty.AddRange(items); /// /// Creates a new immutable list builder. diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableQueue.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableQueue.cs index 122bae100534f0..d2f5d142bbf869 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableQueue.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableQueue.cs @@ -83,7 +83,7 @@ public static ImmutableQueue Create(params T[] items) /// The type of items in the immutable queue. /// A span that contains the items to prepopulate the queue with. /// A new immutable queue that contains the specified items. - public static ImmutableQueue Create(ReadOnlySpan items) + public static ImmutableQueue Create(/*params*/ ReadOnlySpan items) { if (items.IsEmpty) { diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet.cs index 567997ed0472aa..ae5493ff083213 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet.cs @@ -97,7 +97,7 @@ public static ImmutableSortedSet Create(params T[] items) /// The type of items in the immutable set. /// A span that contains the items to prepopulate the set with. /// A new immutable set that contains the specified items. - public static ImmutableSortedSet Create(ReadOnlySpan items) + public static ImmutableSortedSet Create(/*params*/ ReadOnlySpan items) { return ImmutableSortedSet.Empty.Union(items); } @@ -123,7 +123,7 @@ public static ImmutableSortedSet Create(IComparer? comparer, params T[] /// The comparer. /// The items to prepopulate. /// The new immutable collection. - public static ImmutableSortedSet Create(IComparer? comparer, ReadOnlySpan items) + public static ImmutableSortedSet Create(IComparer? comparer, /*params*/ ReadOnlySpan items) { return ImmutableSortedSet.Empty.WithComparer(comparer).Union(items); } diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs index 2befd4a7c1307d..ee1d369c6ea144 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs @@ -20,7 +20,7 @@ namespace System.Collections.Immutable [CollectionBuilder(typeof(ImmutableSortedSet), nameof(ImmutableSortedSet.Create))] [DebuggerDisplay("Count = {Count}")] [DebuggerTypeProxy(typeof(ImmutableEnumerableDebuggerProxy<>))] -#if NETCOREAPP +#if NET public sealed partial class ImmutableSortedSet : IImmutableSet, ISortKeyCollection, IReadOnlySet, IReadOnlyList, IList, ISet, IList, IStrongEnumerable.Enumerator> #else public sealed partial class ImmutableSortedSet : IImmutableSet, ISortKeyCollection, IReadOnlyList, IList, ISet, IList, IStrongEnumerable.Enumerator> diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack.cs index 4e11bb76888077..f964f55c79908c 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableStack.cs @@ -70,7 +70,7 @@ public static ImmutableStack Create(params T[] items) /// The type of items in the immutable stack. /// A span that contains the items to prepopulate the stack with. /// A new immutable stack that contains the specified items. - public static ImmutableStack Create(ReadOnlySpan items) + public static ImmutableStack Create(/*params*/ ReadOnlySpan items) { ImmutableStack stack = ImmutableStack.Empty; foreach (T item in items) diff --git a/src/libraries/System.Collections.Immutable/src/System/Polyfills.cs b/src/libraries/System.Collections.Immutable/src/System/Polyfills.cs index 77f304f46fdcd8..eeb82f0960ccc4 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Polyfills.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Polyfills.cs @@ -6,7 +6,7 @@ namespace System.Collections.Generic { -#if !NETCOREAPP2_0_OR_GREATER +#if !NET internal static class KeyValuePairExtensions { [EditorBrowsable(EditorBrowsableState.Never)] @@ -18,7 +18,7 @@ public static void Deconstruct(this KeyValuePair sou } #endif -#if !NET5_0_OR_GREATER +#if !NET internal interface IReadOnlySet : IReadOnlyCollection { bool Contains(T item); @@ -34,7 +34,7 @@ internal interface IReadOnlySet : IReadOnlyCollection namespace System.Numerics { -#if !NETCOREAPP3_0_OR_GREATER +#if !NET internal static class BitOperations { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -45,7 +45,7 @@ internal static class BitOperations namespace System.Runtime.CompilerServices { -#if !NETCOREAPP3_0_OR_GREATER +#if !NET [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] internal sealed class CallerArgumentExpressionAttribute : Attribute { diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs index 13e695ef0a791a..86a6f3539278f8 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs @@ -361,6 +361,35 @@ protected override string CreateTKey(int seed) } protected override string CreateTValue(int seed) => CreateTKey(seed); + + [Theory] + [InlineData(0)] + [InlineData(25)] + [InlineData(50)] + [InlineData(75)] + [InlineData(100)] + public void ContainsKey_WithNonAscii(int percentageWithNonAscii) + { + Random rand = new(42); + + Dictionary expected = new(GetKeyIEqualityComparer()); + for (int i = 0; i < 100; i++) + { + int stringLength = rand.Next(4, 30); + byte[] bytes = new byte[stringLength]; + rand.NextBytes(bytes); + string value = Convert.ToBase64String(bytes); + if (rand.Next(100) < percentageWithNonAscii) + { + value = value.Replace(value[rand.Next(value.Length)], '\u05D0'); + } + expected.Add(value, value); + } + + FrozenDictionary actual = expected.ToFrozenDictionary(GetKeyIEqualityComparer()); + + Assert.All(expected, kvp => actual.ContainsKey(kvp.Key)); + } } public class FrozenDictionary_Generic_Tests_string_string_Default : FrozenDictionary_Generic_Tests_string_string diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs index 8465f66c4c3747..717efc31e45bb3 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs @@ -6,7 +6,6 @@ using System.Globalization; using System.Linq; using Xunit; -using System.Numerics; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; @@ -298,7 +297,7 @@ private sealed class InvertingComparer : IEqualityComparer private sealed class EmptySet : ISet -#if NET5_0_OR_GREATER +#if NET , IReadOnlySet #endif { @@ -338,6 +337,35 @@ protected override string CreateT(int seed) rand.NextBytes(bytes1); return Convert.ToBase64String(bytes1); } + + [Theory] + [InlineData(0)] + [InlineData(25)] + [InlineData(50)] + [InlineData(75)] + [InlineData(100)] + public void Contains_WithNonAscii(int percentageWithNonAscii) + { + Random rand = new(42); + + HashSet expected = new(GetIEqualityComparer()); + for (int i = 0; i < 100; i++) + { + int stringLength = rand.Next(4, 30); + byte[] bytes = new byte[stringLength]; + rand.NextBytes(bytes); + string value = Convert.ToBase64String(bytes); + if (rand.Next(100) < percentageWithNonAscii) + { + value = value.Replace(value[rand.Next(value.Length)], '\u05D0'); + } + expected.Add(value); + } + + FrozenSet actual = expected.ToFrozenSet(GetIEqualityComparer()); + + Assert.All(expected, s => actual.Contains(s)); + } } public class FrozenSet_Generic_Tests_string_Default : FrozenSet_Generic_Tests_string diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableHashSetTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableHashSetTest.cs index 0aab9405d55930..d6a01aee099a26 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableHashSetTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableHashSetTest.cs @@ -118,7 +118,7 @@ public void Create() Assert.Equal(1, set.Count); Assert.Same(comparer, set.KeyComparer); - set = ImmutableHashSet.Create("a", "b"); + set = ImmutableHashSet.Create(new[] { "a", "b" }); Assert.Equal(2, set.Count); Assert.Same(EqualityComparer.Default, set.KeyComparer); @@ -126,7 +126,7 @@ public void Create() Assert.Equal(2, set.Count); Assert.Same(EqualityComparer.Default, set.KeyComparer); - set = ImmutableHashSet.Create(comparer, "a", "b"); + set = ImmutableHashSet.Create(comparer, new[] { "a", "b" }); Assert.Equal(2, set.Count); Assert.Same(comparer, set.KeyComparer); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs index ec569e77699464..e522f4cff834ea 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs @@ -584,7 +584,7 @@ public void Create() list = ImmutableList.Create("a"); Assert.Equal(1, list.Count); - list = ImmutableList.Create("a", "b"); + list = ImmutableList.Create(new[] { "a", "b" }); Assert.Equal(2, list.Count); list = ImmutableList.Create((ReadOnlySpan)new[] { "a", "b" }); @@ -793,7 +793,7 @@ public static void TestDebuggerAttributes_Null() Assert.IsType(tie.InnerException); } -#if NETCOREAPP +#if NET [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] public void UsableWithCollectibleAssemblies() { diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs index c03621929a5990..4aef1b5577a345 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs @@ -213,7 +213,7 @@ public void Create() Assert.False(queue.IsEmpty); Assert.Equal(new[] { 1 }, queue); - queue = ImmutableQueue.Create(1, 2); + queue = ImmutableQueue.Create(new int[] { 1, 2 }); Assert.False(queue.IsEmpty); Assert.Equal(new[] { 1, 2 }, queue); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs index eecff21ffb34b7..f16d59dd63ae1b 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs @@ -289,7 +289,7 @@ public void Create() Assert.Equal(1, set.Count); Assert.Same(comparer, set.KeyComparer); - set = ImmutableSortedSet.Create("a", "b"); + set = ImmutableSortedSet.Create(new [] { "a", "b" }); Assert.Equal(2, set.Count); Assert.Same(Comparer.Default, set.KeyComparer); @@ -297,7 +297,7 @@ public void Create() Assert.Equal(2, set.Count); Assert.Same(Comparer.Default, set.KeyComparer); - set = ImmutableSortedSet.Create(comparer, "a", "b"); + set = ImmutableSortedSet.Create(comparer, new[] { "a", "b" }); Assert.Equal(2, set.Count); Assert.Same(comparer, set.KeyComparer); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs index 26336209e12047..4abd031ed43b2d 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs @@ -241,7 +241,7 @@ public void Create() Assert.False(stack.IsEmpty); Assert.Equal(new[] { 1 }, stack); - stack = ImmutableStack.Create(1, 2); + stack = ImmutableStack.Create(new[] { 1, 2 }); Assert.False(stack.IsEmpty); Assert.Equal(new[] { 2, 1 }, stack); diff --git a/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj b/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj index 770e5fc0fc1816..1bc456cd13ba3a 100644 --- a/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj +++ b/src/libraries/System.Collections.NonGeneric/src/System.Collections.NonGeneric.csproj @@ -21,6 +21,7 @@ + diff --git a/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveComparer.cs b/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveComparer.cs index 0c84d460db3655..82f587ec9616b9 100644 --- a/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveComparer.cs +++ b/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveComparer.cs @@ -17,7 +17,7 @@ namespace System.Collections public class CaseInsensitiveComparer : IComparer { private readonly CompareInfo _compareInfo; - private static volatile CaseInsensitiveComparer? s_InvariantCaseInsensitiveComparer; + private static CaseInsensitiveComparer? s_InvariantCaseInsensitiveComparer; public CaseInsensitiveComparer() { diff --git a/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs b/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs index 61777b6c93c50c..22bb48f8a1c2f0 100644 --- a/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs +++ b/src/libraries/System.Collections.NonGeneric/src/System/Collections/CaseInsensitiveHashCodeProvider.cs @@ -12,7 +12,7 @@ namespace System.Collections [Obsolete("CaseInsensitiveHashCodeProvider has been deprecated. Use StringComparer instead.")] public class CaseInsensitiveHashCodeProvider : IHashCodeProvider { - private static volatile CaseInsensitiveHashCodeProvider? s_invariantCaseInsensitiveHashCodeProvider; + private static CaseInsensitiveHashCodeProvider? s_invariantCaseInsensitiveHashCodeProvider; private readonly CompareInfo _compareInfo; public CaseInsensitiveHashCodeProvider() diff --git a/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj b/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj index 21e6fc760efae5..4301d885411c68 100644 --- a/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj +++ b/src/libraries/System.Collections.Specialized/src/System.Collections.Specialized.csproj @@ -23,6 +23,7 @@ + diff --git a/src/libraries/System.Collections/src/CompatibilitySuppressions.xml b/src/libraries/System.Collections/src/CompatibilitySuppressions.xml index c313881d43172b..f281317339d43b 100644 --- a/src/libraries/System.Collections/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Collections/src/CompatibilitySuppressions.xml @@ -1,4 +1,5 @@  + CP0001 diff --git a/src/libraries/System.Collections/src/System/Collections/StructuralComparisons.cs b/src/libraries/System.Collections/src/System/Collections/StructuralComparisons.cs index 988cc218e9fded..d4eb6576b3aed1 100644 --- a/src/libraries/System.Collections/src/System/Collections/StructuralComparisons.cs +++ b/src/libraries/System.Collections/src/System/Collections/StructuralComparisons.cs @@ -7,16 +7,15 @@ namespace System.Collections { public static class StructuralComparisons { - private static volatile IComparer? s_StructuralComparer; - private static volatile IEqualityComparer? s_StructuralEqualityComparer; + public static IComparer StructuralComparer => System.Collections.StructuralComparer.s_instance; - public static IComparer StructuralComparer => s_StructuralComparer ??= new StructuralComparer(); - - public static IEqualityComparer StructuralEqualityComparer => s_StructuralEqualityComparer ??= new StructuralEqualityComparer(); + public static IEqualityComparer StructuralEqualityComparer => System.Collections.StructuralEqualityComparer.s_instance; } internal sealed class StructuralEqualityComparer : IEqualityComparer { + internal static readonly StructuralEqualityComparer s_instance = new(); + public new bool Equals(object? x, object? y) { if (x != null) @@ -58,6 +57,8 @@ public int GetHashCode(object obj) internal sealed class StructuralComparer : IComparer { + internal static readonly StructuralComparer s_instance = new(); + public int Compare(object? x, object? y) { if (x == null) return y == null ? 0 : -1; diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs index 95ea38065458f1..75744ec2c1d30c 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs @@ -22,7 +22,7 @@ namespace System.ComponentModel.Composition.Hosting public partial class DirectoryCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged, ICompositionElement { private static bool IsWindows => -#if NETCOREAPP_5_0_OR_GREATER +#if NET OperatingSystem.IsWindows(); #else RuntimeInformation.IsOSPlatform(OSPlatform.Windows); diff --git a/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj b/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj index 0d413f6fd370ee..a5d9913733b441 100644 --- a/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj +++ b/src/libraries/System.ComponentModel.EventBasedAsync/src/System.ComponentModel.EventBasedAsync.csproj @@ -18,6 +18,7 @@ + diff --git a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj index 5fcff901309503..2938d1e641264e 100644 --- a/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj +++ b/src/libraries/System.ComponentModel.Primitives/src/System.ComponentModel.Primitives.csproj @@ -47,6 +47,7 @@ + diff --git a/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs index 2b9c0c08c88e19..fc06665da5ecfc 100644 --- a/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs +++ b/src/libraries/System.ComponentModel.Primitives/src/System/ComponentModel/CategoryAttribute.cs @@ -12,22 +12,22 @@ namespace System.ComponentModel [AttributeUsage(AttributeTargets.All)] public class CategoryAttribute : Attribute { - private static volatile CategoryAttribute? s_action; - private static volatile CategoryAttribute? s_appearance; - private static volatile CategoryAttribute? s_asynchronous; - private static volatile CategoryAttribute? s_behavior; - private static volatile CategoryAttribute? s_data; - private static volatile CategoryAttribute? s_design; - private static volatile CategoryAttribute? s_dragDrop; - private static volatile CategoryAttribute? s_defAttr; - private static volatile CategoryAttribute? s_focus; - private static volatile CategoryAttribute? s_format; - private static volatile CategoryAttribute? s_key; - private static volatile CategoryAttribute? s_layout; - private static volatile CategoryAttribute? s_mouse; - private static volatile CategoryAttribute? s_windowStyle; - - private bool _localized; + private static CategoryAttribute? s_action; + private static CategoryAttribute? s_appearance; + private static CategoryAttribute? s_asynchronous; + private static CategoryAttribute? s_behavior; + private static CategoryAttribute? s_data; + private static CategoryAttribute? s_design; + private static CategoryAttribute? s_dragDrop; + private static CategoryAttribute? s_defAttr; + private static CategoryAttribute? s_focus; + private static CategoryAttribute? s_format; + private static CategoryAttribute? s_key; + private static CategoryAttribute? s_layout; + private static CategoryAttribute? s_mouse; + private static CategoryAttribute? s_windowStyle; + + private volatile bool _localized; private readonly object _locker = new object(); diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationLockCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationLockCollection.cs index de0d3af555f8d9..8f5c8c9f37c3c4 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationLockCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationLockCollection.cs @@ -220,7 +220,7 @@ internal bool DefinedInParent(string name) string parentListEnclosed = "," + _seedList + ","; if (name.Equals(_ignoreName) || -#if NETCOREAPP +#if NET parentListEnclosed.Contains("," + name + ",", StringComparison.Ordinal)) #else parentListEnclosed.IndexOf("," + name + ",", StringComparison.Ordinal) >= 0) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationProperty.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationProperty.cs index f401066ddd8d20..959ba9bd9ed54e 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationProperty.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationProperty.cs @@ -133,7 +133,7 @@ internal ConfigurationProperty(PropertyInfo info) if (collectionAttribute != null) { -#if NETCOREAPP +#if NET if (!collectionAttribute.AddItemName.Contains(',')) #else if (collectionAttribute.AddItemName.IndexOf(',') == -1) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionCollection.cs index b103a4a35a26c8..ef54b46ac03182 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionCollection.cs @@ -88,7 +88,7 @@ public ConfigurationSection Get(string name) throw ExceptionUtil.ParameterNullOrEmpty(nameof(name)); // prevent GetConfig from returning config not in this collection -#if NETCOREAPP +#if NET if (name.Contains('/')) #else if (name.IndexOf('/') >= 0) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionGroupCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionGroupCollection.cs index 68157107c77a7e..81210e851119e6 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionGroupCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationSectionGroupCollection.cs @@ -92,7 +92,7 @@ public ConfigurationSectionGroup Get(string name) throw ExceptionUtil.ParameterNullOrEmpty(nameof(name)); // prevent GetConfig from returning config not in this collection -#if NETCOREAPP +#if NET if (name.Contains('/')) #else if (name.IndexOf('/') >= 0) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs index 32403a8950c2c2..195b3ca5ff4a38 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ImplicitMachineConfigHost.cs @@ -81,7 +81,7 @@ public override Stream OpenStreamForRead(string streamName)
" + -#if NET7_0_OR_GREATER +#if NET @"
" + #endif @"
diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj index 2a24b7ffaad07f..0a6b23dad7e658 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj @@ -97,7 +97,8 @@ - + + diff --git a/src/libraries/System.Console/ref/System.Console.cs b/src/libraries/System.Console/ref/System.Console.cs index 273290de2a89f2..7c5ca19cd01ad6 100644 --- a/src/libraries/System.Console/ref/System.Console.cs +++ b/src/libraries/System.Console/ref/System.Console.cs @@ -175,6 +175,7 @@ public static void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute( public static void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public static void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { } public static void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[]? arg) { } + public static void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } [System.CLSCompliantAttribute(false)] public static void Write(uint value) { } [System.CLSCompliantAttribute(false)] @@ -195,6 +196,7 @@ public static void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttrib public static void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public static void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { } public static void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[]? arg) { } + public static void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } [System.CLSCompliantAttribute(false)] public static void WriteLine(uint value) { } [System.CLSCompliantAttribute(false)] diff --git a/src/libraries/System.Console/src/System/Console.cs b/src/libraries/System.Console/src/System/Console.cs index 63736b59741706..5e0e387b8299fb 100644 --- a/src/libraries/System.Console/src/System/Console.cs +++ b/src/libraries/System.Console/src/System/Console.cs @@ -865,6 +865,17 @@ public static void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat Out.WriteLine(format, arg); } + /// + /// Writes the text representation of the specified span of objects, followed by the current line terminator, to the standard output stream using the specified format information. + /// + /// A composite format string. + /// A span of objects to write using format. + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + Out.WriteLine(format, arg); + } + [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0) { @@ -892,6 +903,17 @@ public static void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] s Out.Write(format, arg); } + /// + /// Writes the text representation of the specified span of objects to the standard output stream using the specified format information. + /// + /// A composite format string. + /// A span of objects to write using format. + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + Out.Write(format, arg); + } + [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void Write(bool value) { diff --git a/src/libraries/System.Console/tests/ManualTests/Readme.md b/src/libraries/System.Console/tests/ManualTests/Readme.md index 6c56bce87840a7..4cd91a362a94d7 100644 --- a/src/libraries/System.Console/tests/ManualTests/Readme.md +++ b/src/libraries/System.Console/tests/ManualTests/Readme.md @@ -6,7 +6,8 @@ To run the suite, follow these steps: 1. Build the CLR and libraries. 2. Using a terminal, navigate to the current folder. 3. Enable manual testing by defining the `MANUAL_TESTS` environment variable (e.g. on bash `export MANUAL_TESTS=true`). -4. Run `dotnet test` and follow the instructions in the command prompt. +4. Disable terminal logger output for dotnet test by setting `MSBUILDENSURESTDOUTFORTASKPROCESSES=1` environment variable. (e.g. on bash `export MSBUILDENSURESTDOUTFORTASKPROCESSES=1`). +5. Run `dotnet test` and follow the instructions in the command prompt. ## Instructions for Windows testers diff --git a/src/libraries/System.Console/tests/ReadAndWrite.cs b/src/libraries/System.Console/tests/ReadAndWrite.cs index 5fbf425fc84855..d60fd6aa34cc04 100644 --- a/src/libraries/System.Console/tests/ReadAndWrite.cs +++ b/src/libraries/System.Console/tests/ReadAndWrite.cs @@ -84,10 +84,14 @@ private static void WriteCore() Console.Write("{0}", null, null); Console.Write("{0} {1} {2}", 32, "Hello", (uint)50); Console.Write("{0}", null, null, null); - Console.Write("{0} {1} {2} {3}", 32, "Hello", (uint)50, (ulong)5); - Console.Write("{0}", null, null, null, null); - Console.Write("{0} {1} {2} {3} {4}", 32, "Hello", (uint)50, (ulong)5, 'a'); - Console.Write("{0}", null, null, null, null, null); + Console.Write("{0} {1} {2} {3}", new object[] { 32, "Hello", (uint)50, (ulong)5 }); + Console.Write("{0} {1} {2} {3}", new object[] { 32, "Hello", (uint)50, (ulong)5 }.AsSpan()); + Console.Write("{0}", new object[] { null, null, null, null }); + Console.Write("{0}", new object[] { null, null, null, null }.AsSpan()); + Console.Write("{0} {1} {2} {3} {4}", new object[] { 32, "Hello", (uint)50, (ulong)5, 'a' }); + Console.Write("{0} {1} {2} {3} {4}", new object[] { 32, "Hello", (uint)50, (ulong)5, 'a' }.AsSpan()); + Console.Write("{0}", new object[] { null, null, null, null, null }); + Console.Write("{0}", new object[] { null, null, null, null, null }.AsSpan()); Console.Write(true); Console.Write('a'); Console.Write(new char[] { 'a', 'b', 'c', 'd', }); @@ -120,10 +124,14 @@ private static void WriteLineCore() Console.WriteLine("{0}", null, null); Console.WriteLine("{0} {1} {2}", 32, "Hello", (uint)50); Console.WriteLine("{0}", null, null, null); - Console.WriteLine("{0} {1} {2} {3}", 32, "Hello", (uint)50, (ulong)5); - Console.WriteLine("{0}", null, null, null, null); - Console.WriteLine("{0} {1} {2} {3} {4}", 32, "Hello", (uint)50, (ulong)5, 'a'); - Console.WriteLine("{0}", null, null, null, null, null); + Console.WriteLine("{0} {1} {2} {3}", new object[] { 32, "Hello", (uint)50, (ulong)5 }); + Console.WriteLine("{0} {1} {2} {3}", new object[] { 32, "Hello", (uint)50, (ulong)5 }.AsSpan()); + Console.WriteLine("{0}", new object[] { null, null, null, null }); + Console.WriteLine("{0}", new object[] { null, null, null, null }.AsSpan()); + Console.WriteLine("{0} {1} {2} {3} {4}", new object[] { 32, "Hello", (uint)50, (ulong)5, 'a' }); + Console.WriteLine("{0} {1} {2} {3} {4}", new object[] { 32, "Hello", (uint)50, (ulong)5, 'a' }.AsSpan()); + Console.WriteLine("{0}", new object[] { null, null, null, null, null }); + Console.WriteLine("{0}", new object[] { null, null, null, null, null }.AsSpan()); Console.WriteLine(true); Console.WriteLine('a'); Console.WriteLine(new char[] { 'a', 'b', 'c', 'd', }); @@ -158,8 +166,10 @@ public static async Task OutWriteAndWriteLineOverloads() writer.Write("{0}", 32); writer.Write("{0} {1}", 32, "Hello"); writer.Write("{0} {1} {2}", 32, "Hello", (uint)50); - writer.Write("{0} {1} {2} {3}", 32, "Hello", (uint)50, (ulong)5); - writer.Write("{0} {1} {2} {3} {4}", 32, "Hello", (uint)50, (ulong)5, 'a'); + writer.Write("{0} {1} {2} {3}", new object[] { 32, "Hello", (uint)50, (ulong)5 }); + writer.Write("{0} {1} {2} {3}", new object[] { 32, "Hello", (uint)50, (ulong)5 }.AsSpan()); + writer.Write("{0} {1} {2} {3} {4}", new object[] { 32, "Hello", (uint)50, (ulong)5, 'a' }); + writer.Write("{0} {1} {2} {3} {4}", new object[] { 32, "Hello", (uint)50, (ulong)5, 'a' }.AsSpan()); writer.Write(true); writer.Write('a'); writer.Write(new char[] { 'a', 'b', 'c', 'd', }); diff --git a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj index ed37aab0c75388..ae85c66d7e8b5f 100644 --- a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj +++ b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj @@ -123,6 +123,7 @@ - + + diff --git a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs index 0bb5bde47ea416..81b4ecdc5b7175 100644 --- a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs +++ b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs @@ -59,7 +59,7 @@ internal partial class DbConnectionOptions private static readonly Regex ConnectionStringRegex = CreateConnectionStringRegex(); private static readonly Regex ConnectionStringRegexOdbc = CreateConnectionStringRegexOdbc(); -#if NET7_0_OR_GREATER +#if NET [GeneratedRegex(ConnectionStringPattern, RegexOptions.ExplicitCapture)] private static partial Regex CreateConnectionStringRegex(); @@ -76,7 +76,7 @@ internal partial class DbConnectionOptions private static readonly Regex ConnectionStringQuoteValueRegex = CreateConnectionStringQuoteValueRegex(); // generally do not quote the value if it matches the pattern private static readonly Regex ConnectionStringQuoteOdbcValueRegex = CreateConnectionStringQuoteOdbcValueRegex(); // do not quote odbc value if it matches this pattern -#if NET7_0_OR_GREATER +#if NET [GeneratedRegex("^(?![;\\s])[^\\p{Cc}]+(? : Instrument where T : struct public void Add(T delta, System.Collections.Generic.KeyValuePair tag) { throw null; } public void Add(T delta, System.Collections.Generic.KeyValuePair tag1, System.Collections.Generic.KeyValuePair tag2) { throw null; } public void Add(T delta, System.Collections.Generic.KeyValuePair tag1, System.Collections.Generic.KeyValuePair tag2, System.Collections.Generic.KeyValuePair tag3) { throw null; } - public void Add(T delta, ReadOnlySpan> tags) { throw null; } + public void Add(T delta, System.ReadOnlySpan> tags) { throw null; } public void Add(T delta, params System.Collections.Generic.KeyValuePair[] tags) { throw null; } public void Add(T delta, in TagList tagList) { throw null; } internal Counter(Meter meter, string name, string? unit, string? description) : @@ -348,7 +349,7 @@ public sealed class UpDownCounter : Instrument where T : struct public void Add(T delta, System.Collections.Generic.KeyValuePair tag) { throw null; } public void Add(T delta, System.Collections.Generic.KeyValuePair tag1, System.Collections.Generic.KeyValuePair tag2) { throw null; } public void Add(T delta, System.Collections.Generic.KeyValuePair tag1, System.Collections.Generic.KeyValuePair tag2, System.Collections.Generic.KeyValuePair tag3) { throw null; } - public void Add(T delta, ReadOnlySpan> tags) { throw null; } + public void Add(T delta, System.ReadOnlySpan> tags) { throw null; } public void Add(T delta, params System.Collections.Generic.KeyValuePair[] tags) { throw null; } public void Add(T delta, in TagList tagList) { throw null; } internal UpDownCounter(Meter meter, string name, string? unit, string? description) : @@ -362,7 +363,7 @@ public sealed class Histogram : Instrument where T : struct public void Record(T value, System.Collections.Generic.KeyValuePair tag1, System.Collections.Generic.KeyValuePair tag2) { throw null; } public void Record(T value, System.Collections.Generic.KeyValuePair tag1, System.Collections.Generic.KeyValuePair tag2, System.Collections.Generic.KeyValuePair tag3) { throw null; } public void Record(T value, in TagList tagList) { throw null; } - public void Record(T value, ReadOnlySpan> tags) { throw null; } + public void Record(T value, System.ReadOnlySpan> tags) { throw null; } public void Record(T value, params System.Collections.Generic.KeyValuePair[] tags) { throw null; } } public interface IMeterFactory : System.IDisposable @@ -398,11 +399,11 @@ public abstract class Instrument : Instrument where T : struct public Measurement(T value) { throw null; } public Measurement(T value, System.Collections.Generic.IEnumerable>? tags) { throw null; } public Measurement(T value, params System.Collections.Generic.KeyValuePair[]? tags) { throw null; } - public Measurement(T value, ReadOnlySpan> tags) { throw null; } + public Measurement(T value, System.ReadOnlySpan> tags) { throw null; } public ReadOnlySpan> Tags { get { throw null; } } public T Value { get { throw null; } } } - public delegate void MeasurementCallback(Instrument instrument, T measurement, ReadOnlySpan> tags, object? state); + public delegate void MeasurementCallback(Instrument instrument, T measurement, ReadOnlySpan> tags, object? state) where T : struct; public class Meter : IDisposable { public Counter CreateCounter(string name, string? unit = null, string? description = null) where T : struct { throw null; } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index 0605251a93b7a7..bf2fb0bb0430a5 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -226,7 +226,7 @@ public string? Id Span flagsChars = stackalloc char[2]; HexConverter.ToCharsBuffer((byte)((~ActivityTraceFlagsIsSet) & _w3CIdFlags), flagsChars, 0, HexConverter.Casing.Lower); string id = -#if NET6_0_OR_GREATER +#if NET string.Create(null, stackalloc char[128], $"00-{_traceId}-{_spanId}-{flagsChars}"); #else "00-" + _traceId + "-" + _spanId + "-" + flagsChars.ToString(); @@ -258,7 +258,7 @@ public string? ParentId Span flagsChars = stackalloc char[2]; HexConverter.ToCharsBuffer((byte)((~ActivityTraceFlagsIsSet) & _parentTraceFlags), flagsChars, 0, HexConverter.Casing.Lower); string parentId = -#if NET6_0_OR_GREATER +#if NET string.Create(null, stackalloc char[128], $"00-{_traceId}-{_parentSpanId}-{flagsChars}"); #else "00-" + _traceId + "-" + _parentSpanId + "-" + flagsChars.ToString(); @@ -517,6 +517,25 @@ public Activity AddEvent(ActivityEvent e) return this; } + /// + /// Add an to the list. + /// + /// The to add. + /// for convenient chaining. + /// + /// For contexts that are available during span creation, adding links at span creation is preferred to calling later, + /// because head sampling decisions can only consider information present during span creation. + /// + public Activity AddLink(ActivityLink link) + { + if (_links != null || Interlocked.CompareExchange(ref _links, new DiagLinkedList(link), null) != null) + { + _links.Add(link); + } + + return this; + } + /// /// Update the Activity to have baggage with an additional 'key' and value 'value'. /// This shows up in the enumeration as well as the diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs index e1678dc3dda86a..4d4edfbf7b798f 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs @@ -1362,7 +1362,7 @@ public static PropertyFetch FetcherForProperty(Type? type, string propertyName) private static PropertyFetch CreateEnumeratePropertyFetch(Type type, TypeInfo enumerableOfTType) { Type elemType = enumerableOfTType.GetGenericArguments()[0]; -#if NETCOREAPP +#if NET if (!RuntimeFeature.IsDynamicCodeSupported && elemType.IsValueType) { return new EnumeratePropertyFetch(type); @@ -1377,7 +1377,7 @@ private static PropertyFetch CreateEnumeratePropertyFetch(Type type, TypeInfo en Justification = "MakeGenericType is only called when IsDynamicCodeSupported is true or only with ref types.")] private static PropertyFetch CreatePropertyFetch(Type type, PropertyInfo propertyInfo) { -#if NETCOREAPP +#if NET if (!RuntimeFeature.IsDynamicCodeSupported && (propertyInfo.DeclaringType!.IsValueType || propertyInfo.PropertyType.IsValueType)) { return new ReflectionPropertyFetch(type, propertyInfo); @@ -1434,7 +1434,7 @@ public ValueTypedFetchProperty(Type type, PropertyInfo property) : base(type) private readonly StructFunc _propertyFetch; } -#if NETCOREAPP +#if NET /// /// A fetcher that can be used when MakeGenericType isn't available. /// diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Counter.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Counter.cs index 1d311d62196391..9f15ff37c70104 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Counter.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Counter.cs @@ -59,7 +59,7 @@ internal Counter(Meter meter, string name, string? unit, string? description, IE /// /// The increment measurement. /// A span of key-value pair tags associated with the measurement. - public void Add(T delta, ReadOnlySpan> tags) => RecordMeasurement(delta, tags); + public void Add(T delta, /*params*/ ReadOnlySpan> tags) => RecordMeasurement(delta, tags); /// /// Record the increment value of the measurement. diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/CounterAggregator.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/CounterAggregator.cs index b9e3c8d35bca70..4577c16b9b988e 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/CounterAggregator.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/CounterAggregator.cs @@ -33,7 +33,7 @@ public override void Update(double value) // Get the delta best associated with the current thread, preferring to use core ID rather than // thread ID to reduce contention. ref PaddedDouble delta = ref deltas[ -#if NETCOREAPP2_1_OR_GREATER +#if NET Thread.GetCurrentProcessorId() #else Environment.CurrentManagedThreadId diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Histogram.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Histogram.cs index ed3431edfce8be..91f5f40da6e80e 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Histogram.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Histogram.cs @@ -59,7 +59,7 @@ internal Histogram(Meter meter, string name, string? unit, string? description, /// /// The measurement value. /// A span of key-value pair tags associated with the measurement. - public void Record(T value, ReadOnlySpan> tags) => RecordMeasurement(value, tags); + public void Record(T value, /*params*/ ReadOnlySpan> tags) => RecordMeasurement(value, tags); /// /// Record a measurement value. diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Measurement.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Measurement.cs index 49db3c86f8dbf1..f678ef66014ff0 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Measurement.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Measurement.cs @@ -59,7 +59,7 @@ public Measurement(T value, params KeyValuePair[]? tags) /// /// The measurement value. /// The measurement associated tags list. - public Measurement(T value, ReadOnlySpan> tags) + public Measurement(T value, /*params*/ ReadOnlySpan> tags) { _tags = tags.ToArray(); Value = value; diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs index a3c443b0a38f11..ba789aa98b15bf 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs @@ -737,7 +737,7 @@ private static string FormatQuantiles(QuantileValue[] quantiles) StringBuilder sb = new StringBuilder(); for (int i = 0; i < quantiles.Length; i++) { -#if NETCOREAPP +#if NET sb.Append(CultureInfo.InvariantCulture, $"{quantiles[i].Quantile}={quantiles[i].Value}"); #else sb.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}", quantiles[i].Quantile, quantiles[i].Value); diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/TagList.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/TagList.cs index 7646bcc2d33a46..138da8875aeed6 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/TagList.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/TagList.cs @@ -43,7 +43,7 @@ public struct TagList : IList>, IReadOnlyList. ///
/// A span of tags to initialize the list with. - public TagList(ReadOnlySpan> tagList) : this() + public TagList(/*params*/ ReadOnlySpan> tagList) : this() { _tagsCount = tagList.Length; switch (_tagsCount) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/UpDownCounter.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/UpDownCounter.cs index 79d0ed29d8f417..4a093865c5511d 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/UpDownCounter.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/UpDownCounter.cs @@ -58,7 +58,7 @@ internal UpDownCounter(Meter meter, string name, string? unit, string? descripti /// /// The amount to be added which can be positive, negative or zero. /// A span of key-value pair tags associated with the measurement. - public void Add(T delta, ReadOnlySpan> tags) => RecordMeasurement(delta, tags); + public void Add(T delta, /*params*/ ReadOnlySpan> tags) => RecordMeasurement(delta, tags); /// /// Record the delta value of the measurement. The delta can be positive, negative or zero. diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs index ae3c138e369714..00cb26017a3846 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivityTests.cs @@ -1597,6 +1597,35 @@ public void TestEvent() Assert.Equal(0, activity.Events.ElementAt(1).Tags.Count()); } + [Fact] + public void AddLinkTest() + { + ActivityContext c1 = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None); + ActivityContext c2 = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None); + + ActivityLink l1 = new ActivityLink(c1); + ActivityLink l2 = new ActivityLink(c2, new ActivityTagsCollection() + { + new KeyValuePair("foo", 99) + }); + + Activity activity = new Activity("LinkTest"); + Assert.True(ReferenceEquals(activity, activity.AddLink(l1))); + Assert.True(ReferenceEquals(activity, activity.AddLink(l2))); + + // Add a duplicate of l1. The implementation doesn't check for duplicates. + Assert.True(ReferenceEquals(activity, activity.AddLink(l1))); + + ActivityLink[] links = activity.Links.ToArray(); + Assert.Equal(3, links.Length); + Assert.Equal(c1, links[0].Context); + Assert.Equal(c2, links[1].Context); + Assert.Equal(c1, links[2].Context); + KeyValuePair tag = links[1].Tags.Single(); + Assert.Equal("foo", tag.Key); + Assert.Equal(99, tag.Value); + } + [Fact] public void TestIsAllDataRequested() { @@ -2163,12 +2192,14 @@ public void EnumerateLinksTest() var context1 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None); var context2 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None); + var context3 = new ActivityContext(ActivityTraceId.CreateRandom(), default, ActivityTraceFlags.None); a = source.CreateActivity( name: "Root", kind: ActivityKind.Internal, parentContext: default, links: new[] { new ActivityLink(context1), new ActivityLink(context2) }); + a.AddLink(new ActivityLink(context3)); Assert.NotNull(a); @@ -2182,6 +2213,9 @@ public void EnumerateLinksTest() Assert.True(enumerator.MoveNext()); Assert.Equal(context2.TraceId, enumerator.Current.Context.TraceId); values.Add(enumerator.Current); + Assert.True(enumerator.MoveNext()); + Assert.Equal(context3.TraceId, enumerator.Current.Context.TraceId); + values.Add(enumerator.Current); Assert.False(enumerator.MoveNext()); Assert.Equal(a.Links, values); diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs index 4a3cd242bb8be0..b292e55f1bcf20 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs @@ -4,6 +4,7 @@ using Microsoft.DotNet.RemoteExecutor; using System.Collections.Generic; using System.Diagnostics.Metrics; +using System.Diagnostics.Tests; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -13,6 +14,29 @@ namespace System.Diagnostics.Metrics.Tests { public class MetricsTests { + [Fact] + public void MeasurementConstructionTest() + { + for (int i = 0; i < 30; i++) + { + TagListTests.CreateTagList(i, out TagList tags); + TagListTests.ValidateTags(in tags, i); + KeyValuePair[] tagsArray = tags.ToArray(); + + var measurement = new Measurement(i, tags); + Assert.Equal(i, measurement.Value); + TagListTests.ValidateTags(new TagList(measurement.Tags), tagsArray); + + measurement = new Measurement(i, tagsArray); + Assert.Equal(i, measurement.Value); + TagListTests.ValidateTags(new TagList(measurement.Tags), tagsArray); + + measurement = new Measurement(i, tagsArray.AsSpan()); + Assert.Equal(i, measurement.Value); + TagListTests.ValidateTags(new TagList(measurement.Tags), tagsArray); + } + } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public void MeterConstructionTest() { @@ -238,76 +262,115 @@ public void ThrowingExceptionsFromObservableInstrumentCallbacks() }).Dispose(); } - [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - public void InstrumentMeasurementTest() + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(false)] + [InlineData(true)] + public void InstrumentMeasurementTest(bool useSpan) { - RemoteExecutor.Invoke(() => { + RemoteExecutor.Invoke((string useSpanStr) => { Meter meter = new Meter("InstrumentMeasurementTest"); + bool useSpan = bool.Parse(useSpanStr); Counter counter = meter.CreateCounter("byteCounter"); - InstrumentMeasurementAggregationValidation(counter, (value, tags) => { counter.Add(value, tags); } ); + InstrumentMeasurementAggregationValidation(counter, (value, tags) => { AddToCounter(counter, value, tags, useSpan); } ); UpDownCounter upDownCounter = meter.CreateUpDownCounter("byteUpDownCounter"); - InstrumentMeasurementAggregationValidation(upDownCounter, (value, tags) => { upDownCounter.Add(value, tags); }); + InstrumentMeasurementAggregationValidation(upDownCounter, (value, tags) => { AddToUpDownCounter(upDownCounter, value, tags, useSpan); }); Counter counter1 = meter.CreateCounter("shortCounter"); - InstrumentMeasurementAggregationValidation(counter1, (value, tags) => { counter1.Add(value, tags); } ); + InstrumentMeasurementAggregationValidation(counter1, (value, tags) => { AddToCounter(counter1, value, tags, useSpan); } ); UpDownCounter upDownCounter1 = meter.CreateUpDownCounter("shortUpDownCounter"); - InstrumentMeasurementAggregationValidation(upDownCounter1, (value, tags) => { upDownCounter1.Add(value, tags); }, true); + InstrumentMeasurementAggregationValidation(upDownCounter1, (value, tags) => { AddToUpDownCounter(upDownCounter1, value, tags, useSpan); }, true); Counter counter2 = meter.CreateCounter("intCounter"); - InstrumentMeasurementAggregationValidation(counter2, (value, tags) => { counter2.Add(value, tags); } ); + InstrumentMeasurementAggregationValidation(counter2, (value, tags) => { AddToCounter(counter2, value, tags, useSpan); } ); UpDownCounter upDownCounter2 = meter.CreateUpDownCounter("intUpDownCounter"); - InstrumentMeasurementAggregationValidation(upDownCounter2, (value, tags) => { upDownCounter2.Add(value, tags); }, true); + InstrumentMeasurementAggregationValidation(upDownCounter2, (value, tags) => { AddToUpDownCounter(upDownCounter2, value, tags, useSpan); }, true); Counter counter3 = meter.CreateCounter("longCounter"); - InstrumentMeasurementAggregationValidation(counter3, (value, tags) => { counter3.Add(value, tags); } ); + InstrumentMeasurementAggregationValidation(counter3, (value, tags) => { AddToCounter(counter3, value, tags, useSpan); } ); UpDownCounter upDownCounter3 = meter.CreateUpDownCounter("longUpDownCounter"); - InstrumentMeasurementAggregationValidation(upDownCounter3, (value, tags) => { upDownCounter3.Add(value, tags); }, true); + InstrumentMeasurementAggregationValidation(upDownCounter3, (value, tags) => { AddToUpDownCounter(upDownCounter3, value, tags, useSpan); }, true); Counter counter4 = meter.CreateCounter("floatCounter"); - InstrumentMeasurementAggregationValidation(counter4, (value, tags) => { counter4.Add(value, tags); } ); + InstrumentMeasurementAggregationValidation(counter4, (value, tags) => { AddToCounter(counter4, value, tags, useSpan); } ); UpDownCounter upDownCounter4 = meter.CreateUpDownCounter("floatUpDownCounter"); - InstrumentMeasurementAggregationValidation(upDownCounter4, (value, tags) => { upDownCounter4.Add(value, tags); }, true); + InstrumentMeasurementAggregationValidation(upDownCounter4, (value, tags) => { AddToUpDownCounter(upDownCounter4, value, tags, useSpan); }, true); Counter counter5 = meter.CreateCounter("doubleCounter"); - InstrumentMeasurementAggregationValidation(counter5, (value, tags) => { counter5.Add(value, tags); } ); + InstrumentMeasurementAggregationValidation(counter5, (value, tags) => { AddToCounter(counter5, value, tags, useSpan); } ); UpDownCounter upDownCounter5 = meter.CreateUpDownCounter("doubleUpDownCounter"); - InstrumentMeasurementAggregationValidation(upDownCounter5, (value, tags) => { upDownCounter5.Add(value, tags); }, true); + InstrumentMeasurementAggregationValidation(upDownCounter5, (value, tags) => { AddToUpDownCounter(upDownCounter5, value, tags, useSpan); }, true); Counter counter6 = meter.CreateCounter("decimalCounter"); - InstrumentMeasurementAggregationValidation(counter6, (value, tags) => { counter6.Add(value, tags); } ); + InstrumentMeasurementAggregationValidation(counter6, (value, tags) => { AddToCounter(counter6, value, tags, useSpan); } ); UpDownCounter upDownCounter6 = meter.CreateUpDownCounter("decimalUpDownCounter"); - InstrumentMeasurementAggregationValidation(upDownCounter6, (value, tags) => { upDownCounter6.Add(value, tags); }, true); + InstrumentMeasurementAggregationValidation(upDownCounter6, (value, tags) => { AddToUpDownCounter(upDownCounter6, value, tags, useSpan); }, true); Histogram histogram = meter.CreateHistogram("byteHistogram"); - InstrumentMeasurementAggregationValidation(histogram, (value, tags) => { histogram.Record(value, tags); } ); + InstrumentMeasurementAggregationValidation(histogram, (value, tags) => { Record(histogram, value, tags, useSpan); } ); Histogram histogram1 = meter.CreateHistogram("shortHistogram"); - InstrumentMeasurementAggregationValidation(histogram1, (value, tags) => { histogram1.Record(value, tags); } ); + InstrumentMeasurementAggregationValidation(histogram1, (value, tags) => { Record(histogram1, value, tags, useSpan); } ); Histogram histogram2 = meter.CreateHistogram("intHistogram"); - InstrumentMeasurementAggregationValidation(histogram2, (value, tags) => { histogram2.Record(value, tags); } ); + InstrumentMeasurementAggregationValidation(histogram2, (value, tags) => { Record(histogram2, value, tags, useSpan); } ); Histogram histogram3 = meter.CreateHistogram("longHistogram"); - InstrumentMeasurementAggregationValidation(histogram3, (value, tags) => { histogram3.Record(value, tags); } ); + InstrumentMeasurementAggregationValidation(histogram3, (value, tags) => { Record(histogram3, value, tags, useSpan); } ); Histogram histogram4 = meter.CreateHistogram("floatHistogram"); - InstrumentMeasurementAggregationValidation(histogram4, (value, tags) => { histogram4.Record(value, tags); } ); + InstrumentMeasurementAggregationValidation(histogram4, (value, tags) => { Record(histogram4, value, tags, useSpan); } ); Histogram histogram5 = meter.CreateHistogram("doubleHistogram"); - InstrumentMeasurementAggregationValidation(histogram5, (value, tags) => { histogram5.Record(value, tags); } ); + InstrumentMeasurementAggregationValidation(histogram5, (value, tags) => { Record(histogram5, value, tags, useSpan); } ); Histogram histogram6 = meter.CreateHistogram("decimalHistogram"); - InstrumentMeasurementAggregationValidation(histogram6, (value, tags) => { histogram6.Record(value, tags); } ); + InstrumentMeasurementAggregationValidation(histogram6, (value, tags) => { Record(histogram6, value, tags, useSpan); } ); - }).Dispose(); + }, useSpan.ToString()).Dispose(); + + void AddToCounter(Counter counter, T delta, KeyValuePair[] tags, bool useSpan) where T : struct + { + if (useSpan) + { + counter.Add(delta, (ReadOnlySpan>)tags); + } + else + { + counter.Add(delta, tags); + } + } + + void AddToUpDownCounter(UpDownCounter upDownCounter, T delta, KeyValuePair[] tags, bool useSpan) where T : struct + { + if (useSpan) + { + upDownCounter.Add(delta, (ReadOnlySpan>)tags); + } + else + { + upDownCounter.Add(delta, tags); + } + } + + void Record(Histogram histogram, T value, KeyValuePair[] tags, bool useSpan) where T : struct + { + if (useSpan) + { + histogram.Record(value, (ReadOnlySpan>)tags); + } + else + { + histogram.Record(value, tags); + } + } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj deleted file mode 100644 index 8001203352b581..00000000000000 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/System.Diagnostics.DiagnosticSource.NativeAotTests.proj +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TagListTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TagListTests.cs index 9f35cb9d47c027..59edc168186a65 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TagListTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TagListTests.cs @@ -3,7 +3,6 @@ using Xunit; using System.Collections.Generic; -using System.Diagnostics; namespace System.Diagnostics.Tests { @@ -21,7 +20,7 @@ public void TestConstruction() KeyValuePair[] array = new KeyValuePair[tagList.Count]; tagList.CopyTo(array); TagList list = new TagList(array.AsSpan()); - ValidateTags(in tagList, i); + ValidateTags(in list, i); } } @@ -303,7 +302,7 @@ public void TestNegativeCases() Assert.Throws(() => list.RemoveAt(2)); } - private void ValidateTags(in TagList tagList, KeyValuePair[] array) + internal static void ValidateTags(in TagList tagList, KeyValuePair[] array) { Assert.True(tagList.Count <= array.Length); for (int i = 0; i < tagList.Count; i++) @@ -313,7 +312,7 @@ private void ValidateTags(in TagList tagList, KeyValuePair[] ar } } - private void ValidateTags(in TagList tagList, int tagsCount) + internal static void ValidateTags(in TagList tagList, int tagsCount) { Assert.Equal(tagsCount, tagList.Count); for (int i = 0; i < tagList.Count; i++) @@ -323,7 +322,7 @@ private void ValidateTags(in TagList tagList, int tagsCount) } } - private void CreateTagList(int tagsCount, out TagList tagList) + internal static void CreateTagList(int tagsCount, out TagList tagList) { tagList = new TagList(); for (int i = 0; i < tagsCount; i++) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TrimmingTests/DiagnosticSourceEventSourceTests.cs similarity index 100% rename from src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests/DiagnosticSourceEventSourceTests.cs rename to src/libraries/System.Diagnostics.DiagnosticSource/tests/TrimmingTests/DiagnosticSourceEventSourceTests.cs diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TrimmingTests/System.Diagnostics.DiagnosticSource.proj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TrimmingTests/System.Diagnostics.DiagnosticSource.proj index ca9483e224ffb4..919c0b7614b145 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/TrimmingTests/System.Diagnostics.DiagnosticSource.proj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/TrimmingTests/System.Diagnostics.DiagnosticSource.proj @@ -2,6 +2,8 @@ + diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs index e5cdb63f7ba76c..a8f8fd63369693 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/UnsafeNativeMethods.cs @@ -5,7 +5,7 @@ using System; using System.Diagnostics.Eventing.Reader; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.InteropServices.Marshalling; #endif using System.Security; @@ -341,7 +341,7 @@ internal enum EvtLoginClass EvtRpcLogin = 1 } -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #endif [StructLayout(LayoutKind.Sequential)] @@ -355,7 +355,7 @@ internal struct EvtRpcLogin public string Domain; public CoTaskMemUnicodeSafeHandle Password; public int Flags; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(EvtRpcLogin), MarshalMode.ManagedToUnmanagedRef, typeof(ValueMarshaller))] public static class Marshaller { @@ -695,7 +695,7 @@ internal static partial bool EvtRender( out int buffUsed, out int propCount); -#if NET7_0_OR_GREATER +#if NET [NativeMarshalling(typeof(Marshaller))] #endif [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)] @@ -708,7 +708,7 @@ internal struct EvtStringVariant [FieldOffset(12)] public uint Type; -#if NET7_0_OR_GREATER +#if NET [CustomMarshaller(typeof(EvtStringVariant), MarshalMode.Default, typeof(Marshaller))] public static class Marshaller { diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj b/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj index cdadf742e3d976..fa358a2a90893b 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj +++ b/src/libraries/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.Tests/System.Diagnostics.FileVersionInfo.Tests.csproj @@ -52,6 +52,7 @@ - + + diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs index f6b7737ef81ab2..2f7e0847782aca 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs @@ -13,7 +13,7 @@ using Microsoft.Win32; using static Interop.Advapi32; -#if !NETCOREAPP +#if !NET using MemoryMarshal = System.Diagnostics.PerformanceCounterLib; #endif @@ -120,7 +120,7 @@ internal static string ComputerName } } -#if !NETCOREAPP +#if !NET internal static T Read(ReadOnlySpan span) where T : struct => System.Runtime.InteropServices.MemoryMarshal.Read(span); diff --git a/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System/Diagnostics/XmlWriterTraceListener.cs b/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System/Diagnostics/XmlWriterTraceListener.cs index a513b8aa86159c..e5b72a51d41132 100644 --- a/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System/Diagnostics/XmlWriterTraceListener.cs +++ b/src/libraries/System.Diagnostics.TextWriterTraceListener/src/System/Diagnostics/XmlWriterTraceListener.cs @@ -16,7 +16,7 @@ public class XmlWriterTraceListener : TextWriterTraceListener { private const string FixedHeader = ""; - private static volatile string? s_processName; + private static string? s_processName; private readonly string _machineName = Environment.MachineName; private StringBuilder? _strBldr; private XmlTextWriter? _xmlBlobWriter; @@ -252,13 +252,15 @@ private void WriteEndHeader() { if (OperatingSystem.IsBrowser()) // Process isn't supported on Browser { - s_processName = processName = string.Empty; + processName = string.Empty; } else { using Process process = Process.GetCurrentProcess(); - s_processName = processName = process.ProcessName; + processName = process.ProcessName; } + + s_processName = processName; } InternalWrite("\" />"); diff --git a/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourcePropertyValueTest.cs b/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourcePropertyValueTest.cs index 6682cb0fd45eb8..e98a84a45ae888 100644 --- a/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourcePropertyValueTest.cs +++ b/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourcePropertyValueTest.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; /// @@ -34,6 +35,7 @@ private class TestEventSource : EventSource public TestEventSource() : base(EventSourceSettings.EtwSelfDescribingEventFormat) { } [Event(1)] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(TestSubData))] public void LogData(TestData data) { Write("LogData", data); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs index fb663740108b08..422c37e70dbb30 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs @@ -22,7 +22,7 @@ public static bool IsLibLdapInstalled { get { -#if NETCOREAPP +#if NET if (!_isLibLdapInstalled.HasValue) { if (PlatformDetection.IsApplePlatform) diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.cs index 48ae19cce80c90..e13d5ddfd6f7b0 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.cs @@ -100,7 +100,7 @@ public override int GetByteCount(string s) } public -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 override #endif int GetByteCount(ReadOnlySpan chars) @@ -135,7 +135,7 @@ public override unsafe int GetCharCount(byte* bytes, int count) } public -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 override #endif int GetCharCount(ReadOnlySpan bytes) @@ -435,7 +435,7 @@ public override int GetByteCount(string s) return s_utf8Encoding.GetByteCount(s); } -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 public override int GetByteCount(ReadOnlySpan chars) { return s_utf8Encoding.GetByteCount(chars); @@ -476,7 +476,7 @@ public override unsafe int GetCharCount(byte* bytes, int count) } } -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 public override int GetCharCount(ReadOnlySpan bytes) { try diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Integer.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Integer.cs index 102b05b82fb368..35372824d35e20 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Integer.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Integer.cs @@ -104,7 +104,7 @@ public static BigInteger ReadInteger( { ReadOnlySpan contents = ReadIntegerBytes(source, ruleSet, out int consumed, expectedTag); -#if NETCOREAPP2_1_OR_GREATER +#if NET BigInteger value = new BigInteger(contents, isBigEndian: true); #else byte[] tmp = CryptoPool.Rent(contents.Length); diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs index fac90e12aec1c2..33e5a0adb1c986 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnDecoder.Oid.cs @@ -61,7 +61,7 @@ public static string ReadObjectIdentifier( UniversalTagNumber.ObjectIdentifier, out int consumed); -#if NETCOREAPP +#if NET string? wellKnown = WellKnownOids.GetValue(contents); if (wellKnown is not null) diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Integer.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Integer.cs index 389196c0acd261..b1720b5106b2cd 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Integer.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Integer.cs @@ -281,7 +281,7 @@ private void WriteIntegerCore(Asn1Tag tag, BigInteger value) Debug.Assert(!tag.IsConstructed); WriteTag(tag); -#if NETCOREAPP2_1_OR_GREATER +#if NET WriteLength(value.GetByteCount()); // WriteLength ensures the content-space value.TryWriteBytes(_buffer.AsSpan(_offset), out int bytesWritten, isBigEndian: true); diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Oid.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Oid.cs index 7c046016c531b2..04a063a11fdc31 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Oid.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnWriter.Oid.cs @@ -59,7 +59,7 @@ public void WriteObjectIdentifier(ReadOnlySpan oidValue, Asn1Tag? tag = nu { CheckUniversalTag(tag, UniversalTagNumber.ObjectIdentifier); -#if NETCOREAPP +#if NET ReadOnlySpan wellKnownContents = WellKnownOids.GetContents(oidValue); if (!wellKnownContents.IsEmpty) diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/SetOfValueComparer.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/SetOfValueComparer.cs index 44b6c3030957e8..d766b5008c324c 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/SetOfValueComparer.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/SetOfValueComparer.cs @@ -17,7 +17,7 @@ internal static int Compare(ReadOnlySpan x, ReadOnlySpan y) int min = Math.Min(x.Length, y.Length); int diff; -#if NET7_0_OR_GREATER +#if NET int diffIndex = x.CommonPrefixLength(y); if (diffIndex != min) diff --git a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/WellKnownOids.cs b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/WellKnownOids.cs index c308c5af7fd5db..215dbe5eb846f1 100644 --- a/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/WellKnownOids.cs +++ b/src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/WellKnownOids.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NETCOREAPP +#if NET namespace System.Formats.Asn1 { internal static class WellKnownOids diff --git a/src/libraries/System.Formats.Asn1/tests/Reader/ReadIA5String.cs b/src/libraries/System.Formats.Asn1/tests/Reader/ReadIA5String.cs index b7a74a95c3ff60..b11db277363c88 100644 --- a/src/libraries/System.Formats.Asn1/tests/Reader/ReadIA5String.cs +++ b/src/libraries/System.Formats.Asn1/tests/Reader/ReadIA5String.cs @@ -678,7 +678,7 @@ public static void ExpectedTag_IgnoresConstructed( Assert.Equal(val1.ByteArrayToHex(), val2.ByteArrayToHex()); -#if NETCOREAPP +#if NET string expected = Encoding.ASCII.GetString(val1.Span); #else string expected = Encoding.ASCII.GetString(val1.ToArray()); diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborConformanceLevel.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborConformanceLevel.cs index b31bbbcd62a2a3..b46066f061a5bc 100644 --- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborConformanceLevel.cs +++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborConformanceLevel.cs @@ -207,7 +207,7 @@ public static bool RequireCanonicalSimpleValueEncodings(CborConformanceMode conf public static int GetKeyEncodingHashCode(ReadOnlySpan encoding) { HashCode hash = default; -#if NETCOREAPP +#if NET hash.AddBytes(encoding); #else while (encoding.Length >= sizeof(int)) diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.cs index 988b79dae85f47..9354a772f64fde 100644 --- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.cs +++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.cs @@ -241,7 +241,7 @@ private void EnsureWriteCapacity(int pendingCount) { int newCapacity = currentCapacity == 0 ? 1024 : currentCapacity * 2; const uint MaxArrayLength = 0x7FFFFFC7; // Array.MaxLength -#if NETCOREAPP +#if NET Debug.Assert(MaxArrayLength == Array.MaxLength); #endif if ((uint)newCapacity > MaxArrayLength || newCapacity < requiredCapacity) diff --git a/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.TextString.cs b/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.TextString.cs index 4f6acad8e5287c..314592bb6f0099 100644 --- a/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.TextString.cs +++ b/src/libraries/System.Formats.Cbor/tests/Reader/CborReaderTests.TextString.cs @@ -106,7 +106,7 @@ public static void TryReadTextString_IndefiniteLengthConcatenated_SingleValue__H Assert.True(result); Assert.Equal(expectedValue.Length, charsWritten); Assert.Equal(expectedValue, new string(buffer.Slice(0, charsWritten) -#if !NETCOREAPP +#if !NET .ToArray() #endif )); @@ -136,7 +136,7 @@ public static void TryReadTextString_BufferTooSmall_ShouldReturnFalse(string act Assert.True(result); Assert.Equal(actualValue.Length, charsWritten); Assert.Equal(actualValue, new string(buffer.AsSpan(0, charsWritten) -#if !NETCOREAPP +#if !NET .ToArray() #endif )); @@ -162,7 +162,7 @@ public static void TryReadTextString_IndefiniteLengthConcatenated_BufferTooSmall Assert.True(result); Assert.Equal(expectedValue.Length, charsWritten); Assert.Equal(expectedValue, new string(buffer.AsSpan(0, charsWritten) -#if !NETCOREAPP +#if !NET .ToArray() #endif )); @@ -184,7 +184,7 @@ public static void ReadDefiniteLengthTextStringBytes_SingleValue_HappyPath(strin ReadOnlyMemory resultBytes = reader.ReadDefiniteLengthTextStringBytes(); string result = Encoding.UTF8.GetString(resultBytes.Span -#if !NETCOREAPP +#if !NET .ToArray() #endif ); diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj index e120f89518cc3f..03cbd816a2ff71 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj @@ -95,7 +95,7 @@ - + diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs index 3a844a60637b07..260bf0bdadb374 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32.cs @@ -169,7 +169,7 @@ public static uint HashToUInt32(ReadOnlySpan source) => private static uint Update(uint crc, ReadOnlySpan source) { -#if NET7_0_OR_GREATER +#if NET if (CanBeVectorized(source)) { return UpdateVectorized(crc, source); @@ -181,7 +181,7 @@ private static uint Update(uint crc, ReadOnlySpan source) private static uint UpdateScalar(uint crc, ReadOnlySpan source) { -#if NET6_0_OR_GREATER +#if NET // Use ARM intrinsics for CRC if available. This is used for the trailing bytes on the vectorized path // and is the primary method if the vectorized path is unavailable. if (System.Runtime.Intrinsics.Arm.Crc32.Arm64.IsSupported) diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.cs index e9993a7503e787..89b81c657c518c 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64.cs @@ -167,7 +167,7 @@ public static ulong HashToUInt64(ReadOnlySpan source) => private static ulong Update(ulong crc, ReadOnlySpan source) { -#if NET7_0_OR_GREATER +#if NET if (CanBeVectorized(source)) { return UpdateVectorized(crc, source); diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/NonCryptographicHashAlgorithm.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/NonCryptographicHashAlgorithm.cs index c11622efbbd2f1..9b18216370a11f 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/NonCryptographicHashAlgorithm.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/NonCryptographicHashAlgorithm.cs @@ -156,7 +156,7 @@ private async Task AppendAsyncCore(Stream stream, CancellationToken cancellation while (true) { -#if NETCOREAPP +#if NET int read = await stream.ReadAsync(buffer.AsMemory(), cancellationToken).ConfigureAwait(false); #else int read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash128.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash128.cs index fdfd24a60ab1f4..e1181cb73f914d 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash128.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash128.cs @@ -17,7 +17,7 @@ namespace System.IO.Hashing /// For methods that persist the computed numerical hash value as bytes, /// the value is written in the Big Endian byte order. /// -#if NET5_0_OR_GREATER +#if NET [SkipLocalsInit] #endif public sealed unsafe class XxHash128 : NonCryptographicHashAlgorithm @@ -51,7 +51,7 @@ public XxHash128(long seed) : base(HashLengthInBytes) /// is null. public static byte[] Hash(byte[] source, long seed) { -#if NET6_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(source); #else if (source is null) @@ -110,7 +110,7 @@ public static bool TryHash(ReadOnlySpan source, Span destination, ou return false; } -#if NET7_0_OR_GREATER +#if NET /// Computes the XXH128 hash of the provided data. /// The data to hash. /// The seed value for this hash computation. The default is zero. @@ -197,7 +197,7 @@ private Hash128 GetCurrentHashAsHash128() return current; } -#if NET7_0_OR_GREATER +#if NET /// Gets the current computed hash value without modifying accumulated state. /// The hash value for the data already provided. [CLSCompliant(false)] diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash3.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash3.cs index 702409b949d451..affdfe78d6a850 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash3.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHash3.cs @@ -16,7 +16,7 @@ namespace System.IO.Hashing /// For methods that persist the computed numerical hash value as bytes, /// the value is written in the Big Endian byte order. /// -#if NET5_0_OR_GREATER +#if NET [SkipLocalsInit] #endif public sealed unsafe class XxHash3 : NonCryptographicHashAlgorithm @@ -50,7 +50,7 @@ public XxHash3(long seed) : base(HashLengthInBytes) /// is null. public static byte[] Hash(byte[] source, long seed) { -#if NET6_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(source); #else if (source is null) diff --git a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHashShared.cs b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHashShared.cs index bfdf1963ac3b02..cafa80dbbf112e 100644 --- a/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHashShared.cs +++ b/src/libraries/System.IO.Hashing/src/System/IO/Hashing/XxHashShared.cs @@ -6,7 +6,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if NET7_0_OR_GREATER +#if NET using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; @@ -15,7 +15,7 @@ namespace System.IO.Hashing { /// Shared implementation of the XXH3 hash algorithm for 64-bit in and version. -#if NET5_0_OR_GREATER +#if NET [SkipLocalsInit] #endif internal static unsafe class XxHashShared @@ -333,7 +333,7 @@ public static void CopyAccumulators(ref State state, ulong* accumulators) { fixed (ulong* stateAccumulators = state.Accumulators) { -#if NET7_0_OR_GREATER +#if NET if (Vector256.IsHardwareAccelerated) { Vector256.Store(Vector256.Load(stateAccumulators), accumulators); @@ -390,7 +390,7 @@ public static void DigestLong(ref State state, ulong* accumulators, byte* secret [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void InitializeAccumulators(ulong* accumulators) { -#if NET7_0_OR_GREATER +#if NET if (Vector256.IsHardwareAccelerated) { Vector256.Store(Vector256.Create(Prime32_3, Prime64_1, Prime64_2, Prime64_3), accumulators); @@ -452,7 +452,7 @@ public static ulong Avalanche(ulong hash) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong Multiply64To128(ulong left, ulong right, out ulong lower) { -#if NET5_0_OR_GREATER +#if NET return Math.BigMul(left, right, out lower); #else ulong lowerLow = Multiply32To64((uint)left, (uint)right); @@ -479,7 +479,7 @@ public static void DeriveSecretFromSeed(byte* destinationSecret, ulong seed) { fixed (byte* defaultSecret = &MemoryMarshal.GetReference(DefaultSecret)) { -#if NET7_0_OR_GREATER +#if NET if (Vector256.IsHardwareAccelerated && BitConverter.IsLittleEndian) { Vector256 seedVec = Vector256.Create(seed, 0u - seed, seed, 0u - seed); @@ -515,7 +515,7 @@ private static void Accumulate(ulong* accumulators, byte* source, byte* secret, byte* secretForAccumulate = secret; byte* secretForScramble = secret + (SecretLengthBytes - StripeLengthBytes); -#if NET7_0_OR_GREATER +#if NET if (Vector256.IsHardwareAccelerated && BitConverter.IsLittleEndian) { Vector256 acc1 = Vector256.Load(accumulators); @@ -620,7 +620,7 @@ public static void Accumulate512(ulong* accumulators, byte* source, byte* secret [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Accumulate512Inlined(ulong* accumulators, byte* source, byte* secret) { -#if NET7_0_OR_GREATER +#if NET if (Vector256.IsHardwareAccelerated && BitConverter.IsLittleEndian) { for (int i = 0; i < AccumulatorCount / Vector256.Count; i++) @@ -659,7 +659,7 @@ private static void Accumulate512Inlined(ulong* accumulators, byte* source, byte } } -#if NET7_0_OR_GREATER +#if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 Accumulate256(Vector256 accVec, byte* source, Vector256 secret) { @@ -714,7 +714,7 @@ private static Vector128 MultiplyWideningLower(Vector128 source) private static void ScrambleAccumulators(ulong* accumulators, byte* secret) { -#if NET7_0_OR_GREATER +#if NET if (Vector256.IsHardwareAccelerated && BitConverter.IsLittleEndian) { for (int i = 0; i < AccumulatorCount / Vector256.Count; i++) @@ -752,7 +752,7 @@ private static void ScrambleAccumulators(ulong* accumulators, byte* secret) } } -#if NET7_0_OR_GREATER +#if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 ScrambleAccumulator256(Vector256 accVec, Vector256 secret) { diff --git a/src/libraries/System.IO.Hashing/tests/NonCryptoHashTestDriver.cs b/src/libraries/System.IO.Hashing/tests/NonCryptoHashTestDriver.cs index f2d8e411533ec7..3204d93d4fb577 100644 --- a/src/libraries/System.IO.Hashing/tests/NonCryptoHashTestDriver.cs +++ b/src/libraries/System.IO.Hashing/tests/NonCryptoHashTestDriver.cs @@ -334,7 +334,7 @@ protected TestCaseBase(string name, byte[] output) internal static string ToHexString(ReadOnlySpan input) { -#if NETCOREAPP +#if NET return Convert.ToHexString(input); #else var builder = new global::System.Text.StringBuilder(input.Length * 2); @@ -350,7 +350,7 @@ internal static string ToHexString(ReadOnlySpan input) internal static byte[] FromHexString(string hexString) { -#if NETCOREAPP +#if NET return Convert.FromHexString(hexString); #else byte[] bytes = new byte[hexString.Length / 2]; @@ -420,7 +420,7 @@ public LargeTestCase(string name, byte data, long repeatCount, string outputHex) public IEnumerable> EnumerateDataChunks() { -#if NET5_0_OR_GREATER +#if NET byte[] chunk = GC.AllocateUninitializedArray(1024 * 1024); #else byte[] chunk = new byte[1024 * 1024]; diff --git a/src/libraries/System.IO.Hashing/tests/XxHash128Tests.cs b/src/libraries/System.IO.Hashing/tests/XxHash128Tests.cs index 8d32a6f06c1d2d..3ba2044d069505 100644 --- a/src/libraries/System.IO.Hashing/tests/XxHash128Tests.cs +++ b/src/libraries/System.IO.Hashing/tests/XxHash128Tests.cs @@ -41,7 +41,7 @@ public void Hash_OneShot_Expected() Assert.Equal(expectedHash128, ReadHashBigEndian(XxHash128.Hash(input, test.Seed))); Assert.Equal(expectedHash128, ReadHashBigEndian(XxHash128.Hash((ReadOnlySpan)input, test.Seed))); -#if NET7_0_OR_GREATER +#if NET // Validate `XxHash128.HashToUInt128` Assert.Equal(new UInt128(test.HashHigh, test.HashLow), XxHash128.HashToUInt128(input, test.Seed)); #endif @@ -110,7 +110,7 @@ public void Hash_Streaming_Expected() // Validate that the hash we get from doing a one-shot of all the data up to this point // matches the incremental hash for the data appended until now. -#if NET7_0_OR_GREATER +#if NET Assert.Equal(XxHash128.HashToUInt128(asciiBytes.AsSpan(0, processed), test.Seed), hash.GetCurrentHashAsUInt128()); #endif Assert.True(hash.TryGetCurrentHash(destination, out int bytesWritten)); @@ -120,7 +120,7 @@ public void Hash_Streaming_Expected() } // Validate the final hash code. -#if NET7_0_OR_GREATER +#if NET Assert.Equal(new UInt128(test.HashHigh, test.HashLow), hash.GetCurrentHashAsUInt128()); #endif Array.Clear(destination, 0, destination.Length); diff --git a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj index 3b224099af7611..a11a0d7077cc65 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj +++ b/src/libraries/System.IO.IsolatedStorage/src/System.IO.IsolatedStorage.csproj @@ -46,6 +46,7 @@ + diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs index b2ace96c807391..d76b0972d017ce 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs @@ -320,7 +320,7 @@ private void ProcessRelationshipAttributes(XmlCompatibilityReader reader) { try { -#if NET6_0_OR_GREATER +#if NET relationshipTargetMode = Enum.Parse(targetModeAttributeValue, ignoreCase: false); #else relationshipTargetMode = (TargetMode)(Enum.Parse(typeof(TargetMode), targetModeAttributeValue, ignoreCase: false)); diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs index 2707afbf4b5391..8bf3d1e5a0e8b5 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs @@ -285,7 +285,7 @@ private static string EscapeSpecialCharacters(string path) // This is currently enforced by the order of characters in the s_specialCharacterChars array foreach (char c in s_specialCharacterChars) { -#if NET5_0_OR_GREATER +#if NET if (path.Contains(c)) #else if (path.IndexOf(c) != -1) diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipWrappingStream.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipWrappingStream.cs index e3f3b42e775310..2a50857af0e3f2 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipWrappingStream.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipWrappingStream.cs @@ -67,7 +67,7 @@ int count return _baseStream.Read(buffer, offset, count); } -#if NETCOREAPP +#if NET public override void Write( ReadOnlySpan buffer ) diff --git a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeReader.cs b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeReader.cs index 747d23e778f87a..0b4d13593a03f6 100644 --- a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeReader.cs +++ b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeReader.cs @@ -171,7 +171,7 @@ public override void Complete(Exception? exception = null) } } -#if NETCOREAPP +#if NET public override ValueTask CompleteAsync(Exception? exception = null) => CompleteAndGetNeedsDispose() ? InnerStream.DisposeAsync() : default; #endif @@ -239,7 +239,7 @@ private ValueTask ReadInternalAsync(int? minimumSize, CancellationTo return Core(this, minimumSize, tokenSource, cancellationToken); -#if NETCOREAPP +#if NET [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))] #endif static async ValueTask Core(StreamPipeReader reader, int? minimumSize, CancellationTokenSource tokenSource, CancellationToken cancellationToken) diff --git a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeWriter.cs b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeWriter.cs index c065df5cd1a10b..6f5731a9fbb07f 100644 --- a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeWriter.cs +++ b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeWriter.cs @@ -286,7 +286,7 @@ private void Cancel() InternalTokenSource.Cancel(); } -#if NETCOREAPP +#if NET [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))] #endif private async ValueTask FlushAsyncInternal(bool writeToStream, ReadOnlyMemory data, CancellationToken cancellationToken = default) diff --git a/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledReadsStream.cs b/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledReadsStream.cs index 0b925b337a7482..dc6c6474f1fcd4 100644 --- a/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledReadsStream.cs +++ b/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledReadsStream.cs @@ -24,7 +24,7 @@ public override async Task ReadAsync(byte[] buffer, int offset, int count, return 0; } -#if NETCOREAPP +#if NET public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) { await WaitForReadTask.Task; diff --git a/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledWritesStream.cs b/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledWritesStream.cs index a0e15629cee1d6..a3bde09cad0a27 100644 --- a/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledWritesStream.cs +++ b/src/libraries/System.IO.Pipelines/tests/Infrastructure/CancelledWritesStream.cs @@ -23,7 +23,7 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc cancellationToken.ThrowIfCancellationRequested(); } -#if NETCOREAPP +#if NET public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { await WaitForWriteTask.Task; diff --git a/src/libraries/System.IO.Pipelines/tests/Infrastructure/ThrowAfterNWritesStream.cs b/src/libraries/System.IO.Pipelines/tests/Infrastructure/ThrowAfterNWritesStream.cs index b46d0c233ea37a..72640a70e4f730 100644 --- a/src/libraries/System.IO.Pipelines/tests/Infrastructure/ThrowAfterNWritesStream.cs +++ b/src/libraries/System.IO.Pipelines/tests/Infrastructure/ThrowAfterNWritesStream.cs @@ -32,7 +32,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati return Task.CompletedTask; } -#if NETCOREAPP +#if NET public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { if (_writes >= _maxWrites) diff --git a/src/libraries/System.IO.Pipelines/tests/PipeReaderCopyToAsyncTests.cs b/src/libraries/System.IO.Pipelines/tests/PipeReaderCopyToAsyncTests.cs index 21228b2a1bf726..3c524de5122365 100644 --- a/src/libraries/System.IO.Pipelines/tests/PipeReaderCopyToAsyncTests.cs +++ b/src/libraries/System.IO.Pipelines/tests/PipeReaderCopyToAsyncTests.cs @@ -349,7 +349,7 @@ public override void Write(byte[] buffer, int offset, int count) Check(count); base.Write(buffer, offset, count); } -#if NETCOREAPP3_0_OR_GREATER +#if NET public override void Write(ReadOnlySpan buffer) { Check(buffer.Length); diff --git a/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderTests.cs b/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderTests.cs index f70373c58fefd3..f9fb1f87dbafba 100644 --- a/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderTests.cs +++ b/src/libraries/System.IO.Pipelines/tests/StreamPipeReaderTests.cs @@ -614,7 +614,7 @@ public async Task CompleteCallsAppropriateDisposeMethodOnUnderlyingStream() stream = new(); reader = PipeReader.Create(stream); await reader.CompleteAsync(); -#if NETCOREAPP +#if NET Assert.False(stream.DisposeCalled); Assert.True(stream.DisposeAsyncCalled); #else @@ -661,7 +661,7 @@ public override Task ReadAsync(byte[] buffer, int offset, int count, Cancel { throw new OperationCanceledException(); } -#if NETCOREAPP +#if NET public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) { throw new OperationCanceledException(); @@ -696,7 +696,7 @@ public override async Task ReadAsync(byte[] buffer, int offset, int count, return bytes; } -#if NETCOREAPP +#if NET public override async ValueTask ReadAsync(Memory destination, CancellationToken cancellationToken = default) { if (_throwOnNextCallToRead) @@ -723,7 +723,7 @@ protected override void Dispose(bool disposing) DisposeCalled = true; } -#if NETCOREAPP +#if NET public override ValueTask DisposeAsync() { DisposeAsyncCalled = true; diff --git a/src/libraries/System.IO.Pipelines/tests/StreamPipeWriterTests.cs b/src/libraries/System.IO.Pipelines/tests/StreamPipeWriterTests.cs index 6b158f8fdb2256..3a812857822df6 100644 --- a/src/libraries/System.IO.Pipelines/tests/StreamPipeWriterTests.cs +++ b/src/libraries/System.IO.Pipelines/tests/StreamPipeWriterTests.cs @@ -661,7 +661,7 @@ public override Task FlushAsync(CancellationToken cancellationToken) throw new OperationCanceledException(); } -#if NETCOREAPP +#if NET public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { throw new OperationCanceledException(); diff --git a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj index fcd66e7adf9a64..6e48d964b2744e 100644 --- a/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj +++ b/src/libraries/System.IO.Pipes.AccessControl/src/System.IO.Pipes.AccessControl.csproj @@ -19,6 +19,7 @@ Condition="'$(TargetPlatformIdentifier)' == 'windows'" /> + diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.Unix.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.Unix.cs index edcf919c2ea684..65bbba57685a21 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.Unix.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.Unix.cs @@ -13,7 +13,7 @@ public partial class SerialPort : Component { public static string[] GetPortNames() { -#if NETCOREAPP +#if NET return OperatingSystem.IsLinux() ? GetPortNames_Linux() : OperatingSystem.IsAndroid() ? GetPortNames_Linux() : OperatingSystem.IsMacOS() ? GetPortNames_OSX() diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs index 752163fd2bd379..426eb77d637d5b 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs @@ -963,7 +963,7 @@ public string ReadExisting() Buffer.BlockCopy(_inBuffer, _readPos, bytesReceived, 0, CachedBytesToRead); } -#if NET7_0_OR_GREATER +#if NET _internalSerialStream.ReadExactly(bytesReceived, CachedBytesToRead, bytesReceived.Length - CachedBytesToRead); // get everything #else int readCount = bytesReceived.Length - CachedBytesToRead; diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs index 398eb2817a1d91..fa79f2a9c1e0ea 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs @@ -562,7 +562,7 @@ internal SerialStream(string portName, int baudRate, Parity parity, int dataBits if (!portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase) || !uint.TryParse( -#if NETCOREAPP +#if NET portName.AsSpan(3), #else portName.Substring(3), diff --git a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj index 9213e4c6c944fe..66a070211ddca4 100644 --- a/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj +++ b/src/libraries/System.Linq.Expressions/src/System.Linq.Expressions.csproj @@ -219,6 +219,7 @@ + diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs index b1446848ce6174..9a1c951c1b184f 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Numerics; using System.Threading; namespace System.Dynamic.Utils @@ -40,27 +41,11 @@ internal Entry(int hash, TKey key, TValue value) /// The maximum number of elements to store will be this number aligned to next ^2. internal CacheDict(int size) { - int alignedSize = AlignSize(size); + int alignedSize = (int)BitOperations.RoundUpToPowerOf2((uint)size); _mask = alignedSize - 1; _entries = new Entry[alignedSize]; } - private static int AlignSize(int size) - { - Debug.Assert(size > 0); - - size--; - size |= size >> 1; - size |= size >> 2; - size |= size >> 4; - size |= size >> 8; - size |= size >> 16; - size++; - - Debug.Assert((size & (~size + 1)) == size, "aligned size should be a power of 2"); - return size; - } - /// /// Tries to get the value associated with 'key', returning true if it's found and /// false if it's not present. diff --git a/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj b/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj index 3d7f38289ac0aa..15ff9887505a59 100644 --- a/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj +++ b/src/libraries/System.Linq.Parallel/src/System.Linq.Parallel.csproj @@ -157,6 +157,7 @@ + diff --git a/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj b/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj index 8298f938086124..343028ced1ad2a 100644 --- a/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj +++ b/src/libraries/System.Linq.Queryable/src/System.Linq.Queryable.csproj @@ -19,6 +19,7 @@ + diff --git a/src/libraries/System.Linq/tests/System.Linq.Tests.csproj b/src/libraries/System.Linq/tests/System.Linq.Tests.csproj index 33d584fe8f6a15..1e4692999a1743 100644 --- a/src/libraries/System.Linq/tests/System.Linq.Tests.csproj +++ b/src/libraries/System.Linq/tests/System.Linq.Tests.csproj @@ -5,7 +5,8 @@ - + + diff --git a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj index 4f8e58e36abfbb..ef01da51d137d3 100644 --- a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj @@ -53,6 +53,7 @@ System.Net.Http.Json.JsonContent + @@ -65,6 +66,7 @@ System.Net.Http.Json.JsonContent + diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.cs index 2d033b206872e6..4223cf3e064109 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.cs @@ -95,7 +95,7 @@ public static partial class HttpClientJsonExtensions { // Matches how HttpClient throws a timeout exception. string message = SR.Format(SR.net_http_request_timedout, client.Timeout.TotalSeconds); -#if NETCOREAPP +#if NET throw new TaskCanceledException(message, new TimeoutException(oce.Message, oce), oce.CancellationToken); #else throw new TaskCanceledException(message, new TimeoutException(oce.Message, oce)); diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs index 539df6d3d43f22..179cb829ef52df 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs @@ -114,7 +114,7 @@ private Task SerializeToStreamAsyncCore(Stream targetStream, CancellationToken c private async Task SerializeToStreamAsyncTranscoding(Stream targetStream, bool async, Encoding targetEncoding, CancellationToken cancellationToken) { // Wrap provided stream into a transcoding stream that buffers the data transcoded from utf-8 to the targetEncoding. -#if NETCOREAPP +#if NET Stream transcodingStream = Encoding.CreateTranscodingStream(targetStream, targetEncoding, Encoding.UTF8, leaveOpen: true); try { diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/LengthLimitReadStream.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/LengthLimitReadStream.cs index 9837587958a927..b40d400f89fb56 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/LengthLimitReadStream.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/LengthLimitReadStream.cs @@ -37,7 +37,7 @@ internal static void ThrowExceededBufferLimit(int limit) public override bool CanSeek => _innerStream.CanSeek; public override bool CanWrite => false; -#if NETCOREAPP +#if NET public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => ReadAsync(new Memory(buffer, offset, count), cancellationToken).AsTask(); diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs index fee02cc8822950..a57b1cf24f5162 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs @@ -478,7 +478,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => Exception ex = await Assert.ThrowsAsync(() => useDeleteAsync ? client.DeleteFromJsonAsync(uri) : client.GetFromJsonAsync(uri)); -#if NETCOREAPP +#if NET Assert.Contains("HttpClient.Timeout", ex.Message); Assert.IsType(ex.InnerException); #endif @@ -526,7 +526,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri => } }); -#if NETCOREAPP +#if NET Assert.Contains("HttpClient.Timeout", ex.Message); Assert.IsType(ex.InnerException); #endif diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/NoWriteNoSeekStreamContent.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/NoWriteNoSeekStreamContent.cs index 047ef52edbb562..67992f6b25c4b2 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/NoWriteNoSeekStreamContent.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/NoWriteNoSeekStreamContent.cs @@ -29,7 +29,7 @@ protected override Task SerializeToStreamAsync(Stream stream, TransportContext? SerializeToStreamAsync(stream, context, CancellationToken.None); #pragma warning disable IDE0060 -#if NETCOREAPP +#if NET protected override #else internal diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs index dccbaea01da0b5..5482588aa2f5e6 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs @@ -154,7 +154,7 @@ private async Task CopyToAsyncCore(Stream destination, byte[] buffer, Cancellati Debug.Assert(bytesRead > 0); // Write that data out to the output stream -#if NETSTANDARD2_1 || NETCOREAPP +#if NETSTANDARD2_1 || NET await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false); #else await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false); diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTrailersHelper.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTrailersHelper.cs index 2bf4de4e34eb37..e4f4257a366feb 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTrailersHelper.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTrailersHelper.cs @@ -11,7 +11,7 @@ namespace System.Net.Http internal static class WinHttpTrailersHelper { // UNITTEST is true when building against WinHttpHandler.Unit.Tests, which includes the source file. -#if !NETSTANDARD2_1 && !NETCOREAPP && !UNITTEST +#if !NETSTANDARD2_1 && !NET && !UNITTEST // Trailer property name was chosen to be descriptive and be unlikely to collide with a user set property. // Apps and libraries will use this key so it shouldn't change. private const string RequestMessagePropertyName = "__ResponseTrailers"; @@ -24,7 +24,7 @@ private sealed class HttpResponseTrailers : HttpHeaders public static HttpHeaders GetResponseTrailers(HttpResponseMessage response) { -#if NETSTANDARD2_1 || NETCOREAPP || UNITTEST +#if NETSTANDARD2_1 || NET || UNITTEST return response.TrailingHeaders; #else HttpResponseTrailers responseTrailers = new HttpResponseTrailers(); diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs index b75571770fa9ec..0d2165eda36e91 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/PlatformHandlerTest.cs @@ -82,7 +82,7 @@ public sealed class PlatformHandler_HttpClientEKUTest : HttpClientEKUTest public PlatformHandler_HttpClientEKUTest(ITestOutputHelper output) : base(output) { } } -#if NETCOREAPP +#if NET public sealed class PlatformHandler_HttpClientHandler_Decompression_Tests : HttpClientHandler_Decompression_Test { public PlatformHandler_HttpClientHandler_Decompression_Tests(ITestOutputHelper output) : base(output) { } @@ -182,7 +182,7 @@ public sealed class PlatformHandler_HttpClientHandler_Authentication_Test : Http public PlatformHandler_HttpClientHandler_Authentication_Test(ITestOutputHelper output) : base(output) { } } -#if NETCOREAPP +#if NET #if !WINHTTPHANDLER_TEST // [ActiveIssue("https://github.com/dotnet/runtime/issues/33930")] [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows10Version1607OrGreater))] public sealed class PlatformHandlerTest_Cookies_Http2 : HttpClientHandlerTest_Cookies diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 7db63948a28513..e4ffec94743f35 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -164,6 +164,8 @@ Link="Common\System\Text\ValueStringBuilder.AppendSpanFormattable.cs" /> + @@ -216,6 +218,7 @@ + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs index 4b04787d3acdce..0d647385f996ca 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.AnyMobile.cs @@ -776,15 +776,10 @@ protected internal override Task SendAsync(HttpRequestMessa // lazy-load the validator func so it can be trimmed by the ILLinker if it isn't used. private static Func? s_dangerousAcceptAnyServerCertificateValidator; [UnsupportedOSPlatform("browser")] - public static Func DangerousAcceptAnyServerCertificateValidator - { - get - { - return Volatile.Read(ref s_dangerousAcceptAnyServerCertificateValidator) ?? - Interlocked.CompareExchange(ref s_dangerousAcceptAnyServerCertificateValidator, delegate { return true; }, null) ?? - s_dangerousAcceptAnyServerCertificateValidator; - } - } + public static Func DangerousAcceptAnyServerCertificateValidator => + s_dangerousAcceptAnyServerCertificateValidator ?? + Interlocked.CompareExchange(ref s_dangerousAcceptAnyServerCertificateValidator, delegate { return true; }, null) ?? + s_dangerousAcceptAnyServerCertificateValidator; private void ThrowForModifiedManagedSslOptionsIfStarted() { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs index 9c3935701e82f9..7a6edd71053bb6 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs @@ -363,7 +363,7 @@ protected internal override Task SendAsync(HttpRequestMessa private static Func? s_dangerousAcceptAnyServerCertificateValidator; [UnsupportedOSPlatform("browser")] public static Func DangerousAcceptAnyServerCertificateValidator => - Volatile.Read(ref s_dangerousAcceptAnyServerCertificateValidator) ?? + s_dangerousAcceptAnyServerCertificateValidator ?? Interlocked.CompareExchange(ref s_dangerousAcceptAnyServerCertificateValidator, delegate { return true; }, null) ?? s_dangerousAcceptAnyServerCertificateValidator; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs index 639e0367ba5aa7..69f01907167c7e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs @@ -215,11 +215,12 @@ private static async ValueTask SendWithAuthAsync(HttpReques // If preauth is enabled and this isn't proxy auth, try to get a basic credential from the // preauth credentials cache, and if successful, set an auth header for it onto the request. // Currently we only support preauth for Basic. - bool performedBasicPreauth = false; + NetworkCredential? preAuthCredential = null; + Uri? preAuthCredentialUri = null; if (preAuthenticate) { Debug.Assert(pool.PreAuthCredentials != null); - NetworkCredential? credential; + (Uri uriPrefix, NetworkCredential credential)? preAuthCredentialPair; lock (pool.PreAuthCredentials) { // Just look for basic credentials. If in the future we support preauth @@ -227,13 +228,13 @@ private static async ValueTask SendWithAuthAsync(HttpReques Debug.Assert(pool.PreAuthCredentials.GetCredential(authUri, NegotiateScheme) == null); Debug.Assert(pool.PreAuthCredentials.GetCredential(authUri, NtlmScheme) == null); Debug.Assert(pool.PreAuthCredentials.GetCredential(authUri, DigestScheme) == null); - credential = pool.PreAuthCredentials.GetCredential(authUri, BasicScheme); + preAuthCredentialPair = pool.PreAuthCredentials.GetCredential(authUri, BasicScheme); } - if (credential != null) + if (preAuthCredentialPair != null) { - SetBasicAuthToken(request, credential, isProxyAuth); - performedBasicPreauth = true; + (preAuthCredentialUri, preAuthCredential) = preAuthCredentialPair.Value; + SetBasicAuthToken(request, preAuthCredential, isProxyAuth); } } @@ -265,13 +266,21 @@ await TrySetDigestAuthToken(request, challenge.Credential, digestResponse, isPro break; case AuthenticationType.Basic: - if (performedBasicPreauth) + if (preAuthCredential != null) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.AuthenticationError(authUri, $"Pre-authentication with {(isProxyAuth ? "proxy" : "server")} failed."); } - break; + + if (challenge.Credential == preAuthCredential) + { + // Pre auth failed, and user supplied credentials are still same, we can stop there. + break; + } + + // Pre-auth credentials have changed, continue with the new ones. + // The old ones will be removed below. } response.Dispose(); @@ -293,6 +302,17 @@ await TrySetDigestAuthToken(request, challenge.Credential, digestResponse, isPro default: lock (pool.PreAuthCredentials!) { + // remove previously cached (failing) creds + if (preAuthCredentialUri != null) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(pool.PreAuthCredentials, $"Removing Basic credential from cache, uri={preAuthCredentialUri}, username={preAuthCredential!.UserName}"); + } + + pool.PreAuthCredentials.Remove(preAuthCredentialUri, BasicScheme); + } + try { if (NetEventSource.Log.IsEnabled()) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs index 1cff8e9ad39516..0d9f3a2a1b9537 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionPool/HttpConnectionPool.cs @@ -59,7 +59,7 @@ internal sealed partial class HttpConnectionPool : IDisposable private SslClientAuthenticationOptions? _sslOptionsHttp3; private readonly SslClientAuthenticationOptions? _sslOptionsProxy; - private readonly CredentialCache? _preAuthCredentials; + private readonly PreAuthCredentialCache? _preAuthCredentials; /// Whether the pool has been used since the last time a cleanup occurred. private bool _usedSinceLastCleanup = true; @@ -237,7 +237,7 @@ public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionK // Set up for PreAuthenticate. Access to this cache is guarded by a lock on the cache itself. if (_poolManager.Settings._preAuthenticate) { - _preAuthCredentials = new CredentialCache(); + _preAuthCredentials = new PreAuthCredentialCache(); } _http11RequestQueue = new RequestQueue(); @@ -296,7 +296,7 @@ private static SslClientAuthenticationOptions ConstructSslOptions(HttpConnection public bool IsSecure => _kind == HttpConnectionKind.Https || _kind == HttpConnectionKind.SslProxyTunnel || _kind == HttpConnectionKind.SslSocksTunnel; public Uri? ProxyUri => _proxyUri; public ICredentials? ProxyCredentials => _poolManager.ProxyCredentials; - public CredentialCache? PreAuthCredentials => _preAuthCredentials; + public PreAuthCredentialCache? PreAuthCredentials => _preAuthCredentials; public bool IsDefaultPort => OriginAuthority.Port == (IsSecure ? DefaultHttpsPort : DefaultHttpPort); private bool DoProxyAuth => (_kind == HttpConnectionKind.Proxy || _kind == HttpConnectionKind.ProxyConnect); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs index a4e8efeca6412e..75b9d9b1f8a964 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs @@ -300,6 +300,11 @@ internal Exception Abort(Exception abortException) private void OnServerGoAway(long firstRejectedStreamId) { + if (NetEventSource.Log.IsEnabled()) + { + Trace($"GOAWAY received. First rejected stream ID = {firstRejectedStreamId}"); + } + // Stop sending requests to this connection. _pool.InvalidateHttp3Connection(this); @@ -649,6 +654,10 @@ private async Task ProcessServerControlStreamAsync(QuicStream stream, ArrayBuffe case Http3FrameType.ReservedHttp2Ping: case Http3FrameType.ReservedHttp2WindowUpdate: case Http3FrameType.ReservedHttp2Continuation: + if (NetEventSource.Log.IsEnabled()) + { + Trace($"Received reserved frame: {frameType}"); + } throw HttpProtocolException.CreateHttp3ConnectionException(Http3ErrorCode.UnexpectedFrame); case Http3FrameType.PushPromise: case Http3FrameType.CancelPush: @@ -663,6 +672,10 @@ private async Task ProcessServerControlStreamAsync(QuicStream stream, ArrayBuffe } if (!shuttingDown) { + if (NetEventSource.Log.IsEnabled()) + { + Trace($"Control stream closed by the server."); + } throw HttpProtocolException.CreateHttp3ConnectionException(Http3ErrorCode.ClosedCriticalStream); } return; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/PreAuthCredentialCache.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/PreAuthCredentialCache.cs new file mode 100644 index 00000000000000..1f4dcc54fb0c2c --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/PreAuthCredentialCache.cs @@ -0,0 +1,61 @@ +// 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; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; + +namespace System.Net.Http +{ + internal sealed class PreAuthCredentialCache + { + private Dictionary? _cache; + + public void Add(Uri uriPrefix, string authType, NetworkCredential cred) + { + Debug.Assert(uriPrefix != null); + Debug.Assert(authType != null); + + var key = new CredentialCacheKey(uriPrefix, authType); + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Adding key:[{key}], cred:[{cred.Domain}],[{cred.UserName}]"); + + _cache ??= new Dictionary(); + _cache.Add(key, cred); + } + + public void Remove(Uri uriPrefix, string authType) + { + Debug.Assert(uriPrefix != null); + Debug.Assert(authType != null); + + if (_cache == null) + { + return; + } + + var key = new CredentialCacheKey(uriPrefix, authType); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Removing key:[{key}]"); + _cache.Remove(key); + } + + public (Uri uriPrefix, NetworkCredential credential)? GetCredential(Uri uriPrefix, string authType) + { + Debug.Assert(uriPrefix != null); + Debug.Assert(authType != null); + + if (_cache == null) + { + return null; + } + + CredentialCacheHelper.TryGetCredential(_cache, uriPrefix, authType, out Uri? mostSpecificMatchUri, out NetworkCredential? mostSpecificMatch); + + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Returning {(mostSpecificMatch == null ? "null" : "(" + mostSpecificMatch.UserName + ":" + mostSpecificMatch.Domain + ")")}"); + + return mostSpecificMatch == null ? null : (mostSpecificMatchUri!, mostSpecificMatch!); + } + } +} diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index f71efde6631058..d6a53a33e2342e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -8,6 +8,8 @@ using System.Net.Test.Common; using System.Net.Quic; +using Microsoft.DotNet.XUnitExtensions; + namespace System.Net.Http.Functional.Tests { public abstract class HttpClientHandler_AltSvc_Test : HttpClientHandlerTestBase @@ -27,10 +29,15 @@ private HttpClient CreateHttpClient(Version version) return client; } - [Theory] + [ConditionalTheory] [MemberData(nameof(AltSvcHeaderUpgradeVersions))] public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overrideHost) { + if (UseVersion == HttpVersion30 && fromVersion == HttpVersion.Version11 && overrideHost) + { + throw new SkipTestException("https://github.com/dotnet/runtime/issues/91757"); + } + // The test makes a request to a HTTP/1 or HTTP/2 server first, which supplies an Alt-Svc header pointing to the second server. using GenericLoopbackServer firstServer = fromVersion.Major switch @@ -71,9 +78,14 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri { HttpVersion.Version20, false } }; - [Fact] + [ConditionalFact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { + if (UseVersion == HttpVersion30) + { + throw new SkipTestException("https://github.com/dotnet/runtime/issues/101376"); + } + using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); using HttpClient client = CreateHttpClient(HttpVersion.Version20); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.BasicAuth.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.BasicAuth.cs new file mode 100644 index 00000000000000..a6ac590fb6adcf --- /dev/null +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.BasicAuth.cs @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Linq; +using System.Net.Test.Common; +using System.Text; +using System.Threading.Tasks; + +using Microsoft.DotNet.XUnitExtensions; +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.Http.Functional.Tests +{ + [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + public class HttpClientHandlerTest_BasicAuth : HttpClientHandlerTestBase + { + public HttpClientHandlerTest_BasicAuth(ITestOutputHelper output) : base(output) + { + } + + protected override Version UseVersion => HttpVersion.Version20; + + [Fact] + public async Task RefreshesPreAuthCredentialsOnChange() + { + CredentialPlugin credentialPlugin = new CredentialPlugin(); + + using Http2LoopbackServer server = Http2LoopbackServer.CreateServer(); + server.AllowMultipleConnections = true; + + HttpClientHandler handler = CreateHttpClientHandler(); + handler.PreAuthenticate = true; + handler.Credentials = credentialPlugin; + using HttpClient client = CreateHttpClient(handler); + + Task sendTask = client.GetAsync(server.Address); + + async Task GetAuth(GenericLoopbackConnection connection) + { + HttpRequestData data = await connection.ReadRequestDataAsync(); + HttpHeaderData? header = data.Headers.FirstOrDefault(h => string.Equals(h.Name, "Authorization", StringComparison.OrdinalIgnoreCase)); + + if (header == null) + { + return ""; + } + + return Encoding.UTF8.GetString(Convert.FromBase64String(header.Value.Value.Replace("Basic", "", StringComparison.OrdinalIgnoreCase))); + } + + await server.HandleRequestAsync(HttpStatusCode.Unauthorized, headers: new[] { new HttpHeaderData("WWW-Authenticate", "Basic realm=\"test\"") }); + await server.AcceptConnectionAsync(async conn => + { + Assert.Equal("username:password", await GetAuth(conn)); + await conn.SendResponseAsync(HttpStatusCode.OK); + }).WaitAsync(TimeSpan.FromSeconds(30)); + + HttpResponseMessage response = await sendTask; + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + // change password and try again + credentialPlugin.ChangePassword(); + sendTask = client.GetAsync(server.Address); + + // first one reuses the cached credentials -> 401 + await server.AcceptConnectionAsync(async conn => + { + Assert.Equal("username:password", await GetAuth(conn)); + await conn.SendResponseAsync(HttpStatusCode.Unauthorized, headers: new[] { new HttpHeaderData("WWW-Authenticate", "Basic realm=\"test\"") }); + }).WaitAsync(TimeSpan.FromSeconds(30)); + + // client should try again with correct credentials + await server.AcceptConnectionAsync(async conn => + { + Assert.Equal("username:password1", await GetAuth(conn)); + await conn.SendResponseAsync(HttpStatusCode.OK); + }).WaitAsync(TimeSpan.FromSeconds(30)); + + response = await sendTask; + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + } + + internal class CredentialPlugin : ICredentials + { + public CredentialPlugin() + { + UserName = "username"; + counter = 0; + Password = "password"; + } + + private int counter; + public string UserName { get; private set; } + public string Password { get; private set; } + + public void ChangePassword() + { + counter++; + Password = "password" + counter; + } + + NetworkCredential? ICredentials.GetCredential(Uri uri, string authType) + { + if (authType == "Basic") + { + return new NetworkCredential(UserName, Password); + } + + return null; + } + } +} diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs index 663e3e3a4e1483..cbd74f8188a20f 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs @@ -13,6 +13,8 @@ using Xunit; using Xunit.Abstractions; +using Microsoft.DotNet.XUnitExtensions; + namespace System.Net.Http.Functional.Tests { using Configuration = System.Net.Test.Common.Configuration; @@ -24,6 +26,7 @@ public HttpClientHandlerTest_Headers(ITestOutputHelper output) : base(output) { private sealed class DerivedHttpHeaders : HttpHeaders { } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task SendAsync_RequestWithSimpleHeader_ResponseReferencesUnmodifiedRequestHeaders() { const string HeaderKey = "some-header-123", HeaderValue = "this is the expected header value"; @@ -71,6 +74,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task SendAsync_LargeHeaders_CorrectlyWritten() { if (UseVersion == HttpVersion.Version30) @@ -106,6 +110,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task SendAsync_DefaultHeaders_CorrectlyWritten() { const string Version = "2017-04-17"; @@ -167,6 +172,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData("Accept-CharSet", "text/plain, text/json", false)] // invalid format for header but added with TryAddWithoutValidation [InlineData("Content-Location", "", false)] // invalid format for header but added with TryAddWithoutValidation [InlineData("Max-Forwards", "NotAnInteger", false)] // invalid format for header but added with TryAddWithoutValidation + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task SendAsync_SpecialHeaderKeyOrValue_Success(string key, string value, bool parsable) { if (PlatformDetection.IsBrowser && (key == "Content-Location" || key == "Date" || key == "Accept-CharSet")) @@ -283,12 +289,17 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }); } - [Theory] + [ConditionalTheory] [InlineData("Thu, 01 Dec 1994 16:00:00 GMT", true)] [InlineData("-1", false)] [InlineData("0", false)] public async Task SendAsync_Expires_Success(string value, bool isValid) { + if (UseVersion == HttpVersion30) + { + throw new SkipTestException("https://github.com/dotnet/runtime/issues/91757"); + } + await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using (HttpClient client = CreateHttpClient()) @@ -349,6 +360,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [Theory] [InlineData(false)] [InlineData(true)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task SendAsync_GetWithValidHostHeader_Success(bool withPort) { if (UseVersion == HttpVersion.Version30) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http1.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http1.cs index b3949e548e7ccc..b57e3812784599 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http1.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http1.cs @@ -17,6 +17,7 @@ public class HttpClientHandlerTest_Http1 : HttpClientHandlerTestBase public HttpClientHandlerTest_Http1(ITestOutputHelper output) : base(output) { } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotNodeJS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task SendAsync_HostHeader_First() { // RFC 7230 3.2.2. Field Order diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.RequestRetry.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.RequestRetry.cs index 4e2426b958e658..8198fb8818a08e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.RequestRetry.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.RequestRetry.cs @@ -170,7 +170,7 @@ public SynchronizedSendContent(TaskCompletionSource sendingContent, Task c _sendingContent = sendingContent; } -#if NETCOREAPP +#if NET protected override void SerializeToStream(Stream stream, TransportContext context, CancellationToken cancellationToken) => SerializeToStreamAsync(stream, context).GetAwaiter().GetResult(); #endif diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs index 888b38b813127e..088e57294d54b2 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTestBase.SocketsHttpHandler.cs @@ -96,7 +96,7 @@ protected static LoopbackServerFactory GetFactoryForVersion(Version useVersion) { return useVersion.Major switch { -#if NETCOREAPP +#if NET #if HTTP3 3 => Http3LoopbackServerFactory.Singleton, #endif diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs index 0dd1a485894d6b..d62566f1dd1b4a 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpRequestMessageTest.cs @@ -239,6 +239,7 @@ public void ToString_DefaultAndNonDefaultInstance_DumpAllFields() [InlineData("OPTIONS")] [InlineData("HEAD")] [ActiveIssue("https://github.com/dotnet/runtime/issues/86317", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task HttpRequest_BodylessMethod_NoContentLength(string method) { using (HttpClient client = CreateHttpClient()) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index c0eda6ab1a57ed..f91fc2dda1dd3c 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -1633,6 +1633,7 @@ public SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http2(ITest protected override Version UseVersion => HttpVersion.Version20; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] [ActiveIssue("https://github.com/dotnet/runtime/issues/91757")] [ActiveIssue("https://github.com/dotnet/runtime/issues/101015")] @@ -3994,6 +3995,7 @@ public SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http11(ITestOutputHe [InlineData("foo", "\tbar\t")] [InlineData("foo", "\t bar \t")] [InlineData("foo ", " \t bar \r\n ")] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task ResponseHeaders_ExtraWhitespace_Trimmed(string name, string value) { await LoopbackServer.CreateClientAndServerAsync(async uri => @@ -4026,6 +4028,7 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http2(ITestOutputH protected override Version UseVersion => HttpVersion.Version20; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Http3 : HttpClientHandlerTest { @@ -4033,13 +4036,19 @@ public SocketsHttpHandlerTest_HttpClientHandlerTest_Http3(ITestOutputHelper outp protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_Cookies_Http3 : HttpClientHandlerTest_Cookies { public SocketsHttpHandlerTest_Cookies_Http3(ITestOutputHelper output) : base(output) { } protected override Version UseVersion => HttpVersion.Version30; + + [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/91757")] + public override Task GetAsync_DefaultCoookieContainer_NoCookieSent() { return null!; } } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3 : HttpClientHandlerTest_Headers { @@ -4047,6 +4056,7 @@ public SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3(ITestOutputHel protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3 : SocketsHttpHandler_Cancellation_Test { @@ -4054,6 +4064,7 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3(ITestOutputH protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3 : HttpClientHandler_AltSvc_Test { @@ -4061,6 +4072,7 @@ public SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3(ITestOutputHelper protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_Finalization_Http3 : HttpClientHandler_Finalization_Test { @@ -4225,6 +4237,7 @@ public SocketsHttpHandler_RequestContentLengthMismatchTest_Http2(ITestOutputHelp protected override Version UseVersion => HttpVersion.Version20; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_RequestContentLengthMismatchTest_Http3 : SocketsHttpHandler_RequestContentLengthMismatchTest { @@ -4401,6 +4414,7 @@ public SocketsHttpHandler_SocketsHttpHandler_SecurityTest_Http2(ITestOutputHelpe protected override Version UseVersion => HttpVersion.Version20; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_SocketsHttpHandler_SecurityTest_Http3 : SocketsHttpHandler_SecurityTest { @@ -4529,6 +4543,7 @@ await Http11LoopbackServerFactory.Singleton.CreateClientAndServerAsync(async uri } } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpRequestErrorTest_Http30 : SocketsHttpHandler_HttpRequestErrorTest { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index fd09f7db0b2282..0256d1d53a4517 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -245,6 +245,7 @@ + diff --git a/src/libraries/System.Net.Http/tests/TrimmingTests/System.Net.Http.TrimmingTests.proj b/src/libraries/System.Net.Http/tests/TrimmingTests/System.Net.Http.TrimmingTests.proj index ca55774a5ac45d..ea8bfeffaa4bbb 100644 --- a/src/libraries/System.Net.Http/tests/TrimmingTests/System.Net.Http.TrimmingTests.proj +++ b/src/libraries/System.Net.Http/tests/TrimmingTests/System.Net.Http.TrimmingTests.proj @@ -5,6 +5,8 @@ browser-wasm + + true diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs index de2197321e5355..8a99feaeec369f 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs @@ -85,8 +85,7 @@ internal static unsafe NetworkInterface[] GetNetworkInterfaces() List interfaceList = new List(); Interop.IpHlpApi.GetAdaptersAddressesFlags flags = - Interop.IpHlpApi.GetAdaptersAddressesFlags.IncludeGateways - | Interop.IpHlpApi.GetAdaptersAddressesFlags.IncludeWins; + Interop.IpHlpApi.GetAdaptersAddressesFlags.IncludeAllInterfaces; // Figure out the right buffer size for the adapter information. uint result = Interop.IpHlpApi.GetAdaptersAddresses( diff --git a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkInterfaceBasicTest.cs b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkInterfaceBasicTest.cs index dcb12e8b7f87b0..5d5167be739f8e 100644 --- a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkInterfaceBasicTest.cs +++ b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkInterfaceBasicTest.cs @@ -22,6 +22,7 @@ public NetworkInterfaceBasicTest(ITestOutputHelper output) [Fact] public void BasicTest_GetNetworkInterfaces_AtLeastOne() { + Assert.NotEqual(0, NetworkInterface.GetAllNetworkInterfaces().Length); } @@ -50,7 +51,8 @@ public void BasicTest_AccessInstanceProperties_NoExceptions() if (nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet) { - Assert.Equal(6, nic.GetPhysicalAddress().GetAddressBytes().Length); + var physicalAddressLength = nic.GetPhysicalAddress().GetAddressBytes().Length; + Assert.True(physicalAddressLength == 0 || physicalAddressLength == 6); } } } diff --git a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj index a659207964a3e8..e71aaa8222e300 100644 --- a/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj +++ b/src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj @@ -82,6 +82,8 @@ Link="Common\System\Text\StringBuilderCache.cs" /> + diff --git a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs index 8e21138d1b58f5..b25a5df1db2d1c 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs @@ -63,7 +63,7 @@ public sealed class Cookie private bool m_secure; // Do not rename (binary serialization) [System.Runtime.Serialization.OptionalField] private bool m_httpOnly = false; // Do not rename (binary serialization) - private DateTime m_timeStamp = DateTime.Now; // Do not rename (binary serialization) + private DateTime m_timeStamp = DateTime.UtcNow; // Do not rename (binary serialization) private string m_value = string.Empty; // Do not rename (binary serialization) private int m_version; // Do not rename (binary serialization) @@ -199,13 +199,13 @@ public bool Expired { get { - return (m_expires != DateTime.MinValue) && (m_expires.ToLocalTime() <= DateTime.Now); + return (m_expires != DateTime.MinValue) && (m_expires.ToUniversalTime() <= DateTime.UtcNow); } set { if (value) { - m_expires = DateTime.Now; + m_expires = DateTime.UtcNow; } } } @@ -801,7 +801,7 @@ internal void ToString(StringBuilder sb) } if (Expires != DateTime.MinValue) { - int seconds = (int)(Expires.ToLocalTime() - DateTime.Now).TotalSeconds; + int seconds = (int)(Expires.ToUniversalTime() - DateTime.UtcNow).TotalSeconds; if (seconds < 0) { // This means that the cookie has already expired. Set Max-Age to 0 diff --git a/src/libraries/System.Net.Primitives/src/System/Net/CredentialCache.cs b/src/libraries/System.Net.Primitives/src/System/Net/CredentialCache.cs index 8cb88371227919..8e46d4ab6c529d 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/CredentialCache.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/CredentialCache.cs @@ -13,7 +13,7 @@ namespace System.Net // name-password pairs and associates these with host/realm. public class CredentialCache : ICredentials, ICredentialsByHost, IEnumerable { - private Dictionary? _cache; + private Dictionary? _cache; private Dictionary? _cacheForHosts; private int _version; @@ -37,11 +37,11 @@ public void Add(Uri uriPrefix, string authType, NetworkCredential cred) ++_version; - var key = new CredentialKey(uriPrefix, authType); + var key = new CredentialCacheKey(uriPrefix, authType); if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Adding key:[{key}], cred:[{cred.Domain}],[{cred.UserName}]"); - _cache ??= new Dictionary(); + _cache ??= new Dictionary(); _cache.Add(key, cred); } @@ -88,7 +88,7 @@ public void Remove(Uri? uriPrefix, string? authType) ++_version; - var key = new CredentialKey(uriPrefix, authType); + var key = new CredentialCacheKey(uriPrefix, authType); if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Removing key:[{key}]"); @@ -135,28 +135,7 @@ public void Remove(string? host, int port, string? authenticationType) return null; } - int longestMatchPrefix = -1; - NetworkCredential? mostSpecificMatch = null; - - // Enumerate through every credential in the cache - foreach (KeyValuePair pair in _cache) - { - CredentialKey key = pair.Key; - - // Determine if this credential is applicable to the current Uri/AuthType - if (key.Match(uriPrefix, authType)) - { - int prefixLen = key.UriPrefixLength; - - // Check if the match is better than the current-most-specific match - if (prefixLen > longestMatchPrefix) - { - // Yes: update the information about currently preferred match - longestMatchPrefix = prefixLen; - mostSpecificMatch = pair.Value; - } - } - } + CredentialCacheHelper.TryGetCredential(_cache, uriPrefix, authType, out _ /*uri*/, out NetworkCredential? mostSpecificMatch); if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Returning {(mostSpecificMatch == null ? "null" : "(" + mostSpecificMatch.UserName + ":" + mostSpecificMatch.Domain + ")")}"); @@ -201,7 +180,7 @@ internal static CredentialEnumerator Create(CredentialCache cache) { return cache._cacheForHosts != null ? new DoubleTableCredentialEnumerator(cache) : - new SingleTableCredentialEnumerator(cache, cache._cache); + new SingleTableCredentialEnumerator(cache, cache._cache); } else { @@ -286,7 +265,7 @@ public override void Reset() } } - private sealed class DoubleTableCredentialEnumerator : SingleTableCredentialEnumerator + private sealed class DoubleTableCredentialEnumerator : SingleTableCredentialEnumerator { private Dictionary.ValueCollection.Enumerator _enumerator; // mutable struct field deliberately not readonly. private bool _onThisEnumerator; @@ -406,95 +385,4 @@ public override bool Equals([NotNullWhen(true)] object? obj) => public override string ToString() => string.Create(CultureInfo.InvariantCulture, $"{Host}:{Port}:{AuthenticationType}"); } - - internal sealed class CredentialKey : IEquatable - { - public readonly Uri UriPrefix; - public readonly int UriPrefixLength = -1; - public readonly string AuthenticationType; - - internal CredentialKey(Uri uriPrefix, string authenticationType) - { - Debug.Assert(uriPrefix != null); - Debug.Assert(authenticationType != null); - - UriPrefix = uriPrefix; - UriPrefixLength = UriPrefix.ToString().Length; - AuthenticationType = authenticationType; - } - - internal bool Match(Uri uri, string authenticationType) - { - if (uri == null || authenticationType == null) - { - return false; - } - - // If the protocols don't match, this credential is not applicable for the given Uri. - if (!string.Equals(authenticationType, AuthenticationType, StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Match({UriPrefix} & {uri})"); - - return IsPrefix(uri, UriPrefix); - } - - // IsPrefix (Uri) - // - // Determines whether is a prefix of this URI. A prefix - // match is defined as: - // - // scheme match - // + host match - // + port match, if any - // + path is a prefix of path, if any - // - // Returns: - // True if is a prefix of this URI - private static bool IsPrefix(Uri uri, Uri prefixUri) - { - Debug.Assert(uri != null); - Debug.Assert(prefixUri != null); - - if (prefixUri.Scheme != uri.Scheme || prefixUri.Host != uri.Host || prefixUri.Port != uri.Port) - { - return false; - } - - int prefixLen = prefixUri.AbsolutePath.LastIndexOf('/'); - if (prefixLen > uri.AbsolutePath.LastIndexOf('/')) - { - return false; - } - - return string.Compare(uri.AbsolutePath, 0, prefixUri.AbsolutePath, 0, prefixLen, StringComparison.OrdinalIgnoreCase) == 0; - } - - public override int GetHashCode() => - StringComparer.OrdinalIgnoreCase.GetHashCode(AuthenticationType) ^ - UriPrefix.GetHashCode(); - - public bool Equals([NotNullWhen(true)] CredentialKey? other) - { - if (other == null) - { - return false; - } - - bool equals = - string.Equals(AuthenticationType, other.AuthenticationType, StringComparison.OrdinalIgnoreCase) && - UriPrefix.Equals(other.UriPrefix); - - if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Equals({this},{other}) returns {equals}"); - - return equals; - } - - public override bool Equals([NotNullWhen(true)] object? obj) => Equals(obj as CredentialKey); - - public override string ToString() => - string.Create(CultureInfo.InvariantCulture, $"[{UriPrefixLength}]:{UriPrefix}:{AuthenticationType}"); - } } diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs index 1ba710d4f46e86..11fa3ba37026ee 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieTest.cs @@ -116,10 +116,10 @@ public static void Expired_GetSet_Success() Cookie c = new Cookie(); Assert.False(c.Expired); - c.Expires = DateTime.Now.AddDays(-1); + c.Expires = DateTime.UtcNow.AddDays(-1); Assert.True(c.Expired); - c.Expires = DateTime.Now.AddDays(1); + c.Expires = DateTime.UtcNow.AddDays(1); Assert.False(c.Expired); c.Expired = true; @@ -135,7 +135,7 @@ public static void Expires_GetSet_Success() Cookie c = new Cookie(); Assert.Equal(c.Expires, DateTime.MinValue); - DateTime dt = DateTime.Now; + DateTime dt = DateTime.UtcNow; c.Expires = dt; Assert.Equal(dt, c.Expires); } @@ -226,7 +226,9 @@ public static void Secure_GetSet_Success() [Fact] public static void Timestamp_GetSet_Success() { - DateTime dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, 0); //DateTime.Now changes as the test runs + //DateTime.UtcNow changes as the test runs + DateTime dt = DateTime.UtcNow; + dt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0); Cookie c = new Cookie(); Assert.True(c.TimeStamp >= dt); } diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CredentialCacheTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CredentialCacheTest.cs index a67967b36811c7..6895fabba4f1b9 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CredentialCacheTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CredentialCacheTest.cs @@ -272,6 +272,17 @@ public static void GetCredential_SimilarUriAuthenticationType_GetLongestUriPrefi Assert.Equal(nc, credential2); } + [Fact] + public static void GetCredential_LongerUriButShorterMatch() + { + CredentialCache cc = new CredentialCache(); + cc.Add(new Uri("http://microsoft:80/common/unique/something"), authenticationType1, credential2); + cc.Add(new Uri("http://microsoft:80/common/veryloooooongprefix"), authenticationType1, credential1); + + NetworkCredential nc = cc.GetCredential(new Uri("http://microsoft:80/common/unique/a"), authenticationType1); + Assert.Equal(nc, credential2); + } + [Fact] public static void GetCredential_UriAuthenticationType_Invalid() { diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs index 4fc86adfbd1565..38a02cad2328b5 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs @@ -21,6 +21,7 @@ internal static partial class MsQuicConfiguration private const string DisableCacheCtxSwitch = "System.Net.Quic.DisableConfigurationCache"; internal static bool ConfigurationCacheEnabled { get; } = GetConfigurationCacheEnabled(); + private static bool GetConfigurationCacheEnabled() { // AppContext switch takes precedence @@ -28,15 +29,15 @@ private static bool GetConfigurationCacheEnabled() { return !value; } - else + // check environment variable second + else if (Environment.GetEnvironmentVariable(DisableCacheEnvironmentVariable) is string envVar) { - // check environment variable - return - Environment.GetEnvironmentVariable(DisableCacheEnvironmentVariable) is string envVar && - !(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)); + return !(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)); } - } + // enabled by default + return true; + } private static readonly ConcurrentDictionary s_configurationCache = new(); private readonly struct CacheKey : IEquatable diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicExtensions.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicExtensions.cs index 5c079f65287415..cfc5a09a37171c 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicExtensions.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicExtensions.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Net.Quic; namespace Microsoft.Quic; @@ -17,7 +18,7 @@ public override string ToString() => Type switch { QUIC_LISTENER_EVENT_TYPE.NEW_CONNECTION - => $"{{ {nameof(NEW_CONNECTION.Info)} = {{ {nameof(QUIC_NEW_CONNECTION_INFO.QuicVersion)} = {NEW_CONNECTION.Info->QuicVersion}, {nameof(QUIC_NEW_CONNECTION_INFO.LocalAddress)} = {MsQuicHelpers.QuicAddrToIPEndPoint(NEW_CONNECTION.Info->LocalAddress)}, {nameof(QUIC_NEW_CONNECTION_INFO.RemoteAddress)} = {MsQuicHelpers.QuicAddrToIPEndPoint(NEW_CONNECTION.Info->RemoteAddress)} }} }}", + => $"{{ {nameof(NEW_CONNECTION.Info)} = {{ {nameof(QUIC_NEW_CONNECTION_INFO.QuicVersion)} = {NEW_CONNECTION.Info->QuicVersion}, {nameof(QUIC_NEW_CONNECTION_INFO.LocalAddress)} = {MsQuicHelpers.QuicAddrToIPEndPoint(NEW_CONNECTION.Info->LocalAddress)}, {nameof(QUIC_NEW_CONNECTION_INFO.RemoteAddress)} = {MsQuicHelpers.QuicAddrToIPEndPoint(NEW_CONNECTION.Info->RemoteAddress)} }}, {nameof(NEW_CONNECTION.Connection)} = 0x{(IntPtr)NEW_CONNECTION.Connection:X11} }}", _ => string.Empty }; } @@ -40,9 +41,29 @@ public override string ToString() QUIC_CONNECTION_EVENT_TYPE.PEER_ADDRESS_CHANGED => $"{{ {nameof(PEER_ADDRESS_CHANGED.Address)} = {MsQuicHelpers.QuicAddrToIPEndPoint(PEER_ADDRESS_CHANGED.Address)} }}", QUIC_CONNECTION_EVENT_TYPE.PEER_STREAM_STARTED - => $"{{ {nameof(PEER_STREAM_STARTED.Flags)} = {PEER_STREAM_STARTED.Flags} }}", + => $"{{ {nameof(PEER_STREAM_STARTED.Stream)} = 0x{(IntPtr)PEER_STREAM_STARTED.Stream:X11} {nameof(PEER_STREAM_STARTED.Flags)} = {PEER_STREAM_STARTED.Flags} }}", + QUIC_CONNECTION_EVENT_TYPE.STREAMS_AVAILABLE + => $"{{ {nameof(STREAMS_AVAILABLE.BidirectionalCount)} = {STREAMS_AVAILABLE.BidirectionalCount}, {nameof(STREAMS_AVAILABLE.UnidirectionalCount)} = {STREAMS_AVAILABLE.UnidirectionalCount} }}", + QUIC_CONNECTION_EVENT_TYPE.PEER_NEEDS_STREAMS + => $"{{ {nameof(PEER_NEEDS_STREAMS.Bidirectional)} = {PEER_NEEDS_STREAMS.Bidirectional} }}", + QUIC_CONNECTION_EVENT_TYPE.IDEAL_PROCESSOR_CHANGED + => $"{{ {nameof(IDEAL_PROCESSOR_CHANGED.IdealProcessor)} = {IDEAL_PROCESSOR_CHANGED.IdealProcessor}, {nameof(IDEAL_PROCESSOR_CHANGED.PartitionIndex)} = {IDEAL_PROCESSOR_CHANGED.PartitionIndex} }}", + QUIC_CONNECTION_EVENT_TYPE.DATAGRAM_STATE_CHANGED + => $"{{ {nameof(DATAGRAM_STATE_CHANGED.SendEnabled)} = {DATAGRAM_STATE_CHANGED.SendEnabled}, {nameof(DATAGRAM_STATE_CHANGED.MaxSendLength)} = {DATAGRAM_STATE_CHANGED.MaxSendLength} }}", + QUIC_CONNECTION_EVENT_TYPE.DATAGRAM_RECEIVED + => $"{{ {nameof(DATAGRAM_RECEIVED.Flags)} = {DATAGRAM_RECEIVED.Flags} }}", + QUIC_CONNECTION_EVENT_TYPE.DATAGRAM_SEND_STATE_CHANGED + => $"{{ {nameof(DATAGRAM_SEND_STATE_CHANGED.ClientContext)} = 0x{(IntPtr)DATAGRAM_SEND_STATE_CHANGED.ClientContext:X11}, {nameof(DATAGRAM_SEND_STATE_CHANGED.State)} = {DATAGRAM_SEND_STATE_CHANGED.State} }}", + QUIC_CONNECTION_EVENT_TYPE.RESUMED + => $"{{ {nameof(RESUMED.ResumptionStateLength)} = {RESUMED.ResumptionStateLength} }}", + QUIC_CONNECTION_EVENT_TYPE.RESUMPTION_TICKET_RECEIVED + => $"{{ {nameof(RESUMPTION_TICKET_RECEIVED.ResumptionTicketLength)} = {RESUMPTION_TICKET_RECEIVED.ResumptionTicketLength} }}", QUIC_CONNECTION_EVENT_TYPE.PEER_CERTIFICATE_RECEIVED - => $"{{ {nameof(PEER_CERTIFICATE_RECEIVED.DeferredStatus)} = {PEER_CERTIFICATE_RECEIVED.DeferredStatus}, {nameof(PEER_CERTIFICATE_RECEIVED.DeferredErrorFlags)} = {PEER_CERTIFICATE_RECEIVED.DeferredErrorFlags} }}", + => $"{{ {nameof(PEER_CERTIFICATE_RECEIVED.DeferredStatus)} = {PEER_CERTIFICATE_RECEIVED.DeferredStatus}, {nameof(PEER_CERTIFICATE_RECEIVED.DeferredErrorFlags)} = {PEER_CERTIFICATE_RECEIVED.DeferredErrorFlags}, {nameof(PEER_CERTIFICATE_RECEIVED.Certificate)} = 0x{(IntPtr)PEER_CERTIFICATE_RECEIVED.Certificate:X11} }}", + QUIC_CONNECTION_EVENT_TYPE.RELIABLE_RESET_NEGOTIATED + => $"{{ {nameof(RELIABLE_RESET_NEGOTIATED.IsNegotiated)} = {RELIABLE_RESET_NEGOTIATED.IsNegotiated} }}", + QUIC_CONNECTION_EVENT_TYPE.ONE_WAY_DELAY_NEGOTIATED + => $"{{ {nameof(ONE_WAY_DELAY_NEGOTIATED.SendNegotiated)} = {ONE_WAY_DELAY_NEGOTIATED.SendNegotiated}, {nameof(ONE_WAY_DELAY_NEGOTIATED.ReceiveNegotiated)} = {ONE_WAY_DELAY_NEGOTIATED.ReceiveNegotiated} }}", _ => string.Empty }; } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicSafeHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicSafeHandle.cs index cf7d70a18e08d1..8e70ec20572454 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicSafeHandle.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicSafeHandle.cs @@ -88,7 +88,7 @@ internal sealed class MsQuicContextSafeHandle : MsQuicSafeHandle /// Holds a weak reference to the managed instance. /// It allows delegating MsQuic events to the managed object while it still can be collected and finalized. /// - private readonly GCHandle _context; + private GCHandle _context; /// /// Optional parent safe handle, used to increment/decrement reference count with the lifetime of this instance. diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs index 114c39c49c1e5e..bb1cc7d25b7b3e 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/ThrowHelper.cs @@ -27,13 +27,27 @@ internal static QuicException GetOperationAbortedException(string? message = nul return new QuicException(QuicError.OperationAborted, null, message ?? SR.net_quic_operationaborted); } - internal static bool TryGetStreamExceptionForMsQuicStatus(int status, [NotNullWhen(true)] out Exception? exception) + internal static bool TryGetStreamExceptionForMsQuicStatus(int status, [NotNullWhen(true)] out Exception? exception, bool streamWasSuccessfullyStarted = true, string? message = null) { if (status == QUIC_STATUS_ABORTED) { - // If status == QUIC_STATUS_ABORTED, we will receive an event later, which will complete the task source. - exception = null; - return false; + // Connection has been closed by the peer (either at transport or application level), + if (streamWasSuccessfullyStarted) + { + // we will receive an event later, which will complete the stream with concrete + // information why the connection was aborted. + exception = null; + return false; + } + else + { + // we won't be receiving any event callback for shutdown on this stream, so we don't + // necessarily know which error to report. So we throw an exception which we can distinguish + // at the caller (ConnectionAborted normally has App error code) and throw the correct + // exception from there. + exception = new QuicException(QuicError.ConnectionAborted, null, ""); + return true; + } } else if (status == QUIC_STATUS_INVALID_STATE) { @@ -43,13 +57,16 @@ internal static bool TryGetStreamExceptionForMsQuicStatus(int status, [NotNullWh } else if (StatusFailed(status)) { - exception = GetExceptionForMsQuicStatus(status); + exception = GetExceptionForMsQuicStatus(status, message: message); return true; } exception = null; return false; } + // see TryGetStreamExceptionForMsQuicStatus for explanation + internal static bool IsConnectionAbortedWhenStartingStreamException(Exception ex) => ex is QuicException qe && qe.QuicError == QuicError.ConnectionAborted && qe.ApplicationErrorCode is null; + internal static Exception GetExceptionForMsQuicStatus(int status, long? errorCode = default, string? message = null) { Exception ex = GetExceptionInternal(status, errorCode, message); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/QUIC_SETTINGS.IEquattable.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/QUIC_SETTINGS.IEquattable.cs new file mode 100644 index 00000000000000..3f008c74136d1c --- /dev/null +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/QUIC_SETTINGS.IEquattable.cs @@ -0,0 +1,94 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Quic; + +internal partial struct QUIC_SETTINGS : System.IEquatable +{ + // Because QUIC_SETTINGS may contain gaps due to layout/alignment of individual + // fields, we implement IEquatable manually. If a new field is added, + // then there is a unit test which should fail. + + public readonly bool Equals(QUIC_SETTINGS other) + { + return Anonymous1.IsSetFlags == other.Anonymous1.IsSetFlags + && MaxBytesPerKey == other.MaxBytesPerKey + && HandshakeIdleTimeoutMs == other.HandshakeIdleTimeoutMs + && IdleTimeoutMs == other.IdleTimeoutMs + && MtuDiscoverySearchCompleteTimeoutUs == other.MtuDiscoverySearchCompleteTimeoutUs + && TlsClientMaxSendBuffer == other.TlsClientMaxSendBuffer + && TlsServerMaxSendBuffer == other.TlsServerMaxSendBuffer + && StreamRecvWindowDefault == other.StreamRecvWindowDefault + && StreamRecvBufferDefault == other.StreamRecvBufferDefault + && ConnFlowControlWindow == other.ConnFlowControlWindow + && MaxWorkerQueueDelayUs == other.MaxWorkerQueueDelayUs + && MaxStatelessOperations == other.MaxStatelessOperations + && InitialWindowPackets == other.InitialWindowPackets + && SendIdleTimeoutMs == other.SendIdleTimeoutMs + && InitialRttMs == other.InitialRttMs + && MaxAckDelayMs == other.MaxAckDelayMs + && DisconnectTimeoutMs == other.DisconnectTimeoutMs + && KeepAliveIntervalMs == other.KeepAliveIntervalMs + && CongestionControlAlgorithm == other.CongestionControlAlgorithm + && PeerBidiStreamCount == other.PeerBidiStreamCount + && PeerUnidiStreamCount == other.PeerUnidiStreamCount + && MaxBindingStatelessOperations == other.MaxBindingStatelessOperations + && StatelessOperationExpirationMs == other.StatelessOperationExpirationMs + && MinimumMtu == other.MinimumMtu + && MaximumMtu == other.MaximumMtu + && _bitfield == other._bitfield + && MaxOperationsPerDrain == other.MaxOperationsPerDrain + && MtuDiscoveryMissingProbeCount == other.MtuDiscoveryMissingProbeCount + && DestCidUpdateIdleTimeoutMs == other.DestCidUpdateIdleTimeoutMs + && Anonymous2.Flags == other.Anonymous2.Flags + && StreamRecvWindowBidiLocalDefault == other.StreamRecvWindowBidiLocalDefault + && StreamRecvWindowBidiRemoteDefault == other.StreamRecvWindowBidiRemoteDefault + && StreamRecvWindowUnidiDefault == other.StreamRecvWindowUnidiDefault; + } + + public override readonly int GetHashCode() + { + HashCode hash = default; + hash.Add(Anonymous1.IsSetFlags); + hash.Add(MaxBytesPerKey); + hash.Add(HandshakeIdleTimeoutMs); + hash.Add(IdleTimeoutMs); + hash.Add(MtuDiscoverySearchCompleteTimeoutUs); + hash.Add(TlsClientMaxSendBuffer); + hash.Add(TlsServerMaxSendBuffer); + hash.Add(StreamRecvWindowDefault); + hash.Add(StreamRecvBufferDefault); + hash.Add(ConnFlowControlWindow); + hash.Add(MaxWorkerQueueDelayUs); + hash.Add(MaxStatelessOperations); + hash.Add(InitialWindowPackets); + hash.Add(SendIdleTimeoutMs); + hash.Add(InitialRttMs); + hash.Add(MaxAckDelayMs); + hash.Add(DisconnectTimeoutMs); + hash.Add(KeepAliveIntervalMs); + hash.Add(CongestionControlAlgorithm); + hash.Add(PeerBidiStreamCount); + hash.Add(PeerUnidiStreamCount); + hash.Add(MaxBindingStatelessOperations); + hash.Add(StatelessOperationExpirationMs); + hash.Add(MinimumMtu); + hash.Add(MaximumMtu); + hash.Add(_bitfield); + hash.Add(MaxOperationsPerDrain); + hash.Add(MtuDiscoveryMissingProbeCount); + hash.Add(DestCidUpdateIdleTimeoutMs); + hash.Add(Anonymous2.Flags); + hash.Add(StreamRecvWindowBidiLocalDefault); + hash.Add(StreamRecvWindowBidiRemoteDefault); + hash.Add(StreamRecvWindowUnidiDefault); + return hash.ToHashCode(); + } + + public override readonly bool Equals(object? obj) + { + return obj is QUIC_SETTINGS other && Equals(other); + } +} diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs index 26296b1f6a89b8..29b4c822d62367 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic.cs @@ -20,7 +20,7 @@ namespace Microsoft.Quic { internal unsafe partial struct QUIC_BUFFER { - public Span Span => new(Buffer, (int)Length); + public readonly Span Span => new(Buffer, (int)Length); } internal partial class MsQuic diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 315352d2797bb4..f266acb265a138 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -108,6 +108,11 @@ static async ValueTask StartConnectAsync(QuicClientConnectionOpt /// private int _disposed; + /// + /// Completed when connection shutdown is initiated. + /// + private TaskCompletionSource _connectionCloseTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + private readonly ValueTaskSource _connectedTcs = new ValueTaskSource(); private readonly ResettableValueTaskSource _shutdownTcs = new ResettableValueTaskSource() { @@ -252,6 +257,11 @@ private unsafe QuicConnection() throw; } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} New outbound connection."); + } + _tlsSecret = MsQuicTlsSecret.Create(_handle); } @@ -411,9 +421,15 @@ public async ValueTask OpenOutboundStreamAsync(QuicStreamType type, try { stream = new QuicStream(_handle, type, _defaultStreamErrorCode); + + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} New outbound {type} stream {stream}."); + } + await stream.StartAsync(cancellationToken).ConfigureAwait(false); } - catch + catch (Exception ex) { if (stream is not null) { @@ -422,10 +438,16 @@ public async ValueTask OpenOutboundStreamAsync(QuicStreamType type, // Propagate ODE if disposed in the meantime. ObjectDisposedException.ThrowIf(_disposed == 1, this); + + // In case of an incoming race when the connection is closed by the peer just before we open the stream, + // we receive QUIC_STATUS_ABORTED from MsQuic, but we don't know how the connection was closed. We throw + // special exception and handle it here where we can determine the shutdown reason. + bool connectionAbortedByPeer = ThrowHelper.IsConnectionAbortedWhenStartingStreamException(ex); + // Propagate connection error if present. - if (_acceptQueue.Reader.Completion.IsFaulted) + if (_connectionCloseTcs.Task.IsFaulted || connectionAbortedByPeer) { - await _acceptQueue.Reader.Completion.ConfigureAwait(false); + await _connectionCloseTcs.Task.ConfigureAwait(false); } throw; } @@ -482,6 +504,11 @@ public ValueTask CloseAsync(long errorCode, CancellationToken cancellationToken if (_shutdownTcs.TryGetValueTask(out ValueTask valueTask, this, cancellationToken)) { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Closing connection, Error code = {errorCode}"); + } + unsafe { MsQuicApi.Api.ConnectionShutdown( @@ -518,12 +545,15 @@ private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATE { Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); _connectedTcs.TrySetException(exception); + _connectionCloseTcs.TrySetException(exception); _acceptQueue.Writer.TryComplete(exception); return QUIC_STATUS_SUCCESS; } private unsafe int HandleEventShutdownInitiatedByPeer(ref SHUTDOWN_INITIATED_BY_PEER_DATA data) { - _acceptQueue.Writer.TryComplete(ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetConnectionAbortedException((long)data.ErrorCode))); + Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetConnectionAbortedException((long)data.ErrorCode)); + _connectionCloseTcs.TrySetException(exception); + _acceptQueue.Writer.TryComplete(exception); return QUIC_STATUS_SUCCESS; } private unsafe int HandleEventShutdownComplete() @@ -532,6 +562,7 @@ private unsafe int HandleEventShutdownComplete() _tlsSecret?.WriteSecret(); Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(_disposed == 1 ? new ObjectDisposedException(GetType().FullName) : ThrowHelper.GetOperationAbortedException()); + _connectionCloseTcs.TrySetException(exception); _acceptQueue.Writer.TryComplete(exception); _connectedTcs.TrySetException(exception); _shutdownTokenSource.Cancel(); @@ -551,6 +582,13 @@ private unsafe int HandleEventPeerAddressChanged(ref PEER_ADDRESS_CHANGED_DATA d private unsafe int HandleEventPeerStreamStarted(ref PEER_STREAM_STARTED_DATA data) { QuicStream stream = new QuicStream(_handle, data.Stream, data.Flags, _defaultStreamErrorCode); + + if (NetEventSource.Log.IsEnabled()) + { + QuicStreamType type = data.Flags.HasFlag(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL) ? QuicStreamType.Unidirectional : QuicStreamType.Bidirectional; + NetEventSource.Info(this, $"{this} New inbound {type} stream {stream}, Id = {stream.Id}."); + } + if (!_acceptQueue.Writer.TryWrite(stream)) { if (NetEventSource.Log.IsEnabled()) @@ -648,6 +686,11 @@ public async ValueTask DisposeAsync() return; } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Disposing."); + } + // Check if the connection has been shut down and if not, shut it down. if (_shutdownTcs.TryGetValueTask(out ValueTask valueTask, this)) { diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs index 88ea309054a7db..249f7571519131 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs @@ -335,6 +335,12 @@ private unsafe int HandleEventNewConnection(ref NEW_CONNECTION_DATA data) } QuicConnection connection = new QuicConnection(data.Connection, data.Info); + + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} New inbound connection {connection}."); + } + SslClientHelloInfo clientHello = new SslClientHelloInfo(data.Info->ServerNameLength > 0 ? Marshal.PtrToStringUTF8((IntPtr)data.Info->ServerName, data.Info->ServerNameLength) : "", SslProtocols.Tls13); // Kicks off the rest of the handshake in the background, the process itself will enqueue the result in the accept queue. @@ -404,6 +410,11 @@ public async ValueTask DisposeAsync() return; } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Disposing."); + } + // Check if the listener has been shut down and if not, shut it down. if (_shutdownTcs.TryInitialize(out ValueTask valueTask, this)) { diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs index 06515f3310bf7f..320ca9dbcda849 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicStream.cs @@ -162,13 +162,18 @@ internal unsafe QuicStream(MsQuicContextSafeHandle connectionHandle, QuicStreamT try { QUIC_HANDLE* handle; - ThrowHelper.ThrowIfMsQuicError(MsQuicApi.Api.StreamOpen( + int status = MsQuicApi.Api.StreamOpen( connectionHandle, type == QuicStreamType.Unidirectional ? QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL : QUIC_STREAM_OPEN_FLAGS.NONE, &NativeCallback, (void*)GCHandle.ToIntPtr(context), - &handle), - "StreamOpen failed"); + &handle); + + if (ThrowHelper.TryGetStreamExceptionForMsQuicStatus(status, out Exception? ex, streamWasSuccessfullyStarted: false, message: "StreamOpen failed")) + { + throw ex; + } + _handle = new MsQuicContextSafeHandle(handle, context, SafeHandleType.Stream, connectionHandle); _handle.Disposable = _sendBuffers; } @@ -225,6 +230,7 @@ internal unsafe QuicStream(MsQuicContextSafeHandle connectionHandle, QUIC_HANDLE } _id = (long)GetMsQuicParameter(_handle, QUIC_PARAM_STREAM_ID); _type = flags.HasFlag(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL) ? QuicStreamType.Unidirectional : QuicStreamType.Bidirectional; + _startedTcs.TrySetResult(); } @@ -244,7 +250,8 @@ internal ValueTask StartAsync(CancellationToken cancellationToken = default) int status = MsQuicApi.Api.StreamStart( _handle, QUIC_STREAM_START_FLAGS.SHUTDOWN_ON_FAIL | QUIC_STREAM_START_FLAGS.INDICATE_PEER_ACCEPT); - if (ThrowHelper.TryGetStreamExceptionForMsQuicStatus(status, out Exception? exception)) + + if (ThrowHelper.TryGetStreamExceptionForMsQuicStatus(status, out Exception? exception, streamWasSuccessfullyStarted: false)) { _startedTcs.TrySetException(exception); } @@ -325,6 +332,11 @@ public override async ValueTask ReadAsync(Memory buffer, Cancellation } } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Stream read '{totalCopied}' bytes."); + } + return totalCopied; } @@ -690,6 +702,11 @@ public override async ValueTask DisposeAsync() return; } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Disposing."); + } + // If the stream wasn't started successfully, gracelessly abort it. if (!_startedTcs.IsCompletedSuccessfully) { diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicInteropTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicInteropTests.cs new file mode 100644 index 00000000000000..5ffd5b53510d24 --- /dev/null +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicInteropTests.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Net.Security; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using System.Reflection; +using System.Linq; +using Xunit; +using Xunit.Abstractions; + +using Microsoft.Quic; + +namespace System.Net.Quic.Tests +{ + public class MsQuicInteropTests + { + private static MemberInfo[] GetMembers() + { + var members = typeof(T).FindMembers(MemberTypes.Field | MemberTypes.Property, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, (mi, _) => + { + if (mi is PropertyInfo property && property.GetSetMethod() == null) + { + return false; + } + + return true; + }, null); + + Assert.NotEmpty(members); + + return members; + } + + private static void ResetMember(MemberInfo member, object instance) + { + switch (member) + { + case FieldInfo field: + field.SetValue(instance, Activator.CreateInstance(field.FieldType)); + break; + case PropertyInfo property: + property.SetValue(instance, Activator.CreateInstance(property.PropertyType)); + break; + default: + throw new InvalidOperationException($"Unexpected member type: {member.MemberType}"); + } + } + + [Fact] + public void QuicSettings_Equals_RespectsAllMembers() + { + QUIC_SETTINGS settings = new QUIC_SETTINGS(); + + // make sure the extension definition is included in compilation + Assert.Contains(typeof(IEquatable), typeof(QUIC_SETTINGS).GetInterfaces()); + + var settingsSpan = MemoryMarshal.AsBytes(new Span(ref settings)); + + // Fill the memory with 1s,we will try to zero out each member and compare + settingsSpan.Fill(0xFF); + + foreach (MemberInfo member in GetMembers()) + { + // copy and box the instance because reflection methods take a reference type arg + object boxed = settings; + ResetMember(member, boxed); + Assert.False(settings.Equals((QUIC_SETTINGS)boxed), $"Member {member.Name} is not compared."); + } + } + } +} diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs index 5125c72e0ca8d1..f8dd160acb00b7 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs @@ -15,7 +15,7 @@ namespace System.Net.Quic.Tests; -[CollectionDefinition(nameof(QuicTestCollection))] +[CollectionDefinition(nameof(QuicTestCollection), DisableParallelization = true)] public unsafe class QuicTestCollection : ICollectionFixture, IDisposable { public static bool IsSupported => QuicListener.IsSupported && QuicConnection.IsSupported; diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs index 62417e62599ba9..35e9871bb88a68 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs @@ -96,18 +96,10 @@ internal void TrackOption(SocketOptionLevel level, SocketOptionName name) ExposedHandleOrUntrackedConfiguration = true; } - internal SocketAsyncContext AsyncContext - { - get - { - if (Volatile.Read(ref _asyncContext) == null) - { - Interlocked.CompareExchange(ref _asyncContext, new SocketAsyncContext(this), null); - } - - return _asyncContext!; - } - } + internal SocketAsyncContext AsyncContext => + _asyncContext ?? + Interlocked.CompareExchange(ref _asyncContext, new SocketAsyncContext(this), null) ?? + _asyncContext!; /// /// This represents whether the Socket instance is blocking or non-blocking *from the user's point of view*, diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs index 0c8b94778a58ea..0dc1775b573454 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketTestBase.cs @@ -15,18 +15,13 @@ namespace System.Net.WebSockets.Client.Tests { public class ClientWebSocketTestBase { - public static readonly object[][] EchoServers = System.Net.Test.Common.Configuration.WebSockets.EchoServers; - public static readonly object[][] EchoHeadersServers = System.Net.Test.Common.Configuration.WebSockets.EchoHeadersServers; + public static readonly object[][] EchoServers = System.Net.Test.Common.Configuration.WebSockets.GetEchoServers(); + public static readonly object[][] EchoHeadersServers = System.Net.Test.Common.Configuration.WebSockets.GetEchoHeadersServers(); public static readonly object[][] EchoServersAndBoolean = EchoServers.SelectMany(o => new object[][] { new object[] { o[0], false }, new object[] { o[0], true } }).ToArray(); - public static readonly object[][] SecureEchoServersAndBoolean = new object[][] - { - new object[] { Test.Common.Configuration.WebSockets.SecureRemoteEchoServer, false }, - new object[] { Test.Common.Configuration.WebSockets.SecureRemoteEchoServer, true } - }; public const int TimeOutMilliseconds = 30000; public const int CloseDescriptionMaxLength = 123; diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs index 7f44a7a69349a6..cb5f0f978f761e 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs +++ b/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs @@ -254,6 +254,7 @@ public async Task ConnectAsync_CookieHeaders_Success(Uri server) [OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))] [ConditionalTheory(nameof(WebSocketsSupported)), MemberData(nameof(EchoServers))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/101115", typeof(PlatformDetection), nameof(PlatformDetection.IsFirefox))] public async Task ConnectAsync_PassNoSubProtocol_ServerRequires_ThrowsWebSocketException(Uri server) { const string AcceptedProtocol = "CustomProtocol"; diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs index f8323a20332027..988f8e4eaaa92b 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketCreateTest.cs @@ -344,7 +344,7 @@ private static async Task CreateWebSocketStream(Uri echoUri, Socket clie return stream; } - public static readonly object[][] EchoServers = System.Net.Test.Common.Configuration.WebSockets.EchoServers; + public static readonly object[][] EchoServers = System.Net.Test.Common.Configuration.WebSockets.GetEchoServers(); public static readonly object[][] EchoServersAndBoolean = EchoServers.SelectMany(o => new object[][] { new object[] { o[0], false }, diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs index 40fcdafe65436a..e7945587afef45 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs @@ -89,12 +89,18 @@ public static void MaxMagnitude(System.ReadOnlySpan x, T y, System.Span public static T Max(System.ReadOnlySpan x) where T : System.Numerics.INumber { throw null; } public static void Max(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) where T : System.Numerics.INumber { } public static void Max(System.ReadOnlySpan x, T y, System.Span destination) where T : System.Numerics.INumber { } + public static T MaxNumber(System.ReadOnlySpan x) where T : System.Numerics.INumber { throw null; } + public static void MaxNumber(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) where T : System.Numerics.INumber { } + public static void MaxNumber(System.ReadOnlySpan x, T y, System.Span destination) where T : System.Numerics.INumber { } public static T MinMagnitude(System.ReadOnlySpan x) where T : System.Numerics.INumberBase { throw null; } public static void MinMagnitude(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) where T : System.Numerics.INumberBase { } public static void MinMagnitude(System.ReadOnlySpan x, T y, System.Span destination) where T : System.Numerics.INumberBase { } public static T Min(System.ReadOnlySpan x) where T : System.Numerics.INumber { throw null; } public static void Min(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) where T : System.Numerics.INumber { } public static void Min(System.ReadOnlySpan x, T y, System.Span destination) where T : System.Numerics.INumber { } + public static T MinNumber(System.ReadOnlySpan x) where T : System.Numerics.INumber { throw null; } + public static void MinNumber(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) where T : System.Numerics.INumber { } + public static void MinNumber(System.ReadOnlySpan x, T y, System.Span destination) where T : System.Numerics.INumber { } public static void MultiplyAdd(System.ReadOnlySpan x, System.ReadOnlySpan y, System.ReadOnlySpan addend, System.Span destination) where T : System.Numerics.IAdditionOperators, System.Numerics.IMultiplyOperators { } public static void MultiplyAdd(System.ReadOnlySpan x, System.ReadOnlySpan y, T addend, System.Span destination) where T : System.Numerics.IAdditionOperators, System.Numerics.IMultiplyOperators { } public static void MultiplyAdd(System.ReadOnlySpan x, T y, System.ReadOnlySpan addend, System.Span destination) where T : System.Numerics.IAdditionOperators, System.Numerics.IMultiplyOperators { } diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index f5bb6c851dfb00..bc0e5be9bed573 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) @@ -82,8 +82,10 @@ + + diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cbrt.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cbrt.cs index 1bc8b85696c121..3336411a098966 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cbrt.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Cbrt.cs @@ -26,7 +26,7 @@ public static void Cbrt(ReadOnlySpan x, Span destination) private readonly struct CbrtOperator : IUnaryOperator where T : IRootFunctions { - public static bool Vectorizable => typeof(T) == typeof(float) || typeof(T) == typeof(double); + public static bool Vectorizable => false; // typeof(T) == typeof(float) || typeof(T) == typeof(double); // TODO: https://github.com/dotnet/runtime/issues/100535 public static T Invoke(T x) => T.Cbrt(x); diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Log.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Log.cs index 74d17f036d9404..d3d2f3e9a705d3 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Log.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Log.cs @@ -161,7 +161,7 @@ public static Vector512 Invoke(Vector512 x) private readonly struct LogBaseOperator : IBinaryOperator where T : ILogarithmicFunctions { - public static bool Vectorizable => LogOperator.Vectorizable; + public static bool Vectorizable => false; //LogOperator.Vectorizable; // TODO: https://github.com/dotnet/runtime/issues/100535 public static T Invoke(T x, T y) => T.Log(x, y); public static Vector128 Invoke(Vector128 x, Vector128 y) => LogOperator.Invoke(x) / LogOperator.Invoke(y); public static Vector256 Invoke(Vector256 x, Vector256 y) => LogOperator.Invoke(x) / LogOperator.Invoke(y); diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs index 0e0566f2d935a5..2e760e30fb7c60 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Max.cs @@ -96,35 +96,21 @@ public static T Invoke(T x, T y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 Invoke(Vector128 x, Vector128 y) { - if (AdvSimd.IsSupported) - { - if (typeof(T) == typeof(byte)) return AdvSimd.Max(x.AsByte(), y.AsByte()).As(); - if (typeof(T) == typeof(sbyte)) return AdvSimd.Max(x.AsSByte(), y.AsSByte()).As(); - if (typeof(T) == typeof(short)) return AdvSimd.Max(x.AsInt16(), y.AsInt16()).As(); - if (typeof(T) == typeof(ushort)) return AdvSimd.Max(x.AsUInt16(), y.AsUInt16()).As(); - if (typeof(T) == typeof(int)) return AdvSimd.Max(x.AsInt32(), y.AsInt32()).As(); - if (typeof(T) == typeof(uint)) return AdvSimd.Max(x.AsUInt32(), y.AsUInt32()).As(); - if (typeof(T) == typeof(float)) return AdvSimd.Max(x.AsSingle(), y.AsSingle()).As(); - } - - if (AdvSimd.Arm64.IsSupported) + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) { - if (typeof(T) == typeof(double)) return AdvSimd.Arm64.Max(x.AsDouble(), y.AsDouble()).As(); - } + if (AdvSimd.IsSupported && typeof(T) == typeof(float)) + { + return AdvSimd.Max(x.AsSingle(), y.AsSingle()).As(); + } - if (typeof(T) == typeof(float)) - { - return - Vector128.ConditionalSelect(Vector128.Equals(x, y), - Vector128.ConditionalSelect(IsNegative(x.AsSingle()).As(), y, x), - Vector128.Max(x, y)); - } + if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double)) + { + return AdvSimd.Arm64.Max(x.AsDouble(), y.AsDouble()).As(); + } - if (typeof(T) == typeof(double)) - { return Vector128.ConditionalSelect(Vector128.Equals(x, y), - Vector128.ConditionalSelect(IsNegative(x.AsDouble()).As(), y, x), + Vector128.ConditionalSelect(IsNegative(x), y, x), Vector128.Max(x, y)); } @@ -134,19 +120,11 @@ public static Vector128 Invoke(Vector128 x, Vector128 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Invoke(Vector256 x, Vector256 y) { - if (typeof(T) == typeof(float)) - { - return - Vector256.ConditionalSelect(Vector256.Equals(x, y), - Vector256.ConditionalSelect(IsNegative(x.AsSingle()).As(), y, x), - Vector256.Max(x, y)); - } - - if (typeof(T) == typeof(double)) + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) { return Vector256.ConditionalSelect(Vector256.Equals(x, y), - Vector256.ConditionalSelect(IsNegative(x.AsDouble()).As(), y, x), + Vector256.ConditionalSelect(IsNegative(x), y, x), Vector256.Max(x, y)); } @@ -156,19 +134,11 @@ public static Vector256 Invoke(Vector256 x, Vector256 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 Invoke(Vector512 x, Vector512 y) { - if (typeof(T) == typeof(float)) - { - return - Vector512.ConditionalSelect(Vector512.Equals(x, y), - Vector512.ConditionalSelect(IsNegative(x.AsSingle()).As(), y, x), - Vector512.Max(x, y)); - } - - if (typeof(T) == typeof(double)) + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) { return Vector512.ConditionalSelect(Vector512.Equals(x, y), - Vector512.ConditionalSelect(IsNegative(x.AsDouble()).As(), y, x), + Vector512.ConditionalSelect(IsNegative(x), y, x), Vector512.Max(x, y)); } @@ -192,24 +162,18 @@ public static Vector512 Invoke(Vector512 x, Vector512 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 Invoke(Vector128 x, Vector128 y) { - if (AdvSimd.IsSupported) + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) { - if (typeof(T) == typeof(byte)) return AdvSimd.Max(x.AsByte(), y.AsByte()).As(); - if (typeof(T) == typeof(sbyte)) return AdvSimd.Max(x.AsSByte(), y.AsSByte()).As(); - if (typeof(T) == typeof(ushort)) return AdvSimd.Max(x.AsUInt16(), y.AsUInt16()).As(); - if (typeof(T) == typeof(short)) return AdvSimd.Max(x.AsInt16(), y.AsInt16()).As(); - if (typeof(T) == typeof(uint)) return AdvSimd.Max(x.AsUInt32(), y.AsUInt32()).As(); - if (typeof(T) == typeof(int)) return AdvSimd.Max(x.AsInt32(), y.AsInt32()).As(); - if (typeof(T) == typeof(float)) return AdvSimd.Max(x.AsSingle(), y.AsSingle()).As(); - } + if (AdvSimd.IsSupported && typeof(T) == typeof(float)) + { + return AdvSimd.Max(x.AsSingle(), y.AsSingle()).As(); + } - if (AdvSimd.Arm64.IsSupported) - { - if (typeof(T) == typeof(double)) return AdvSimd.Arm64.Max(x.AsDouble(), y.AsDouble()).As(); - } + if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double)) + { + return AdvSimd.Arm64.Max(x.AsDouble(), y.AsDouble()).As(); + } - if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) - { return Vector128.ConditionalSelect(Vector128.Equals(x, x), Vector128.ConditionalSelect(Vector128.Equals(y, y), diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MaxNumber.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MaxNumber.cs new file mode 100644 index 00000000000000..ef4b39a77f8cb0 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MaxNumber.cs @@ -0,0 +1,142 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +namespace System.Numerics.Tensors +{ + public static partial class TensorPrimitives + { + /// Searches for the largest number in the specified tensor. + /// The tensor, represented as a span. + /// The maximum element in . + /// Length of must be greater than zero. + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximumNumber` function. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static T MaxNumber(ReadOnlySpan x) + where T : INumber => + MinMaxCore>(x); + + /// Computes the element-wise maximum of the numbers in the specified tensors. + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .MaxNumber([i], [i]). + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximumNumber` function. If either value is + /// the other is returned. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void MaxNumber(ReadOnlySpan x, ReadOnlySpan y, Span destination) + where T : INumber => + InvokeSpanSpanIntoSpan>(x, y, destination); + + /// Computes the element-wise maximum of the numbers in the specified tensors. + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .MaxNumber([i], ). + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximumNumber` function. If either value is + /// the other is returned. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void MaxNumber(ReadOnlySpan x, T y, Span destination) + where T : INumber => + InvokeSpanScalarIntoSpan>(x, y, destination); + + /// T.MaxNumber(x, y) + internal readonly struct MaxNumberOperator : IAggregationOperator where T : INumber + { + public static bool Vectorizable => true; + + public static T Invoke(T x, T y) => T.MaxNumber(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) + { + if (AdvSimd.IsSupported && typeof(T) == typeof(float)) + { + return AdvSimd.MaxNumber(x.AsSingle(), y.AsSingle()).As(); + } + + if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double)) + { + return AdvSimd.Arm64.MaxNumber(x.AsDouble(), y.AsDouble()).As(); + } + + return + Vector128.ConditionalSelect(Vector128.Equals(x, y), + Vector128.ConditionalSelect(IsNegative(y), x, y), + Vector128.ConditionalSelect(Vector128.Equals(y, y), Vector128.Max(x, y), x)); + } + + return Vector128.Max(x, y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) + { + return + Vector256.ConditionalSelect(Vector256.Equals(x, y), + Vector256.ConditionalSelect(IsNegative(y), x, y), + Vector256.ConditionalSelect(Vector256.Equals(y, y), Vector256.Max(x, y), x)); + } + + return Vector256.Max(x, y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) + { + return + Vector512.ConditionalSelect(Vector512.Equals(x, y), + Vector512.ConditionalSelect(IsNegative(y), x, y), + Vector512.ConditionalSelect(Vector512.Equals(y, y), Vector512.Max(x, y), x)); + } + + return Vector512.Max(x, y); + } + + public static T Invoke(Vector128 x) => HorizontalAggregate>(x); + public static T Invoke(Vector256 x) => HorizontalAggregate>(x); + public static T Invoke(Vector512 x) => HorizontalAggregate>(x); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs index faea478057982c..fd3931fa3d194e 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Min.cs @@ -79,24 +79,18 @@ public static T Invoke(T x, T y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 Invoke(Vector128 x, Vector128 y) { - if (AdvSimd.IsSupported) + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) { - if (typeof(T) == typeof(byte)) return AdvSimd.Min(x.AsByte(), y.AsByte()).As(); - if (typeof(T) == typeof(sbyte)) return AdvSimd.Min(x.AsSByte(), y.AsSByte()).As(); - if (typeof(T) == typeof(short)) return AdvSimd.Min(x.AsInt16(), y.AsInt16()).As(); - if (typeof(T) == typeof(ushort)) return AdvSimd.Min(x.AsUInt16(), y.AsUInt16()).As(); - if (typeof(T) == typeof(int)) return AdvSimd.Min(x.AsInt32(), y.AsInt32()).As(); - if (typeof(T) == typeof(uint)) return AdvSimd.Min(x.AsUInt32(), y.AsUInt32()).As(); - if (typeof(T) == typeof(float)) return AdvSimd.Min(x.AsSingle(), y.AsSingle()).As(); - } + if (AdvSimd.IsSupported && typeof(T) == typeof(float)) + { + return AdvSimd.Min(x.AsSingle(), y.AsSingle()).As(); + } - if (AdvSimd.Arm64.IsSupported) - { - if (typeof(T) == typeof(double)) return AdvSimd.Arm64.Min(x.AsDouble(), y.AsDouble()).As(); - } + if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double)) + { + return AdvSimd.Arm64.Min(x.AsDouble(), y.AsDouble()).As(); + } - if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) - { return Vector128.ConditionalSelect(Vector128.Equals(x, y), Vector128.ConditionalSelect(IsNegative(y), y, x), @@ -149,24 +143,18 @@ public static Vector512 Invoke(Vector512 x, Vector512 y) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 Invoke(Vector128 x, Vector128 y) { - if (AdvSimd.IsSupported) + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) { - if (typeof(T) == typeof(byte)) return AdvSimd.Min(x.AsByte(), y.AsByte()).As(); - if (typeof(T) == typeof(sbyte)) return AdvSimd.Min(x.AsSByte(), y.AsSByte()).As(); - if (typeof(T) == typeof(short)) return AdvSimd.Min(x.AsInt16(), y.AsInt16()).As(); - if (typeof(T) == typeof(ushort)) return AdvSimd.Min(x.AsUInt16(), y.AsUInt16()).As(); - if (typeof(T) == typeof(int)) return AdvSimd.Min(x.AsInt32(), y.AsInt32()).As(); - if (typeof(T) == typeof(uint)) return AdvSimd.Min(x.AsUInt32(), y.AsUInt32()).As(); - if (typeof(T) == typeof(float)) return AdvSimd.Min(x.AsSingle(), y.AsSingle()).As(); - } + if (AdvSimd.IsSupported && typeof(T) == typeof(float)) + { + return AdvSimd.Min(x.AsSingle(), y.AsSingle()).As(); + } - if (AdvSimd.Arm64.IsSupported) - { - if (typeof(T) == typeof(double)) return AdvSimd.Arm64.Min(x.AsDouble(), y.AsDouble()).As(); - } + if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double)) + { + return AdvSimd.Arm64.Min(x.AsDouble(), y.AsDouble()).As(); + } - if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) - { return Vector128.ConditionalSelect(Vector128.Equals(x, x), Vector128.ConditionalSelect(Vector128.Equals(y, y), diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MinNumber.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MinNumber.cs new file mode 100644 index 00000000000000..ab0cb5080fab00 --- /dev/null +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.MinNumber.cs @@ -0,0 +1,142 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +namespace System.Numerics.Tensors +{ + public static partial class TensorPrimitives + { + /// Searches for the largest number in the specified tensor. + /// The tensor, represented as a span. + /// The maximum element in . + /// Length of must be greater than zero. + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximumNumber` function. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static T MinNumber(ReadOnlySpan x) + where T : INumber => + MinMaxCore>(x); + + /// Computes the element-wise maximum of the numbers in the specified tensors. + /// The first tensor, represented as a span. + /// The second tensor, represented as a span. + /// The destination tensor, represented as a span. + /// Length of must be same as length of . + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .MinNumber([i], [i]). + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximumNumber` function. If either value is + /// the other is returned. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void MinNumber(ReadOnlySpan x, ReadOnlySpan y, Span destination) + where T : INumber => + InvokeSpanSpanIntoSpan>(x, y, destination); + + /// Computes the element-wise maximum of the numbers in the specified tensors. + /// The first tensor, represented as a span. + /// The second tensor, represented as a scalar. + /// The destination tensor, represented as a span. + /// Destination is too short. + /// and reference overlapping memory locations and do not begin at the same location. + /// + /// + /// This method effectively computes [i] = .MinNumber([i], ). + /// + /// + /// The determination of the maximum element matches the IEEE 754:2019 `maximumNumber` function. If either value is + /// the other is returned. Positive 0 is considered greater than negative 0. + /// + /// + /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different + /// operating systems or architectures. + /// + /// + public static void MinNumber(ReadOnlySpan x, T y, Span destination) + where T : INumber => + InvokeSpanScalarIntoSpan>(x, y, destination); + + /// T.MinNumber(x, y) + internal readonly struct MinNumberOperator : IAggregationOperator where T : INumber + { + public static bool Vectorizable => true; + + public static T Invoke(T x, T y) => T.MinNumber(x, y); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector128 Invoke(Vector128 x, Vector128 y) + { + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) + { + if (AdvSimd.IsSupported && typeof(T) == typeof(float)) + { + return AdvSimd.MinNumber(x.AsSingle(), y.AsSingle()).As(); + } + + if (AdvSimd.Arm64.IsSupported && typeof(T) == typeof(double)) + { + return AdvSimd.Arm64.MinNumber(x.AsDouble(), y.AsDouble()).As(); + } + + return + Vector128.ConditionalSelect(Vector128.Equals(x, y), + Vector128.ConditionalSelect(IsNegative(x), x, y), + Vector128.ConditionalSelect(Vector128.Equals(y, y), Vector128.Min(x, y), x)); + } + + return Vector128.Min(x, y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 Invoke(Vector256 x, Vector256 y) + { + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) + { + return + Vector256.ConditionalSelect(Vector256.Equals(x, y), + Vector256.ConditionalSelect(IsNegative(x), x, y), + Vector256.ConditionalSelect(Vector256.Equals(y, y), Vector256.Min(x, y), x)); + } + + return Vector256.Min(x, y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 Invoke(Vector512 x, Vector512 y) + { + if (typeof(T) == typeof(float) || typeof(T) == typeof(double)) + { + return + Vector512.ConditionalSelect(Vector512.Equals(x, y), + Vector512.ConditionalSelect(IsNegative(x), x, y), + Vector512.ConditionalSelect(Vector512.Equals(y, y), Vector512.Min(x, y), x)); + } + + return Vector512.Min(x, y); + } + + public static T Invoke(Vector128 x) => HorizontalAggregate>(x); + public static T Invoke(Vector256 x) => HorizontalAggregate>(x); + public static T Invoke(Vector512 x) => HorizontalAggregate>(x); + } + } +} diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Pow.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Pow.cs index 72d35ed5be779f..263235e4a5c2e3 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Pow.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Pow.cs @@ -59,7 +59,7 @@ public static void Pow(T x, ReadOnlySpan y, Span destination) private readonly struct PowOperator : IBinaryOperator where T : IPowerFunctions { - public static bool Vectorizable => typeof(T) == typeof(float) || typeof(T) == typeof(double); + public static bool Vectorizable => false; // typeof(T) == typeof(float) || typeof(T) == typeof(double); // TODO: https://github.com/dotnet/runtime/issues/100535 public static T Invoke(T x, T y) => T.Pow(x, y); diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Reciprocal.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Reciprocal.cs index 50ef635a21addc..16d0df26157cb2 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Reciprocal.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Reciprocal.cs @@ -95,6 +95,14 @@ public static void ReciprocalSqrtEstimate(ReadOnlySpan x, Span destinat public static Vector128 Invoke(Vector128 x) { +#if NET9_0_OR_GREATER + if (Avx512F.VL.IsSupported) + { + if (typeof(T) == typeof(float)) return Avx512F.VL.Reciprocal14(x.AsSingle()).As(); + if (typeof(T) == typeof(double)) return Avx512F.VL.Reciprocal14(x.AsDouble()).As(); + } +#endif + if (Sse.IsSupported) { if (typeof(T) == typeof(float)) return Sse.Reciprocal(x.AsSingle()).As(); @@ -115,6 +123,14 @@ public static Vector128 Invoke(Vector128 x) public static Vector256 Invoke(Vector256 x) { +#if NET9_0_OR_GREATER + if (Avx512F.VL.IsSupported) + { + if (typeof(T) == typeof(float)) return Avx512F.VL.Reciprocal14(x.AsSingle()).As(); + if (typeof(T) == typeof(double)) return Avx512F.VL.Reciprocal14(x.AsDouble()).As(); + } +#endif + if (Avx.IsSupported) { if (typeof(T) == typeof(float)) return Avx.Reciprocal(x.AsSingle()).As(); @@ -125,11 +141,13 @@ public static Vector256 Invoke(Vector256 x) public static Vector512 Invoke(Vector512 x) { +#if NET9_0_OR_GREATER if (Avx512F.IsSupported) { if (typeof(T) == typeof(float)) return Avx512F.Reciprocal14(x.AsSingle()).As(); if (typeof(T) == typeof(double)) return Avx512F.Reciprocal14(x.AsDouble()).As(); } +#endif return Vector512.One / x; } @@ -143,6 +161,14 @@ public static Vector512 Invoke(Vector512 x) public static Vector128 Invoke(Vector128 x) { +#if NET9_0_OR_GREATER + if (Avx512F.VL.IsSupported) + { + if (typeof(T) == typeof(float)) return Avx512F.VL.ReciprocalSqrt14(x.AsSingle()).As(); + if (typeof(T) == typeof(double)) return Avx512F.VL.ReciprocalSqrt14(x.AsDouble()).As(); + } +#endif + if (Sse.IsSupported) { if (typeof(T) == typeof(float)) return Sse.ReciprocalSqrt(x.AsSingle()).As(); @@ -163,6 +189,14 @@ public static Vector128 Invoke(Vector128 x) public static Vector256 Invoke(Vector256 x) { +#if NET9_0_OR_GREATER + if (Avx512F.VL.IsSupported) + { + if (typeof(T) == typeof(float)) return Avx512F.VL.ReciprocalSqrt14(x.AsSingle()).As(); + if (typeof(T) == typeof(double)) return Avx512F.VL.ReciprocalSqrt14(x.AsDouble()).As(); + } +#endif + if (Avx.IsSupported) { if (typeof(T) == typeof(float)) return Avx.ReciprocalSqrt(x.AsSingle()).As(); @@ -173,11 +207,13 @@ public static Vector256 Invoke(Vector256 x) public static Vector512 Invoke(Vector512 x) { +#if NET9_0_OR_GREATER if (Avx512F.IsSupported) { if (typeof(T) == typeof(float)) return Avx512F.ReciprocalSqrt14(x.AsSingle()).As(); if (typeof(T) == typeof(double)) return Avx512F.ReciprocalSqrt14(x.AsDouble()).As(); } +#endif return Vector512.One / Vector512.Sqrt(x); } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.RootN.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.RootN.cs index e7c394892950a9..5a732f76936000 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.RootN.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.RootN.cs @@ -28,7 +28,7 @@ private readonly struct RootNOperator(int n) : IStatefulUnaryOperator wher { private readonly int _n = n; - public static bool Vectorizable => typeof(T) == typeof(float) || typeof(T) == typeof(double); + public static bool Vectorizable => false; // typeof(T) == typeof(float) || typeof(T) == typeof(double); // TODO: https://github.com/dotnet/runtime/issues/100535 public T Invoke(T x) => T.RootN(x, _n); diff --git a/src/libraries/System.Numerics.Tensors/tests/Helpers.cs b/src/libraries/System.Numerics.Tensors/tests/Helpers.cs index 729cacda351695..b78d0eb01bda27 100644 --- a/src/libraries/System.Numerics.Tensors/tests/Helpers.cs +++ b/src/libraries/System.Numerics.Tensors/tests/Helpers.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; namespace System.Numerics.Tensors.Tests { @@ -20,7 +21,7 @@ internal static class Helpers public const float DefaultHalfTolerance = 3.90625e-03f; public const double DefaultToleranceForEstimates = 1.171875e-02; -#if NETCOREAPP +#if NET private static class DefaultTolerance where T : unmanaged, INumber { public static readonly T Value = DetermineTolerance(DefaultDoubleTolerance, DefaultFloatTolerance, Half.CreateTruncating(DefaultHalfTolerance)) ?? T.CreateTruncating(0); @@ -28,6 +29,11 @@ private static class DefaultTolerance where T : unmanaged, INumber public static bool IsEqualWithTolerance(T expected, T actual, T? tolerance = null) where T : unmanaged, INumber { + if (T.IsNaN(expected) != T.IsNaN(actual)) + { + return false; + } + tolerance = tolerance ?? DefaultTolerance.Value; T diff = T.Abs(expected - actual); return !(diff > tolerance && diff > T.Max(T.Abs(expected), T.Abs(actual)) * tolerance); @@ -35,6 +41,11 @@ public static bool IsEqualWithTolerance(T expected, T actual, T? tolerance = #else public static bool IsEqualWithTolerance(float expected, float actual, float? tolerance = null) { + if (float.IsNaN(expected) != float.IsNaN(actual)) + { + return false; + } + tolerance ??= DefaultFloatTolerance; float diff = MathF.Abs(expected - actual); return !(diff > tolerance && diff > MathF.Max(MathF.Abs(expected), MathF.Abs(actual)) * tolerance); @@ -44,7 +55,7 @@ public static bool IsEqualWithTolerance(float expected, float actual, float? tol public static T? DetermineTolerance( double? doubleTolerance = null, float? floatTolerance = null -#if NETCOREAPP +#if NET , Half? halfTolerance = null #endif ) where T : struct @@ -57,13 +68,23 @@ public static bool IsEqualWithTolerance(float expected, float actual, float? tol { return (T?)(object)floatTolerance; } -#if NETCOREAPP +#if NET else if (typeof(T) == typeof(Half) && halfTolerance != null) { return (T?)(object)halfTolerance; } + else if (typeof(T) == typeof(NFloat)) + { + if (IntPtr.Size == 8 && doubleTolerance != null) + { + return (T?)(object)(NFloat)doubleTolerance; + } + else if (IntPtr.Size == 4 && floatTolerance != null) + { + return (T?)(object)(NFloat)doubleTolerance; + } + } #endif - return null; } } diff --git a/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj index eb08d0e5974a6f..3b8f867b355c0a 100644 --- a/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj @@ -10,6 +10,7 @@ $(NetCoreAppCurrent) true + $(DefineConstants);SNT_NET8_TESTS diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs index 0cd20f1d647a4e..2768a03a070475 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs @@ -386,7 +386,12 @@ public static IEnumerable SpanDestinationFunctionsToTest() yield return Create(TensorPrimitives.Reciprocal, f => T.One / f); yield return Create(TensorPrimitives.ReciprocalEstimate, T.ReciprocalEstimate, T.CreateTruncating(Helpers.DefaultToleranceForEstimates)); yield return Create(TensorPrimitives.ReciprocalSqrt, f => T.One / T.Sqrt(f)); + +#if !SNT_NET8_TESTS + // Avoid running with the net8 tests due to: https://github.com/dotnet/runtime/issues/101846 yield return Create(TensorPrimitives.ReciprocalSqrtEstimate, T.ReciprocalSqrtEstimate, T.CreateTruncating(Helpers.DefaultToleranceForEstimates)); +#endif + yield return Create(TensorPrimitives.Round, T.Round); yield return Create(TensorPrimitives.Sin, T.Sin, trigTolerance); yield return Create(TensorPrimitives.Sinh, T.Sinh, Helpers.DetermineTolerance(doubleTolerance: 1e-14)); @@ -480,8 +485,11 @@ public void SpanDestinationFunctions_ValueRange(SpanDestinationDelegate tensorPr #pragma warning disable xUnit1026 // Theory methods should use all of their parameters [Theory] [MemberData(nameof(SpanDestinationFunctionsToTest))] - public void SpanDestinationFunctions_ThrowsForTooShortDestination(SpanDestinationDelegate tensorPrimitivesMethod, Func _, T? __ = null) + public void SpanDestinationFunctions_ThrowsForTooShortDestination(SpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + Assert.All(Helpers.TensorLengths, tensorLength => { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -493,8 +501,11 @@ public void SpanDestinationFunctions_ThrowsForTooShortDestination(SpanDestinatio [Theory] [MemberData(nameof(SpanDestinationFunctionsToTest))] - public void SpanDestinationFunctions_ThrowsForOverlapppingInputsWithOutputs(SpanDestinationDelegate tensorPrimitivesMethod, Func _, T? __ = null) + public void SpanDestinationFunctions_ThrowsForOverlapppingInputsWithOutputs(SpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + T[] array = new T[10]; AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), array.AsSpan(0, 2))); AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), array.AsSpan(2, 2))); @@ -511,6 +522,8 @@ public static IEnumerable SpanSpanDestinationFunctionsToTest() yield return Create(TensorPrimitives.Hypot, T.Hypot); yield return Create(TensorPrimitives.Ieee754Remainder, T.Ieee754Remainder); yield return Create(TensorPrimitives.Log, T.Log); + yield return Create(TensorPrimitives.MaxNumber, T.MaxNumber); + yield return Create(TensorPrimitives.MinNumber, T.MinNumber); yield return Create(TensorPrimitives.Pow, T.Pow, Helpers.DetermineTolerance(doubleTolerance: 1e-13, floatTolerance: 1e-5f)); static object[] Create(SpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) @@ -644,8 +657,10 @@ public static IEnumerable SpanScalarDestinationFunctionsToTest() yield return Create(TensorPrimitives.Log, T.Log); yield return Create(TensorPrimitives.Max, T.Max); yield return Create(TensorPrimitives.MaxMagnitude, T.MaxMagnitude); + yield return Create(TensorPrimitives.MaxNumber, T.MaxNumber); yield return Create(TensorPrimitives.Min, T.Min); yield return Create(TensorPrimitives.MinMagnitude, T.MinMagnitude); + yield return Create(TensorPrimitives.MinNumber, T.MinNumber); static object[] Create(SpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) => new object[] { tensorPrimitivesMethod, expectedMethod, tolerance }; @@ -942,15 +957,15 @@ public static IEnumerable SpanSpanSpanDestinationFunctionsToTest() { yield return Create(TensorPrimitives.FusedMultiplyAdd, T.FusedMultiplyAdd); yield return Create(TensorPrimitives.Lerp, T.Lerp); - yield return Create(TensorPrimitives.MultiplyAddEstimate, T.FusedMultiplyAdd); // TODO: Change T.FusedMultiplyAdd to T.MultiplyAddEstimate when available + yield return Create(TensorPrimitives.MultiplyAddEstimate, T.FusedMultiplyAdd, T.CreateTruncating(Helpers.DefaultToleranceForEstimates)); // TODO: Change T.FusedMultiplyAdd to T.MultiplyAddEstimate when available - static object[] Create(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) - => new object[] { tensorPrimitivesMethod, expectedMethod }; + static object[] Create(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) + => new object[] { tensorPrimitivesMethod, expectedMethod, tolerance }; } [Theory] [MemberData(nameof(SpanSpanSpanDestinationFunctionsToTest))] - public void SpanSpanSpanDestination_AllLengths(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanSpanSpanDestination_AllLengths(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengthsIncluding0, tensorLength => { @@ -962,14 +977,14 @@ public void SpanSpanSpanDestination_AllLengths(SpanSpanSpanDestinationDelegate t tensorPrimitivesMethod(x, y, z, destination); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i], tolerance); } }); } [Theory] [MemberData(nameof(SpanSpanSpanDestinationFunctionsToTest))] - public void SpanSpanSpanDestination_InPlace(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanSpanSpanDestination_InPlace(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengthsIncluding0, tensorLength => { @@ -980,14 +995,14 @@ public void SpanSpanSpanDestination_InPlace(SpanSpanSpanDestinationDelegate tens for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(xOrig[i], xOrig[i], xOrig[i]), x[i]); + AssertEqualTolerance(expectedMethod(xOrig[i], xOrig[i], xOrig[i]), x[i], tolerance); } }); } [Theory] [MemberData(nameof(SpanSpanSpanDestinationFunctionsToTest))] - public void SpanSpanSpanDestination_SpecialValues(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanSpanSpanDestination_SpecialValues(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengths, tensorLength => { @@ -1001,7 +1016,7 @@ public void SpanSpanSpanDestination_SpecialValues(SpanSpanSpanDestinationDelegat tensorPrimitivesMethod(x.Span, y.Span, z.Span, destination.Span); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i], tolerance); } }, x); @@ -1010,7 +1025,7 @@ public void SpanSpanSpanDestination_SpecialValues(SpanSpanSpanDestinationDelegat tensorPrimitivesMethod(x.Span, y.Span, z.Span, destination.Span); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i], tolerance); } }, y); @@ -1019,7 +1034,7 @@ public void SpanSpanSpanDestination_SpecialValues(SpanSpanSpanDestinationDelegat tensorPrimitivesMethod(x.Span, y.Span, z.Span, destination.Span); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y[i], z[i]), destination[i], tolerance); } }, z); }); @@ -1027,8 +1042,11 @@ public void SpanSpanSpanDestination_SpecialValues(SpanSpanSpanDestinationDelegat [Theory] [MemberData(nameof(SpanSpanSpanDestinationFunctionsToTest))] - public void SpanSpanSpanDestination_ThrowsForMismatchedLengths(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func _) + public void SpanSpanSpanDestination_ThrowsForMismatchedLengths(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + Assert.All(Helpers.TensorLengths, tensorLength => { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -1047,8 +1065,11 @@ public void SpanSpanSpanDestination_ThrowsForMismatchedLengths(SpanSpanSpanDesti [Theory] [MemberData(nameof(SpanSpanSpanDestinationFunctionsToTest))] - public void SpanSpanSpanDestination_ThrowsForTooShortDestination(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func _) + public void SpanSpanSpanDestination_ThrowsForTooShortDestination(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + Assert.All(Helpers.TensorLengths, tensorLength => { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -1062,8 +1083,11 @@ public void SpanSpanSpanDestination_ThrowsForTooShortDestination(SpanSpanSpanDes [Theory] [MemberData(nameof(SpanSpanSpanDestinationFunctionsToTest))] - public void SpanSpanSpanDestination_ThrowsForOverlapppingInputsWithOutputs(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func _) + public void SpanSpanSpanDestination_ThrowsForOverlapppingInputsWithOutputs(SpanSpanSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + T[] array = new T[10]; AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), array.AsSpan(5, 2), array.AsSpan(7, 2), array.AsSpan(0, 2))); AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), array.AsSpan(5, 2), array.AsSpan(7, 2), array.AsSpan(2, 2))); @@ -1078,15 +1102,15 @@ public static IEnumerable SpanSpanScalarDestinationFunctionsToTest() { yield return Create(TensorPrimitives.FusedMultiplyAdd, T.FusedMultiplyAdd); yield return Create(TensorPrimitives.Lerp, T.Lerp); - yield return Create(TensorPrimitives.MultiplyAddEstimate, T.FusedMultiplyAdd); // TODO: Change T.FusedMultiplyAdd to T.MultiplyAddEstimate when available + yield return Create(TensorPrimitives.MultiplyAddEstimate, T.FusedMultiplyAdd, T.CreateTruncating(Helpers.DefaultToleranceForEstimates)); // TODO: Change T.FusedMultiplyAdd to T.MultiplyAddEstimate when available - static object[] Create(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) - => new object[] { tensorPrimitivesMethod, expectedMethod }; + static object[] Create(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) + => new object[] { tensorPrimitivesMethod, expectedMethod, tolerance }; } [Theory] [MemberData(nameof(SpanSpanScalarDestinationFunctionsToTest))] - public void SpanSpanScalarDestination_AllLengths(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanSpanScalarDestination_AllLengths(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengthsIncluding0, tensorLength => { @@ -1099,14 +1123,14 @@ public void SpanSpanScalarDestination_AllLengths(SpanSpanScalarDestinationDelega for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y[i], z), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y[i], z), destination[i], tolerance); } }); } [Theory] [MemberData(nameof(SpanSpanScalarDestinationFunctionsToTest))] - public void SpanSpanScalarDestination_InPlace(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanSpanScalarDestination_InPlace(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengthsIncluding0, tensorLength => { @@ -1118,14 +1142,14 @@ public void SpanSpanScalarDestination_InPlace(SpanSpanScalarDestinationDelegate for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(xOrig[i], xOrig[i], z), x[i]); + AssertEqualTolerance(expectedMethod(xOrig[i], xOrig[i], z), x[i], tolerance); } }); } [Theory] [MemberData(nameof(SpanSpanScalarDestinationFunctionsToTest))] - public void SpanSpanScalarDestination_SpecialValues(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanSpanScalarDestination_SpecialValues(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengths, tensorLength => { @@ -1139,7 +1163,7 @@ public void SpanSpanScalarDestination_SpecialValues(SpanSpanScalarDestinationDel tensorPrimitivesMethod(x.Span, y.Span, z, destination.Span); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y[i], z), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y[i], z), destination[i], tolerance); } }, x); @@ -1148,7 +1172,7 @@ public void SpanSpanScalarDestination_SpecialValues(SpanSpanScalarDestinationDel tensorPrimitivesMethod(x.Span, y.Span, z, destination.Span); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y[i], z), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y[i], z), destination[i], tolerance); } }, y); }); @@ -1156,8 +1180,11 @@ public void SpanSpanScalarDestination_SpecialValues(SpanSpanScalarDestinationDel [Theory] [MemberData(nameof(SpanSpanScalarDestinationFunctionsToTest))] - public void SpanSpanScalarDestination_ThrowsForTooShortDestination(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func _) + public void SpanSpanScalarDestination_ThrowsForTooShortDestination(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + Assert.All(Helpers.TensorLengths, tensorLength => { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -1171,8 +1198,11 @@ public void SpanSpanScalarDestination_ThrowsForTooShortDestination(SpanSpanScala [Theory] [MemberData(nameof(SpanSpanScalarDestinationFunctionsToTest))] - public void SpanSpanScalarDestination_ThrowsForOverlapppingInputsWithOutputs(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func _) + public void SpanSpanScalarDestination_ThrowsForOverlapppingInputsWithOutputs(SpanSpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + T[] array = new T[10]; AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), array.AsSpan(4, 2), default, array.AsSpan(0, 2))); AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), array.AsSpan(4, 2), default, array.AsSpan(2, 2))); @@ -1186,15 +1216,15 @@ public static IEnumerable SpanScalarSpanDestinationFunctionsToTest() { yield return Create(TensorPrimitives.FusedMultiplyAdd, T.FusedMultiplyAdd); yield return Create(TensorPrimitives.Lerp, T.Lerp); - yield return Create(TensorPrimitives.MultiplyAddEstimate, T.FusedMultiplyAdd); // TODO: Change T.FusedMultiplyAdd to T.MultiplyAddEstimate when available + yield return Create(TensorPrimitives.MultiplyAddEstimate, T.FusedMultiplyAdd, T.CreateTruncating(Helpers.DefaultToleranceForEstimates)); // TODO: Change T.FusedMultiplyAdd to T.MultiplyAddEstimate when available - static object[] Create(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + static object[] Create(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) => new object[] { tensorPrimitivesMethod, expectedMethod }; } [Theory] [MemberData(nameof(SpanScalarSpanDestinationFunctionsToTest))] - public void SpanScalarSpanDestination_AllLengths(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanScalarSpanDestination_AllLengths(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengthsIncluding0, tensorLength => { @@ -1207,14 +1237,14 @@ public void SpanScalarSpanDestination_AllLengths(SpanScalarSpanDestinationDelega for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y, z[i]), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y, z[i]), destination[i], tolerance); } }); } [Theory] [MemberData(nameof(SpanScalarSpanDestinationFunctionsToTest))] - public void SpanScalarSpanDestination_InPlace(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanScalarSpanDestination_InPlace(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengthsIncluding0, tensorLength => { @@ -1226,14 +1256,14 @@ public void SpanScalarSpanDestination_InPlace(SpanScalarSpanDestinationDelegate for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(xOrig[i], y, xOrig[i]), x[i]); + AssertEqualTolerance(expectedMethod(xOrig[i], y, xOrig[i]), x[i], tolerance); } }); } [Theory] [MemberData(nameof(SpanScalarSpanDestinationFunctionsToTest))] - public void SpanScalarSpanDestination_SpecialValues(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) + public void SpanScalarSpanDestination_SpecialValues(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { Assert.All(Helpers.TensorLengths, tensorLength => { @@ -1247,7 +1277,7 @@ public void SpanScalarSpanDestination_SpecialValues(SpanScalarSpanDestinationDel tensorPrimitivesMethod(x.Span, y, z.Span, destination.Span); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y, z[i]), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y, z[i]), destination[i], tolerance); } }, x); @@ -1256,7 +1286,7 @@ public void SpanScalarSpanDestination_SpecialValues(SpanScalarSpanDestinationDel tensorPrimitivesMethod(x.Span, y, z.Span, destination.Span); for (int i = 0; i < tensorLength; i++) { - AssertEqualTolerance(expectedMethod(x[i], y, z[i]), destination[i]); + AssertEqualTolerance(expectedMethod(x[i], y, z[i]), destination[i], tolerance); } }, z); }); @@ -1264,8 +1294,11 @@ public void SpanScalarSpanDestination_SpecialValues(SpanScalarSpanDestinationDel [Theory] [MemberData(nameof(SpanScalarSpanDestinationFunctionsToTest))] - public void SpanScalarSpanDestination_ThrowsForTooShortDestination(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func _) + public void SpanScalarSpanDestination_ThrowsForTooShortDestination(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + Assert.All(Helpers.TensorLengths, tensorLength => { using BoundedMemory x = CreateAndFillTensor(tensorLength); @@ -1279,8 +1312,11 @@ public void SpanScalarSpanDestination_ThrowsForTooShortDestination(SpanScalarSpa [Theory] [MemberData(nameof(SpanScalarSpanDestinationFunctionsToTest))] - public void SpanScalarSpanDestination_ThrowsForOverlapppingInputsWithOutputs(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func _) + public void SpanScalarSpanDestination_ThrowsForOverlapppingInputsWithOutputs(SpanScalarSpanDestinationDelegate tensorPrimitivesMethod, Func expectedMethod, T? tolerance = null) { + _ = expectedMethod; + _ = tolerance; + T[] array = new T[10]; AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), default, array.AsSpan(4, 2), array.AsSpan(0, 2))); AssertExtensions.Throws("destination", () => tensorPrimitivesMethod(array.AsSpan(1, 2), default, array.AsSpan(4, 2), array.AsSpan(2, 2))); @@ -1806,8 +1842,10 @@ public static IEnumerable SpanScalarDestinationFunctionsToTest() yield return Create(TensorPrimitives.BitwiseOr, (x, y) => x | y); yield return Create(TensorPrimitives.Max, T.Max); yield return Create(TensorPrimitives.MaxMagnitude, T.MaxMagnitude); + yield return Create(TensorPrimitives.MaxNumber, T.MaxNumber); yield return Create(TensorPrimitives.Min, T.Min); yield return Create(TensorPrimitives.MinMagnitude, T.MinMagnitude); + yield return Create(TensorPrimitives.MinNumber, T.MinNumber); yield return Create(TensorPrimitives.Xor, (x, y) => x ^ y); static object[] Create(SpanScalarDestinationDelegate tensorPrimitivesMethod, Func expectedMethod) diff --git a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs index 8bf4cb6c534827..531a379cf06e99 100644 --- a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs +++ b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs @@ -235,14 +235,20 @@ public static partial class Vector [System.CLSCompliantAttribute(false)] public static System.Numerics.Vector ConvertToDouble(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToInt32(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToInt32Native(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToInt64(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ConvertToInt64Native(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ConvertToSingle(System.Numerics.Vector value) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Numerics.Vector ConvertToSingle(System.Numerics.Vector value) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Numerics.Vector ConvertToUInt32(System.Numerics.Vector value) { throw null; } [System.CLSCompliantAttribute(false)] + public static System.Numerics.Vector ConvertToUInt32Native(System.Numerics.Vector value) { throw null; } + [System.CLSCompliantAttribute(false)] public static System.Numerics.Vector ConvertToUInt64(System.Numerics.Vector value) { throw null; } + [System.CLSCompliantAttribute(false)] + public static System.Numerics.Vector ConvertToUInt64Native(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector CreateSequence(T start, T step) { throw null; } public static System.Numerics.Vector Divide(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Divide(System.Numerics.Vector left, T right) { throw null; } diff --git a/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj b/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj index 1a8f23c29c492b..0ef93fda9ecd4b 100644 --- a/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj +++ b/src/libraries/System.ObjectModel/src/System.ObjectModel.csproj @@ -33,6 +33,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/ref/System.Private.CoreLib.ManualShimTypeForwards.cs b/src/libraries/System.Private.CoreLib/ref/System.Private.CoreLib.ManualShimTypeForwards.cs index 0a93320ccff1eb..ab8473216cd87a 100644 --- a/src/libraries/System.Private.CoreLib/ref/System.Private.CoreLib.ManualShimTypeForwards.cs +++ b/src/libraries/System.Private.CoreLib/ref/System.Private.CoreLib.ManualShimTypeForwards.cs @@ -65,7 +65,7 @@ public ByteEqualityComparer() { } public override int GetHashCode() { throw null; } public override int GetHashCode(byte b) { throw null; } } - public sealed partial class EnumEqualityComparer : System.Collections.Generic.EqualityComparer, System.Runtime.Serialization.ISerializable where T : struct + public sealed partial class EnumEqualityComparer : System.Collections.Generic.EqualityComparer, System.Runtime.Serialization.ISerializable where T : struct, System.Enum { public EnumEqualityComparer() { } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml index a152f063f51ce3..d1f5af506a2476 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.Shared.xml @@ -2,6 +2,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 22a4ddea6ed606..f1b61a1ea67c4b 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -133,6 +133,7 @@ + @@ -648,9 +649,7 @@ - - @@ -1266,6 +1265,7 @@ + @@ -1424,6 +1424,9 @@ Common\System\LocalAppContextSwitches.Common.cs + + Common\System\HexConverter.cs + Common\System\HResults.cs @@ -1472,8 +1475,26 @@ Common\System\IO\PathInternal.CaseSensitivity.cs - - Common\System\Reflection\TypeNameParser.cs + + Common\System\Reflection\TypeNameParser.Helpers + + + Common\System\Reflection\AssemblyNameParser.cs + + + Common\System\Reflection\AssemblyNameFormatter.cs + + + Common\System\Reflection\Metadata\AssemblyNameInfo.cs + + + Common\System\Reflection\Metadata\TypeName.cs + + + Common\System\Reflection\Metadata\TypeNameParser.cs + + + Common\System\Reflection\Metadata\TypeNameParserHelpers.cs Common\System\Runtime\Versioning\NonVersionableAttribute.cs @@ -1578,11 +1599,6 @@ - - - Common\System\HexConverter.cs - - Common\Interop\Windows\Advapi32\Interop.EncryptDecrypt.cs @@ -2766,4 +2782,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs b/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs index b07429f409cb60..2849756d131b4e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs @@ -414,8 +414,7 @@ public void SetThreadPrincipal(IPrincipal principal) Debug.Assert(mi != null); // Don't throw PNSE if null like for WindowsPrincipal as UnauthenticatedPrincipal should // be available on all platforms. - Volatile.Write(ref s_getUnauthenticatedPrincipal, - mi.CreateDelegate>()); + s_getUnauthenticatedPrincipal = mi.CreateDelegate>(); } principal = s_getUnauthenticatedPrincipal(); @@ -430,8 +429,7 @@ public void SetThreadPrincipal(IPrincipal principal) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_Principal); } - Volatile.Write(ref s_getWindowsPrincipal, - mi.CreateDelegate>()); + s_getWindowsPrincipal = mi.CreateDelegate>(); } principal = s_getWindowsPrincipal(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs index 24f8794d852afd..25b6965ee2d12e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs @@ -62,7 +62,7 @@ public static int ByteLength(Array array) nuint byteLength = array.NativeLength * (nuint)array.GetElementSize(); - // This API is explosed both as Buffer.ByteLength and also used indirectly in argument + // This API is exposed both as Buffer.ByteLength and also used indirectly in argument // checks for Buffer.GetByte/SetByte. // // If somebody called Get/SetByte on 2GB+ arrays, there is a decent chance that @@ -177,6 +177,9 @@ ref Unsafe.As(ref source), private const uint BulkMoveWithWriteBarrierChunk = 0x4000; #endif +#if NATIVEAOT + [System.Runtime.RuntimeExport("RhBuffer_BulkMoveWithWriteBarrier")] +#endif internal static void BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount) { if (byteCount <= BulkMoveWithWriteBarrierChunk) diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/SharedArrayPool.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/SharedArrayPool.cs index 89bbd450452391..3fa044d074d607 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/SharedArrayPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/SharedArrayPool.cs @@ -40,10 +40,7 @@ internal sealed partial class SharedArrayPool : ArrayPool /// Allocate a new and try to store it into the array. private unsafe SharedArrayPoolPartitions CreatePerCorePartitions(int bucketIndex) { -#pragma warning disable 8500 // sizeof of managed types - int elementSize = sizeof(T); -#pragma warning restore 8500 - var inst = new SharedArrayPoolPartitions(elementSize); + var inst = new SharedArrayPoolPartitions(); return Interlocked.CompareExchange(ref _buckets[bucketIndex], inst, null) ?? inst; } @@ -199,7 +196,7 @@ public bool Trim() SharedArrayPoolPartitions?[] perCoreBuckets = _buckets; for (int i = 0; i < perCoreBuckets.Length; i++) { - perCoreBuckets[i]?.Trim(currentMilliseconds, Id, pressure, Utilities.GetMaxSizeForBucket(i)); + perCoreBuckets[i]?.Trim(currentMilliseconds, Id, pressure); } // Trim each of the TLS buckets. Note that threads may be modifying their TLS slots concurrently with @@ -323,14 +320,13 @@ internal sealed class SharedArrayPoolPartitions private readonly Partition[] _partitions; /// Initializes the partitions. - /// The size of the elements stored in arrays. - public SharedArrayPoolPartitions(int elementSize) + public SharedArrayPoolPartitions() { // Create the partitions. We create as many as there are processors, limited by our max. var partitions = new Partition[SharedArrayPoolStatics.s_partitionCount]; for (int i = 0; i < partitions.Length; i++) { - partitions[i] = new Partition(elementSize); + partitions[i] = new Partition(); } _partitions = partitions; } @@ -374,23 +370,20 @@ public bool TryPush(Array array) return null; } - public void Trim(int currentMilliseconds, int id, Utilities.MemoryPressure pressure, int bucketSize) + public void Trim(int currentMilliseconds, int id, Utilities.MemoryPressure pressure) { Partition[] partitions = _partitions; for (int i = 0; i < partitions.Length; i++) { - partitions[i].Trim(currentMilliseconds, id, pressure, bucketSize); + partitions[i].Trim(currentMilliseconds, id, pressure); } } /// Provides a simple, bounded stack of arrays, protected by a lock. - /// The size of the elements stored in arrays. - private sealed class Partition(int elementSize) + private sealed class Partition { /// The arrays in the partition. private readonly Array?[] _arrays = new Array[SharedArrayPoolStatics.s_maxArraysPerPartition]; - /// The size of the elements stored in arrays. - private readonly int _elementSize = elementSize; /// Number of arrays stored in . private int _count; /// Timestamp set by Trim when it sees this as 0. @@ -437,20 +430,11 @@ public bool TryPush(Array array) return arr; } - public void Trim(int currentMilliseconds, int id, Utilities.MemoryPressure pressure, int bucketSize) + public void Trim(int currentMilliseconds, int id, Utilities.MemoryPressure pressure) { const int TrimAfterMS = 60 * 1000; // Trim after 60 seconds for low/moderate pressure const int HighTrimAfterMS = 10 * 1000; // Trim after 10 seconds for high pressure - const int LargeBucket = 16384; // If the bucket is larger than this we'll trim an extra when under high pressure - - const int ModerateTypeSize = 16; // If T is larger than this we'll trim an extra when under high pressure - const int LargeTypeSize = 32; // If T is larger than this we'll trim an extra (additional) when under high pressure - - const int LowTrimCount = 1; // Trim one item when pressure is low - const int MediumTrimCount = 2; // Trim two items when pressure is moderate - int HighTrimCount = SharedArrayPoolStatics.s_maxArraysPerPartition; // Trim all items when pressure is high - if (_count == 0) { return; @@ -477,38 +461,16 @@ public void Trim(int currentMilliseconds, int id, Utilities.MemoryPressure press } // We've elapsed enough time since the first item went into the partition. - // Drop the top item so it can be collected and make the partition look a little newer. + // Drop the top item(s) so they can be collected. - ArrayPoolEventSource log = ArrayPoolEventSource.Log; - int trimCount = LowTrimCount; - switch (pressure) + int trimCount = pressure switch { - case Utilities.MemoryPressure.High: - trimCount = HighTrimCount; - - // When pressure is high, aggressively trim larger arrays. - if (bucketSize > LargeBucket) - { - trimCount++; - } - - if (_elementSize > ModerateTypeSize) - { - trimCount++; - - if (_elementSize > LargeTypeSize) - { - trimCount++; - } - } - - break; - - case Utilities.MemoryPressure.Medium: - trimCount = MediumTrimCount; - break; - } + Utilities.MemoryPressure.High => SharedArrayPoolStatics.s_maxArraysPerPartition, + Utilities.MemoryPressure.Medium => 2, + _ => 1, + }; + ArrayPoolEventSource log = ArrayPoolEventSource.Log; while (_count > 0 && trimCount-- > 0) { Array? array = _arrays[--_count]; diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.Int128.cs new file mode 100644 index 00000000000000..5264f100112eb7 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.Int128.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Buffers.Text +{ + internal static partial class FormattingHelpers + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(UInt128 value) + { + ulong upper = value.Upper; + + // 1e19 is 8AC7_2304_89E8_0000 + // 1e20 is 5_6BC7_5E2D_6310_0000 + // 1e21 is 36_35C9_ADC5_DEA0_0000 + + if (upper == 0) + { + // We have less than 64-bits, so just return the lower count + return CountDigits(value.Lower); + } + + // We have more than 1e19, so we have at least 20 digits + int digits = 20; + + if (upper > 5) + { + // ((2^128) - 1) / 1e20 < 34_02_823_669_209_384_635 which + // is 18.5318 digits, meaning the result definitely fits + // into 64-bits and we only need to add the lower digit count + + value /= new UInt128(0x5, 0x6BC7_5E2D_6310_0000); // value /= 1e20 + Debug.Assert(value.Upper == 0); + + digits += CountDigits(value.Lower); + } + else if ((upper == 5) && (value.Lower >= 0x6BC75E2D63100000)) + { + // We're greater than 1e20, but definitely less than 1e21 + // so we have exactly 21 digits + + digits++; + Debug.Assert(digits == 21); + } + + return digits; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountHexDigits(UInt128 value) + { + // The number of hex digits is log16(value) + 1, or log2(value) / 4 + 1 + return ((int)UInt128.Log2(value) >> 2) + 1; + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs index 3da8684132f077..18eac2cf08eb7e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Buffers.Binary; using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; @@ -11,47 +10,6 @@ namespace System.Buffers.Text { internal static partial class FormattingHelpers { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountDigits(UInt128 value) - { - ulong upper = value.Upper; - - // 1e19 is 8AC7_2304_89E8_0000 - // 1e20 is 5_6BC7_5E2D_6310_0000 - // 1e21 is 36_35C9_ADC5_DEA0_0000 - - if (upper == 0) - { - // We have less than 64-bits, so just return the lower count - return CountDigits(value.Lower); - } - - // We have more than 1e19, so we have at least 20 digits - int digits = 20; - - if (upper > 5) - { - // ((2^128) - 1) / 1e20 < 34_02_823_669_209_384_635 which - // is 18.5318 digits, meaning the result definitely fits - // into 64-bits and we only need to add the lower digit count - - value /= new UInt128(0x5, 0x6BC7_5E2D_6310_0000); // value /= 1e20 - Debug.Assert(value.Upper == 0); - - digits += CountDigits(value.Lower); - } - else if ((upper == 5) && (value.Lower >= 0x6BC75E2D63100000)) - { - // We're greater than 1e20, but definitely less than 1e21 - // so we have exactly 21 digits - - digits++; - Debug.Assert(digits == 21); - } - - return digits; - } - // Based on do_count_digits from https://github.com/fmtlib/fmt/blob/662adf4f33346ba9aba8b072194e319869ede54a/include/fmt/format.h#L1124 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDigits(ulong value) @@ -149,13 +107,6 @@ public static int CountDigits(uint value) return (int)((value + tableValue) >> 32); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountHexDigits(UInt128 value) - { - // The number of hex digits is log16(value) + 1, or log2(value) / 4 + 1 - return ((int)UInt128.Log2(value) >> 2) + 1; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountHexDigits(ulong value) { diff --git a/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs b/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs index 22ee77a8cc6e64..43608b97f78ff1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/CodeDom/Compiler/IndentedTextWriter.cs @@ -174,6 +174,17 @@ public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] _writer.Write(format, arg); } + /// + /// Writes out a formatted string, using the same semantics as specified. + /// + /// The formatting string to use. + /// The argument span to output. + public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + OutputTabs(); + _writer.Write(format, arg); + } + /// /// Asynchronously writes the specified to the underlying , inserting /// tabs at the start of every line. @@ -352,6 +363,18 @@ public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeForm _tabsPending = true; } + /// + /// Writes out a formatted string, followed by a line terminator, using the same semantics as specified. + /// + /// The formatting string to use. + /// The argument span to output. + public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + OutputTabs(); + _writer.WriteLine(format, arg); + _tabsPending = true; + } + [CLSCompliant(false)] public override void WriteLine(uint value) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/CollectionExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/CollectionExtensions.cs index 068536049a65f9..6c7949eed7bf74 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/CollectionExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/CollectionExtensions.cs @@ -82,7 +82,7 @@ public static ReadOnlyDictionary AsReadOnly(this IDi /// The list to which the elements should be added. /// The span whose elements should be added to the end of the . /// The is null. - public static void AddRange(this List list, ReadOnlySpan source) + public static void AddRange(this List list, /*params*/ ReadOnlySpan source) { if (list is null) { @@ -109,7 +109,7 @@ public static void AddRange(this List list, ReadOnlySpan source) /// The span whose elements should be added to the . /// The is null. /// is less than 0 or greater than 's . - public static void InsertRange(this List list, int index, ReadOnlySpan source) + public static void InsertRange(this List list, int index, /*params*/ ReadOnlySpan source) { if (list is null) { diff --git a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs index 3ab01cee369168..9fe1c77a1837e8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs @@ -85,7 +85,7 @@ static bool TryConvertFromInvariantString( { Type? typeDescriptorType = Type.GetType("System.ComponentModel.TypeDescriptor, System.ComponentModel.TypeConverter", throwOnError: false); MethodInfo? mi = typeDescriptorType?.GetMethod("ConvertFromInvariantString", BindingFlags.NonPublic | BindingFlags.Static); - Volatile.Write(ref s_convertFromInvariantString, mi == null ? new object() : mi.CreateDelegate>()); + s_convertFromInvariantString = mi == null ? new object() : mi.CreateDelegate>(); } if (!(s_convertFromInvariantString is Func convertFromInvariantString)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs index f2d89445f834ba..189e54dcc1ef74 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs @@ -1117,6 +1117,14 @@ object IConvertible.ToType(Type type, IFormatProvider? provider) // IFloatingPoint // + /// + public static TInteger ConvertToInteger(decimal value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + + /// + public static TInteger ConvertToIntegerNative(decimal value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + /// int IFloatingPoint.GetExponentByteCount() => sizeof(sbyte); diff --git a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs index d24059770d5f88..cc8a66e341b529 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs @@ -23,14 +23,30 @@ public abstract partial class Delegate : ICloneable, ISerializable return a.CombineImpl(b); } - public static Delegate? Combine(params Delegate?[]? delegates) + public static Delegate? Combine(params Delegate?[]? delegates) => + Combine((ReadOnlySpan)delegates); + + /// + /// Concatenates the invocation lists of an span of delegates. + /// + /// The span of delegates to combine. + /// + /// A new delegate with an invocation list that concatenates the invocation lists of the delegates in the span. + /// Returns if is , + /// if contains zero elements, or if every entry in is . + /// + public static Delegate? Combine(/*params*/ ReadOnlySpan delegates) { - if (delegates == null || delegates.Length == 0) - return null; + Delegate? d = null; - Delegate? d = delegates[0]; - for (int i = 1; i < delegates.Length; i++) - d = Combine(d, delegates[i]); + if (!delegates.IsEmpty) + { + d = delegates[0]; + for (int i = 1; i < delegates.Length; i++) + { + d = Combine(d, delegates[i]); + } + } return d; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs index 2d82ed0c0e7f50..5ee6c949bc97e5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/UnconditionalSuppressMessageAttribute.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable + namespace System.Diagnostics.CodeAnalysis { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 265035996eee0b..48cab155a9425c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1461,6 +1461,8 @@ public void Dispose() /// True if called from Dispose(), false if called from the finalizer. protected virtual void Dispose(bool disposing) { + // NOTE: If !IsSupported, we use ILLink.Substitutions to nop out the finalizer. + // Do not add any code before this line (or you'd need to delete the substitution). if (!IsSupported) { return; @@ -1504,6 +1506,7 @@ protected virtual void Dispose(bool disposing) /// ~EventSource() { + // NOTE: we nop out this method body if !IsSupported using ILLink.Substitutions. this.Dispose(false); } #endregion diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs index 71d73546bc1364..81a6792b599cd5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Double.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs @@ -655,6 +655,16 @@ public static bool IsPow2(double value) [Intrinsic] public static double Ceiling(double x) => Math.Ceiling(x); + /// + [Intrinsic] + public static TInteger ConvertToInteger(double value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + + /// + [Intrinsic] + public static TInteger ConvertToIntegerNative(double value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + /// [Intrinsic] public static double Floor(double x) => Math.Floor(x); @@ -855,9 +865,11 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati public static double Lerp(double value1, double value2, double amount) => (value1 * (1.0 - amount)) + (value2 * amount); /// + [Intrinsic] public static double ReciprocalEstimate(double x) => Math.ReciprocalEstimate(x); /// + [Intrinsic] public static double ReciprocalSqrtEstimate(double x) => Math.ReciprocalSqrtEstimate(x); /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index 20fd34bf70d89c..d2b18ed344cc37 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -1746,7 +1746,7 @@ bool ISpanFormattable.TryFormat(Span destination, out int charsWritten, Re /// A span containing the character that represents the standard format string that defines the acceptable format of destination. This may be empty, or "g", "d", "f", or "x". /// if the formatting was successful; otherwise, if the destination span wasn't large enough to contain the formatted value. /// The format parameter contains an invalid value. - public static unsafe bool TryFormat(TEnum value, Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.EnumFormat)] ReadOnlySpan format = default) where TEnum : struct, Enum + public static unsafe bool TryFormat(TEnum value, Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.EnumFormat)] ReadOnlySpan format = default) where TEnum : struct { RuntimeType rt = (RuntimeType)typeof(TEnum); Type underlyingType = typeof(TEnum).GetEnumUnderlyingType(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs index 87199ed3f1eedf..582492c6c40f84 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Browser.cs @@ -14,32 +14,33 @@ internal sealed partial class CalendarData private const int CALENDAR_INFO_BUFFER_LEN = 1000; private unsafe bool JSLoadCalendarDataFromBrowser(string localeName, CalendarId calendarId) { - char* buffer = stackalloc char[CALENDAR_INFO_BUFFER_LEN]; - int exception; - object exResult; - int resultLength = Interop.JsGlobalization.GetCalendarInfo(localeName, calendarId, buffer, CALENDAR_INFO_BUFFER_LEN, out exception, out exResult); - if (exception != 0) - throw new Exception((string)exResult); - string result = new string(buffer, 0, resultLength); - string[] subresults = result.Split("##"); - if (subresults.Length < 14) - throw new Exception("CalendarInfo recieved from the Browser is in icorrect format."); - // JS always has one result per locale, so even arrays are initialized with one element - this.sNativeName = string.IsNullOrEmpty(subresults[0]) ? ((CalendarId)calendarId).ToString() : subresults[0]; // this is EnglishName, not NativeName but it's the best we can do - this.saYearMonths = new string[] { subresults[1] }; - this.sMonthDay = subresults[2]; - this.saLongDates = new string[] { subresults[3] }; - this.saShortDates = new string[] { subresults[4] }; - this.saEraNames = new string[] { subresults[5] }; - this.saAbbrevEraNames = new string[] { subresults[6] }; - this.saDayNames = subresults[7].Split("||"); - this.saAbbrevDayNames = subresults[8].Split("||"); - this.saSuperShortDayNames = subresults[9].Split("||"); - this.saMonthNames = ResizeMonthsArray(subresults[10].Split("||")); - this.saAbbrevMonthNames = ResizeMonthsArray(subresults[11].Split("||")); - this.saMonthGenitiveNames = ResizeMonthsArray(subresults[12].Split("||")); - this.saAbbrevMonthGenitiveNames = ResizeMonthsArray(subresults[13].Split("||")); - return true; + ReadOnlySpan localeNameSpan = localeName.AsSpan(); + fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) + { + char* buffer = stackalloc char[CALENDAR_INFO_BUFFER_LEN]; + nint exceptionPtr = Interop.JsGlobalization.GetCalendarInfo(pLocaleName, localeNameSpan.Length, calendarId, buffer, CALENDAR_INFO_BUFFER_LEN, out int resultLength); + Helper.MarshalAndThrowIfException(exceptionPtr); + string result = new string(buffer, 0, resultLength); + string[] subresults = result.Split("##"); + if (subresults.Length < 14) + throw new Exception("CalendarInfo recieved from the Browser is in icorrect format."); + // JS always has one result per locale, so even arrays are initialized with one element + this.sNativeName = string.IsNullOrEmpty(subresults[0]) ? ((CalendarId)calendarId).ToString() : subresults[0]; // this is EnglishName, not NativeName but it's the best we can do + this.saYearMonths = new string[] { subresults[1] }; + this.sMonthDay = subresults[2]; + this.saLongDates = new string[] { subresults[3] }; + this.saShortDates = new string[] { subresults[4] }; + this.saEraNames = new string[] { subresults[5] }; + this.saAbbrevEraNames = new string[] { subresults[6] }; + this.saDayNames = subresults[7].Split("||"); + this.saAbbrevDayNames = subresults[8].Split("||"); + this.saSuperShortDayNames = subresults[9].Split("||"); + this.saMonthNames = ResizeMonthsArray(subresults[10].Split("||")); + this.saAbbrevMonthNames = ResizeMonthsArray(subresults[11].Split("||")); + this.saMonthGenitiveNames = ResizeMonthsArray(subresults[12].Split("||")); + this.saAbbrevMonthGenitiveNames = ResizeMonthsArray(subresults[13].Split("||")); + return true; + } static string[] ResizeMonthsArray(string[] months) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs index 75440b2a23c458..bc532fcb26c059 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs @@ -198,10 +198,13 @@ private unsafe int IndexOfOrdinalIgnoreCaseHelper(ReadOnlySpan source, Rea #if TARGET_BROWSER if (GlobalizationMode.Hybrid) { - int result = Interop.JsGlobalization.IndexOf(m_name, b, target.Length, a, source.Length, options, fromBeginning, out int exception, out object ex_result); - if (exception != 0) - throw new Exception((string)ex_result); - return result; + ReadOnlySpan cultureNameSpan = m_name.AsSpan(); + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) + { + nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result); + Helper.MarshalAndThrowIfException(exceptionPtr); + return result; + } } #elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) @@ -300,10 +303,13 @@ private unsafe int IndexOfOrdinalHelper(ReadOnlySpan source, ReadOnlySpan< #if TARGET_BROWSER if (GlobalizationMode.Hybrid) { - int result = Interop.JsGlobalization.IndexOf(m_name, b, target.Length, a, source.Length, options, fromBeginning, out int exception, out object ex_result); - if (exception != 0) - throw new Exception((string)ex_result); - return result; + ReadOnlySpan cultureNameSpan = m_name.AsSpan(); + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) + { + nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result); + Helper.MarshalAndThrowIfException(exceptionPtr); + return result; + } } #elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs index 1d265dc70450a8..e8935a6d2439cc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.WebAssembly.cs @@ -47,86 +47,74 @@ private static void AssertIndexingSupported(CompareOptions options, string cultu private unsafe int JsCompareString(ReadOnlySpan string1, ReadOnlySpan string2, CompareOptions options) { AssertHybridOnWasm(options); - string cultureName = m_name; - AssertComparisonSupported(options, cultureName); + AssertComparisonSupported(options, m_name); - int cmpResult; + ReadOnlySpan cultureNameSpan = m_name.AsSpan(); fixed (char* pString1 = &MemoryMarshal.GetReference(string1)) fixed (char* pString2 = &MemoryMarshal.GetReference(string2)) + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) { - cmpResult = Interop.JsGlobalization.CompareString(cultureName, pString1, string1.Length, pString2, string2.Length, options, out int exception, out object ex_result); - if (exception != 0) - throw new Exception((string)ex_result); + nint exceptionPtr = Interop.JsGlobalization.CompareString(pCultureName, cultureNameSpan.Length, pString1, string1.Length, pString2, string2.Length, options, out int cmpResult); + Helper.MarshalAndThrowIfException(exceptionPtr); + return cmpResult; } - - return cmpResult; } private unsafe bool JsStartsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) { AssertHybridOnWasm(options); Debug.Assert(!prefix.IsEmpty); - string cultureName = m_name; - AssertIndexingSupported(options, cultureName); + AssertIndexingSupported(options, m_name); - bool result; + ReadOnlySpan cultureNameSpan = m_name.AsSpan(); fixed (char* pSource = &MemoryMarshal.GetReference(source)) fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) { - result = Interop.JsGlobalization.StartsWith(cultureName, pSource, source.Length, pPrefix, prefix.Length, options, out int exception, out object ex_result); - if (exception != 0) - throw new Exception((string)ex_result); + nint exceptionPtr = Interop.JsGlobalization.StartsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result); + Helper.MarshalAndThrowIfException(exceptionPtr); + return result; } - - - return result; } private unsafe bool JsEndsWith(ReadOnlySpan source, ReadOnlySpan prefix, CompareOptions options) { AssertHybridOnWasm(options); Debug.Assert(!prefix.IsEmpty); - string cultureName = m_name; - AssertIndexingSupported(options, cultureName); + AssertIndexingSupported(options, m_name); - bool result; + ReadOnlySpan cultureNameSpan = m_name.AsSpan(); fixed (char* pSource = &MemoryMarshal.GetReference(source)) fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix)) + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) { - result = Interop.JsGlobalization.EndsWith(cultureName, pSource, source.Length, pPrefix, prefix.Length, options, out int exception, out object ex_result); - if (exception != 0) - throw new Exception((string)ex_result); + nint exceptionPtr = Interop.JsGlobalization.EndsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result); + Helper.MarshalAndThrowIfException(exceptionPtr); + return result; } - - return result; } private unsafe int JsIndexOfCore(ReadOnlySpan source, ReadOnlySpan target, CompareOptions options, int* matchLengthPtr, bool fromBeginning) { AssertHybridOnWasm(options); Debug.Assert(!target.IsEmpty); - string cultureName = m_name; - AssertIndexingSupported(options, cultureName); + AssertIndexingSupported(options, m_name); - int idx; if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options)) { - idx = (options & CompareOptions.IgnoreCase) != 0 ? + return (options & CompareOptions.IgnoreCase) != 0 ? IndexOfOrdinalIgnoreCaseHelper(source, target, options, matchLengthPtr, fromBeginning) : IndexOfOrdinalHelper(source, target, options, matchLengthPtr, fromBeginning); } - else + ReadOnlySpan cultureNameSpan = m_name.AsSpan(); + fixed (char* pSource = &MemoryMarshal.GetReference(source)) + fixed (char* pTarget = &MemoryMarshal.GetReference(target)) + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) { - fixed (char* pSource = &MemoryMarshal.GetReference(source)) - fixed (char* pTarget = &MemoryMarshal.GetReference(target)) - { - idx = Interop.JsGlobalization.IndexOf(m_name, pTarget, target.Length, pSource, source.Length, options, fromBeginning, out int exception, out object ex_result); - if (exception != 0) - throw new Exception((string)ex_result); - } + nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, pTarget, target.Length, pSource, source.Length, options, fromBeginning, out int idx); + Helper.MarshalAndThrowIfException(exceptionPtr); + return idx; } - - return idx; } // there are chars that are ignored by ICU hashing algorithm but not ignored by invariant hashing diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs index 8a8edadaf326d0..417bd563bf3574 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Browser.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; namespace System.Globalization { @@ -41,17 +42,22 @@ private void JSInitLocaleInfo() private unsafe (string, string) JSGetLocaleInfo(string cultureName, string localeName) { - char* buffer = stackalloc char[LOCALE_INFO_BUFFER_LEN]; - int resultLength = Interop.JsGlobalization.GetLocaleInfo(cultureName, localeName, buffer, LOCALE_INFO_BUFFER_LEN, out int exception, out object exResult); - if (exception != 0) - throw new Exception((string)exResult); - string result = new string(buffer, 0, resultLength); - string[] subresults = result.Split("##"); - if (subresults.Length == 0) - throw new Exception("LocaleInfo recieved from the Browser is in incorrect format."); - if (subresults.Length == 1) - return (subresults[0], ""); // Neutral culture - return (subresults[0], subresults[1]); + ReadOnlySpan cultureNameSpan = cultureName.AsSpan(); + ReadOnlySpan localeNameSpan = localeName.AsSpan(); + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan)) + fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) + { + char* buffer = stackalloc char[LOCALE_INFO_BUFFER_LEN]; + nint exceptionPtr = Interop.JsGlobalization.GetLocaleInfo(pCultureName, cultureNameSpan.Length, pLocaleName, localeNameSpan.Length, buffer, LOCALE_INFO_BUFFER_LEN, out int resultLength); + Helper.MarshalAndThrowIfException(exceptionPtr); + string result = new string(buffer, 0, resultLength); + string[] subresults = result.Split("##"); + if (subresults.Length == 0) + throw new Exception("LocaleInfo recieved from the Browser is in incorrect format."); + if (subresults.Length == 1) + return (subresults[0], ""); // Neutral culture + return (subresults[0], subresults[1]); + } } private string JSGetNativeDisplayName(string localeName, string cultureName) @@ -64,43 +70,82 @@ private string JSGetNativeDisplayName(string localeName, string cultureName) private static unsafe CultureData JSLoadCultureInfoFromBrowser(string localeName, CultureData culture) { - char* buffer = stackalloc char[CULTURE_INFO_BUFFER_LEN]; - int resultLength = Interop.JsGlobalization.GetCultureInfo(localeName, buffer, CULTURE_INFO_BUFFER_LEN, out int exception, out object exResult); - if (exception != 0) - throw new Exception((string)exResult); - string result = new string(buffer, 0, resultLength); - string[] subresults = result.Split("##"); - if (subresults.Length < 4) - throw new Exception("CultureInfo recieved from the Browser is in incorrect format."); - culture._sAM1159 = subresults[0]; - culture._sPM2359 = subresults[1]; - culture._saLongTimes = new string[] { subresults[2] }; - culture._saShortTimes = new string[] { subresults[3] }; + ReadOnlySpan localeNameSpan = localeName.AsSpan(); + fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) + { + char* buffer = stackalloc char[CULTURE_INFO_BUFFER_LEN]; + nint exceptionPtr = Interop.JsGlobalization.GetCultureInfo(pLocaleName, localeNameSpan.Length, buffer, CULTURE_INFO_BUFFER_LEN, out int resultLength); + Helper.MarshalAndThrowIfException(exceptionPtr); + string result = new string(buffer, 0, resultLength); + string[] subresults = result.Split("##"); + if (subresults.Length < 4) + throw new Exception("CultureInfo recieved from the Browser is in incorrect format."); + culture._sAM1159 = subresults[0]; + culture._sPM2359 = subresults[1]; + culture._saLongTimes = new string[] { subresults[2] }; + culture._saShortTimes = new string[] { subresults[3] }; + } return culture; } private static unsafe int GetFirstDayOfWeek(string localeName) { - int result = Interop.JsGlobalization.GetFirstDayOfWeek(localeName, out int exception, out object ex_result); - if (exception != 0) + ReadOnlySpan localeNameSpan = localeName.AsSpan(); + fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) { - // Failed, just use 0 - Debug.Fail($"[CultureData.GetFirstDayOfWeek()] failed with {ex_result}"); - return 0; + nint exceptionPtr = Interop.JsGlobalization.GetFirstDayOfWeek(pLocaleName, localeNameSpan.Length, out int result); + if (exceptionPtr != IntPtr.Zero) + { + int success = Helper.MarshalAndThrowIfException( + exceptionPtr, + failOnlyDebug: true, + failureMessage: $"[CultureData.GetFirstDayOfWeek()] failed with"); + // Failed, just use 0 + if (success == -1) + return 0; + } + return result; } - return result; } private static unsafe int GetFirstWeekOfYear(string localeName) { - int result = Interop.JsGlobalization.GetFirstWeekOfYear(localeName, out int exception, out object ex_result); - if (exception != 0) + ReadOnlySpan localeNameSpan = localeName.AsSpan(); + fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan)) + { + nint exceptionPtr = Interop.JsGlobalization.GetFirstWeekOfYear(pLocaleName, localeNameSpan.Length, out int result); + if (exceptionPtr != IntPtr.Zero) + { + int success = Helper.MarshalAndThrowIfException( + exceptionPtr, + failOnlyDebug: true, + failureMessage: $"[CultureData.GetFirstWeekOfYear()] failed with"); + // Failed, just use 0 + if (success == -1) + return 0; + } + return result; + } + } + } + + internal static class Helper + { + internal static int MarshalAndThrowIfException(nint exceptionPtr, bool failOnlyDebug = false, string failureMessage = "") + { + if (exceptionPtr != IntPtr.Zero) { - // Failed, just use 0 - Debug.Fail($"[CultureData.GetFirstDayOfWeek()] failed with {ex_result}"); - return 0; + string message = Marshal.PtrToStringUni(exceptionPtr)!; + Marshal.FreeHGlobal(exceptionPtr); + if (failOnlyDebug) + { + Debug.Fail($"{failureMessage} {message}"); + return -1; + } + throw new Exception(message); } - return result; + return 0; } + } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 189ce06de70335..37d32f9cd57f47 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -111,14 +111,13 @@ internal sealed partial class CultureData private string? _sAM1159; // (user can override) AM designator private string? _sPM2359; // (user can override) PM designator private string? _sTimeSeparator; - private volatile string[]? _saLongTimes; // (user can override) time format - private volatile string[]? _saShortTimes; // (user can override) short time format - private volatile string[]? _saDurationFormats; // time duration format + private string[]? _saLongTimes; // (user can override) time format + private string[]? _saShortTimes; // (user can override) short time format // Calendar specific data private int _iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really) private int _iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really) - private volatile CalendarId[]? _waCalendars; // all available calendar type(s). The first one is the default calendar + private CalendarId[]? _waCalendars; // all available calendar type(s). The first one is the default calendar // Store for specific data about each calendar private CalendarData?[]? _calendars; // Store for specific calendar data @@ -150,7 +149,7 @@ internal sealed partial class CultureData /// private static Dictionary RegionNames => s_regionNames ??= - new Dictionary(257 /* prime */, StringComparer.OrdinalIgnoreCase) + new Dictionary(255, StringComparer.OrdinalIgnoreCase) { { "001", "en-001" }, { "029", "en-029" }, @@ -411,7 +410,7 @@ internal sealed partial class CultureData // Cache of regions we've already looked up private static volatile Dictionary? s_cachedRegions; - private static volatile Dictionary? s_regionNames; + private static Dictionary? s_regionNames; /// /// The culture name to use to interop with the underlying native globalization libraries like ICU or Windows NLS APIs. @@ -621,7 +620,6 @@ private static CultureData CreateCultureWithInvariantData() invariant._sPM2359 = "PM"; // PM designator invariant._saLongTimes = new string[] { "HH:mm:ss" }; // time format invariant._saShortTimes = new string[] { "HH:mm", "hh:mm tt", "H:mm", "h:mm tt" }; // short time format - invariant._saDurationFormats = new string[] { "HH:mm:ss" }; // time duration format // Calendar specific data invariant._iFirstDayOfWeek = 0; // first day of week @@ -661,7 +659,7 @@ private static CultureData CreateCultureWithInvariantData() /// We need an invariant instance, which we build hard-coded /// internal static CultureData Invariant => s_Invariant ??= CreateCultureWithInvariantData(); - private static volatile CultureData? s_Invariant; + private static CultureData? s_Invariant; // Cache of cultures we've already looked up private static volatile Dictionary? s_cachedCultures; @@ -1381,18 +1379,10 @@ internal string[] LongTimes { if (_saLongTimes == null && !GlobalizationMode.Invariant) { - Debug.Assert(!GlobalizationMode.Invariant); - string[]? longTimes = GetTimeFormatsCore(shortFormat: false); - if (longTimes == null || longTimes.Length == 0) - { - _saLongTimes = Invariant._saLongTimes!; - } - else - { - _saLongTimes = longTimes; - } + _saLongTimes = longTimes != null && longTimes.Length != 0 ? longTimes : Invariant._saLongTimes!; } + return _saLongTimes!; } } @@ -1407,23 +1397,13 @@ internal string[] ShortTimes { if (_saShortTimes == null && !GlobalizationMode.Invariant) { - Debug.Assert(!GlobalizationMode.Invariant); - // Try to get the short times from the OS/culture.dll + // If we couldn't find short times, then compute them from long times + // (eg: CORECLR on < Win7 OS & fallback for missing culture.dll) string[]? shortTimes = GetTimeFormatsCore(shortFormat: true); - - if (shortTimes == null || shortTimes.Length == 0) - { - // - // If we couldn't find short times, then compute them from long times - // (eg: CORECLR on < Win7 OS & fallback for missing culture.dll) - // - shortTimes = DeriveShortTimesFromLong(); - } - - // Found short times, use them - _saShortTimes = shortTimes; + _saShortTimes = shortTimes != null && shortTimes.Length != 0 ? shortTimes : DeriveShortTimesFromLong(); } + return _saShortTimes!; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index a0789def2711c1..5c23a1732308c3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -126,8 +126,8 @@ private static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs? s_cachedCulturesByName; - private static volatile Dictionary? s_cachedCulturesByLcid; + private static Dictionary? s_cachedCulturesByName; + private static Dictionary? s_cachedCulturesByLcid; // The parent culture. private CultureInfo? _parent; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs index e98c7071127687..e87960b61792d4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs @@ -1914,8 +1914,8 @@ internal bool YearMonthAdjustment(ref int year, ref int month, bool parsedMonthN internal const string JapaneseLangName = "ja"; internal const string EnglishLangName = "en"; - private static volatile DateTimeFormatInfo? s_jajpDTFI; - private static volatile DateTimeFormatInfo? s_zhtwDTFI; + private static DateTimeFormatInfo? s_jajpDTFI; + private static DateTimeFormatInfo? s_zhtwDTFI; /// /// Create a Japanese DTFI which uses JapaneseCalendar. This is used to parse diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs index edb65a805570a1..ee5919bae506b2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs @@ -26,7 +26,7 @@ public class GregorianCalendar : Calendar internal static ReadOnlySpan DaysToMonth366 => [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366]; - private static volatile Calendar? s_defaultInstance; + private static Calendar? s_defaultInstance; public override DateTime MinSupportedDateTime => DateTime.MinValue; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs index cd37d6ba65292f..a6a5cc72de3ab2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs @@ -42,7 +42,7 @@ public partial class JapaneseCalendar : Calendar // Using a field initializer rather than a static constructor so that the whole class can be lazy // init. - private static volatile EraInfo[]? s_japaneseEraInfo; + private static EraInfo[]? s_japaneseEraInfo; // m_EraInfo must be listed in reverse chronological order. The most recent era // should be the first element. @@ -67,20 +67,19 @@ public partial class JapaneseCalendar : Calendar internal static EraInfo[] GetEraInfo() { // See if we need to build it - return s_japaneseEraInfo ?? - (s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras()) ?? + return s_japaneseEraInfo ??= + (GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras()) ?? // See if we have to use the built-in eras - (s_japaneseEraInfo = new EraInfo[] - { + [ new EraInfo(5, 2019, 5, 1, 2018, 1, GregorianCalendar.MaxYear - 2018, "\x4ee4\x548c", "\x4ee4", "R"), new EraInfo(4, 1989, 1, 8, 1988, 1, 2019 - 1988, "\x5e73\x6210", "\x5e73", "H"), new EraInfo(3, 1926, 12, 25, 1925, 1, 1989 - 1925, "\x662d\x548c", "\x662d", "S"), new EraInfo(2, 1912, 7, 30, 1911, 1, 1926 - 1911, "\x5927\x6b63", "\x5927", "T"), new EraInfo(1, 1868, 1, 1, 1867, 1, 1912 - 1867, "\x660e\x6cbb", "\x660e", "M") - }); + ]; } - internal static volatile Calendar? s_defaultInstance; + internal static Calendar? s_defaultInstance; internal GregorianCalendarHelper _helper; internal static Calendar GetDefaultInstance() => s_defaultInstance ??= new JapaneseCalendar(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs index a20ff0be7c6d11..0424b678e4b182 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs @@ -39,7 +39,7 @@ namespace System.Globalization /// public sealed class NumberFormatInfo : IFormatProvider, ICloneable { - private static volatile NumberFormatInfo? s_invariantInfo; + private static NumberFormatInfo? s_invariantInfo; internal static readonly string[] s_asciiDigits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; internal static readonly int[] s_intArrayWithElement3 = [3]; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/RegionInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/RegionInfo.cs index 091f3a8f6561c8..c8a736ffa4e695 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/RegionInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/RegionInfo.cs @@ -21,7 +21,7 @@ public class RegionInfo private readonly CultureData _cultureData; // The RegionInfo for our current region - internal static volatile RegionInfo? s_currentRegionInfo; + internal static RegionInfo? s_currentRegionInfo; public RegionInfo(string name) { @@ -84,7 +84,6 @@ internal RegionInfo(CultureData cultureData) /// /// This instance provides methods based on the current user settings. - /// These settings are volatile and may change over the lifetime of the /// public static RegionInfo CurrentRegion { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TaiwanCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TaiwanCalendar.cs index 8a282b12457db2..ae935e6011a94f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TaiwanCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TaiwanCalendar.cs @@ -27,7 +27,7 @@ public class TaiwanCalendar : Calendar new EraInfo(1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear }; - private static volatile Calendar? s_defaultInstance; + private static Calendar? s_defaultInstance; private readonly GregorianCalendarHelper _helper; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs index a2dd2a02c05f18..05e8cc3e1d0495 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.WebAssembly.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Runtime.InteropServices; namespace System.Globalization { @@ -13,18 +14,14 @@ internal unsafe void JsChangeCase(char* src, int srcLen, char* dstBuffer, int ds Debug.Assert(!GlobalizationMode.UseNls); Debug.Assert(GlobalizationMode.Hybrid); - int exception; - object ex_result; - if (HasEmptyCultureName) + ReadOnlySpan cultureName = _cultureName.AsSpan(); + fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureName)) { - Interop.JsGlobalization.ChangeCaseInvariant(src, srcLen, dstBuffer, dstBufferCapacity, toUpper, out exception, out ex_result); + nint exceptionPtr = HasEmptyCultureName ? + Interop.JsGlobalization.ChangeCaseInvariant(src, srcLen, dstBuffer, dstBufferCapacity, toUpper) : + Interop.JsGlobalization.ChangeCase(pCultureName, cultureName.Length, src, srcLen, dstBuffer, dstBufferCapacity, toUpper); + Helper.MarshalAndThrowIfException(exceptionPtr); } - else - { - Interop.JsGlobalization.ChangeCase(_cultureName, src, srcLen, dstBuffer, dstBufferCapacity, toUpper, out exception, out ex_result); - } - if (exception != 0) - throw new Exception((string)ex_result); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index adc7df07932f7f..d4459c5162366f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -1314,6 +1314,14 @@ public static bool IsPow2(Half value) /// public static Half Ceiling(Half x) => (Half)MathF.Ceiling((float)x); + /// + public static TInteger ConvertToInteger(Half value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + + /// + public static TInteger ConvertToIntegerNative(Half value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + /// public static Half Floor(Half x) => (Half)MathF.Floor((float)x); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs index 9d1dced98c8c0b..e6cc976336bbfd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs @@ -371,7 +371,16 @@ public static string Combine(string path1, string path2, string path3, string pa public static string Combine(params string[] paths) { ArgumentNullException.ThrowIfNull(paths); + return Combine((ReadOnlySpan)paths); + } + /// + /// Combines a span of strings into a path. + /// + /// A span of parts of the path. + /// The combined paths. + public static string Combine(/*params*/ ReadOnlySpan paths) + { int maxSize = 0; int firstComponent = 0; @@ -520,8 +529,17 @@ public static string Join(string? path1, string? path2, string? path3, string? p public static string Join(params string?[] paths) { ArgumentNullException.ThrowIfNull(paths); + return Join((ReadOnlySpan)paths); + } - if (paths.Length == 0) + /// + /// Concatenates a span of paths into a single path. + /// + /// A span of paths. + /// The concatenated path. + public static string Join(/*params*/ ReadOnlySpan paths) + { + if (paths.IsEmpty) { return string.Empty; } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs index 86d01528643b27..47d847f351d2e8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs @@ -22,9 +22,7 @@ public abstract class Stream : MarshalByRefObject, IDisposable, IAsyncDisposable private protected SemaphoreSlim EnsureAsyncActiveSemaphoreInitialized() => // Lazily-initialize _asyncActiveSemaphore. As we're never accessing the SemaphoreSlim's // WaitHandle, we don't need to worry about Disposing it in the case of a race condition. -#pragma warning disable CS8774 // We lack a NullIffNull annotation for Volatile.Read - Volatile.Read(ref _asyncActiveSemaphore) ?? -#pragma warning restore CS8774 + _asyncActiveSemaphore ?? Interlocked.CompareExchange(ref _asyncActiveSemaphore, new SemaphoreSlim(1, 1), null) ?? _asyncActiveSemaphore; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs index d11c1313ba84d4..947c803d6d2747 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StreamWriter.cs @@ -568,6 +568,23 @@ public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] } } + /// + /// Writes a formatted string to the stream, using the same semantics as . + /// + /// A composite format string. + /// An object span that contains zero or more objects to format and write. + public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, arg, appendNewLine: false); + } + else + { + base.Write(format, arg); + } + } + public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0) { if (GetType() == typeof(StreamWriter)) @@ -619,6 +636,23 @@ public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeForm } } + /// + /// Writes out a formatted string and a new line to the stream, using the same semantics as . + /// + /// A composite format string. + /// An object span that contains zero or more objects to format and write. + public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, arg, appendNewLine: true); + } + else + { + base.WriteLine(format, arg); + } + } + public override Task WriteAsync(char value) { // If we have been inherited into a subclass, the following implementation could be incorrect diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs index 9b5eee9d8c0417..8fc4bb83cd086b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs @@ -12,7 +12,7 @@ namespace System.IO // the resulting sequence of characters to be presented as a string. public class StringWriter : TextWriter { - private static volatile UnicodeEncoding? s_encoding; + private static UnicodeEncoding? s_encoding; private readonly StringBuilder _sb; private bool _isOpen; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.CreateBroadcasting.cs b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.CreateBroadcasting.cs index 41fdf7eb56f964..82c9d6edd619d5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.CreateBroadcasting.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.CreateBroadcasting.cs @@ -268,6 +268,14 @@ public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] } } + public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + foreach (TextWriter writer in _writers) + { + writer.Write(format, arg); + } + } + public override void WriteLine() { foreach (TextWriter writer in _writers) @@ -428,6 +436,14 @@ public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeForm } } + public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + foreach (TextWriter writer in _writers) + { + writer.WriteLine(format, arg); + } + } + public override async Task WriteAsync(char value) { foreach (TextWriter writer in _writers) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs index 289ec5fac7a5e8..27a73516d4be96 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs @@ -317,6 +317,16 @@ public virtual void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] Write(string.Format(FormatProvider, format, arg)); } + /// + /// Writes a formatted string to the text stream, using the same semantics as . + /// + /// A composite format string. + /// An object span that contains zero or more objects to format and write. + public virtual void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + Write(string.Format(FormatProvider, format, arg)); + } + // Writes a line terminator to the text stream. The default line terminator // is Environment.NewLine, but this value can be changed by setting the NewLine property. // @@ -514,6 +524,16 @@ public virtual void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeForma WriteLine(string.Format(FormatProvider, format, arg)); } + /// + /// Writes out a formatted string and a new line to the text stream, using the same semantics as . + /// + /// A composite format string. + /// An object span that contains zero or more objects to format and write. + public virtual void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) + { + WriteLine(string.Format(FormatProvider, format, arg)); + } + #region Task based Async APIs public virtual Task WriteAsync(char value) => Task.Factory.StartNew(static state => @@ -700,6 +720,7 @@ public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1) { } public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1, object? arg2) { } public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, params object?[] arg) { } + public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) { } public override Task WriteAsync(char value) => Task.CompletedTask; public override Task WriteAsync(string? value) => Task.CompletedTask; public override Task WriteAsync(StringBuilder? value, CancellationToken cancellationToken = default) => Task.CompletedTask; @@ -725,6 +746,7 @@ public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeForm public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1) { } public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1, object? arg2) { } public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, params object?[] arg) { } + public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan arg) { } public override Task WriteLineAsync(char value) => Task.CompletedTask; public override Task WriteLineAsync(string? value) => Task.CompletedTask; public override Task WriteLineAsync(StringBuilder? value, CancellationToken cancellationToken = default) => Task.CompletedTask; @@ -833,6 +855,9 @@ protected override void Dispose(bool disposing) [MethodImpl(MethodImplOptions.Synchronized)] public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object?[] arg) => _out.Write(format, arg); + [MethodImpl(MethodImplOptions.Synchronized)] + public override void Write([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, ReadOnlySpan arg) => _out.Write(format, arg); + [MethodImpl(MethodImplOptions.Synchronized)] public override void WriteLine() => _out.WriteLine(); @@ -893,6 +918,9 @@ protected override void Dispose(bool disposing) [MethodImpl(MethodImplOptions.Synchronized)] public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object?[] arg) => _out.WriteLine(format, arg); + [MethodImpl(MethodImplOptions.Synchronized)] + public override void WriteLine([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, ReadOnlySpan arg) => _out.WriteLine(format, arg); + // // On SyncTextWriter all APIs should run synchronously, even the async ones. // diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index e2fe2051ce5c9e..521abb22465e7b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -1195,19 +1195,11 @@ public static double MinMagnitude(double x, double y) /// On ARM64 hardware this may use the FRECPE instruction which performs a single Newton-Raphson iteration. /// On hardware without specialized support, this may just return 1.0 / d. /// + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double ReciprocalEstimate(double d) { - // x86 doesn't provide an estimate instruction for double-precision reciprocal - - if (AdvSimd.Arm64.IsSupported) - { - return AdvSimd.Arm64.ReciprocalEstimateScalar(Vector64.CreateScalar(d)).ToScalar(); - } - else - { - return 1.0 / d; - } + return 1.0 / d; } /// Returns an estimate of the reciprocal square root of a specified number. @@ -1217,19 +1209,11 @@ public static double ReciprocalEstimate(double d) /// On ARM64 hardware this may use the FRSQRTE instruction which performs a single Newton-Raphson iteration. /// On hardware without specialized support, this may just return 1.0 / Sqrt(d). /// + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double ReciprocalSqrtEstimate(double d) { - // x86 doesn't provide an estimate instruction for double-precision reciprocal square root - - if (AdvSimd.Arm64.IsSupported) - { - return AdvSimd.Arm64.ReciprocalSquareRootEstimateScalar(Vector64.CreateScalar(d)).ToScalar(); - } - else - { - return 1.0 / Sqrt(d); - } + return 1.0 / Sqrt(d); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/MathF.cs b/src/libraries/System.Private.CoreLib/src/System/MathF.cs index cc0795255d0c89..05b404abccc51a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MathF.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MathF.cs @@ -313,21 +313,11 @@ public static float MinMagnitude(float x, float y) /// On ARM64 hardware this may use the FRECPE instruction which performs a single Newton-Raphson iteration. /// On hardware without specialized support, this may just return 1.0 / x. /// + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float ReciprocalEstimate(float x) { - if (Sse.IsSupported) - { - return Sse.ReciprocalScalar(Vector128.CreateScalarUnsafe(x)).ToScalar(); - } - else if (AdvSimd.Arm64.IsSupported) - { - return AdvSimd.Arm64.ReciprocalEstimateScalar(Vector64.CreateScalarUnsafe(x)).ToScalar(); - } - else - { - return 1.0f / x; - } + return 1.0f / x; } /// Returns an estimate of the reciprocal square root of a specified number. @@ -338,21 +328,11 @@ public static float ReciprocalEstimate(float x) /// On ARM64 hardware this may use the FRSQRTE instruction which performs a single Newton-Raphson iteration. /// On hardware without specialized support, this may just return 1.0 / Sqrt(x). /// + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float ReciprocalSqrtEstimate(float x) { - if (Sse.IsSupported) - { - return Sse.ReciprocalSqrtScalar(Vector128.CreateScalarUnsafe(x)).ToScalar(); - } - else if (AdvSimd.Arm64.IsSupported) - { - return AdvSimd.Arm64.ReciprocalSquareRootEstimateScalar(Vector64.CreateScalarUnsafe(x)).ToScalar(); - } - else - { - return 1.0f / Sqrt(x); - } + return 1.0f / Sqrt(x); } [Intrinsic] diff --git a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs index 50a0d5b19d5acd..d3c9e28cb0ccda 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs @@ -4173,7 +4173,7 @@ public static bool TryWrite(this Span destination, IFormatProvider? provid /// if the entire interpolated string could be formatted successfully; otherwise, . /// is null. /// The index of a format item is greater than or equal to the number of supplied arguments. - public static bool TryWrite(this Span destination, IFormatProvider? provider, CompositeFormat format, out int charsWritten, ReadOnlySpan args) + public static bool TryWrite(this Span destination, IFormatProvider? provider, CompositeFormat format, out int charsWritten, /*params*/ ReadOnlySpan args) { ArgumentNullException.ThrowIfNull(format); format.ValidateNumberOfArgs(args.Length); diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs index ad75d88cbda7c1..2a89bf96385294 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs @@ -269,8 +269,6 @@ internal static partial class Number private const int SinglePrecisionCustomFormat = 7; private const int DoublePrecisionCustomFormat = 15; - private const int CharStackBufferSize = 32; - /// The non-inclusive upper bound of . /// /// This is a semi-arbitrary bound. For mono, which is often used for more size-constrained workloads, diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs index e36c76007bbdfd..9c92a14f0e75c7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs @@ -16,6 +16,26 @@ public interface IFloatingPoint /// The ceiling of . static virtual TSelf Ceiling(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToPositiveInfinity); + /// Converts a value to a specified integer type using saturation on overflow + /// The integer type to which is converted. + /// The value to be converted. + /// An instance of created from . + static virtual TInteger ConvertToInteger(TSelf value) + where TInteger : IBinaryInteger + { + return TInteger.CreateSaturating(value); + } + + /// Converts a value to a specified integer type using platform specific behavior on overflow. + /// The integer type to which is converted. + /// The value to be converted. + /// An instance of created from . + static virtual TInteger ConvertToIntegerNative(TSelf value) + where TInteger : IBinaryInteger + { + return TSelf.ConvertToInteger(value); + } + /// Computes the floor of a value. /// The value whose floor is to be computed. /// The floor of . diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs index 5d8bc58bbe26ee..0e968e6fca8f34 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs @@ -325,7 +325,7 @@ public static Vector ConvertToDouble(Vector value) } } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -342,7 +342,13 @@ public static Vector ConvertToInt32(Vector value) return result; } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + public static Vector ConvertToInt32Native(Vector value) => ConvertToInt32(value); + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -359,6 +365,12 @@ public static Vector ConvertToInt64(Vector value) return result; } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + public static Vector ConvertToInt64Native(Vector value) => ConvertToInt64(value); + /// Converts a to a . /// The vector to convert. /// The converted vector. @@ -396,7 +408,7 @@ public static Vector ConvertToSingle(Vector value) } } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -414,7 +426,14 @@ public static Vector ConvertToUInt32(Vector value) return result; } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + public static Vector ConvertToUInt32Native(Vector value) => ConvertToUInt32(value); + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -432,6 +451,13 @@ public static Vector ConvertToUInt64(Vector value) return result; } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + public static Vector ConvertToUInt64Native(Vector value) => ConvertToUInt64(value); + /// Creates a new instance where the elements begin at a specified value and which are spaced apart according to another specified value. /// The type of the elements in the vector. /// The value that element 0 will be initialized to. diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs index b182d42b66ecd9..e2c49c820d7738 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs @@ -10,7 +10,8 @@ using EditorBrowsableAttribute = System.ComponentModel.EditorBrowsableAttribute; using EditorBrowsableState = System.ComponentModel.EditorBrowsableState; -#pragma warning disable 0809 //warning CS0809: Obsolete member 'Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' +#pragma warning disable 0809 // Obsolete member 'Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' +#pragma warning disable 8500 // address / sizeof of managed types namespace System { @@ -107,7 +108,7 @@ public unsafe ReadOnlySpan(void* pointer, int length) if (length < 0) ThrowHelper.ThrowArgumentOutOfRangeException(); - _reference = ref Unsafe.As(ref *(byte*)pointer); + _reference = ref *(T*)pointer; _length = length; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameParser.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameParser.cs deleted file mode 100644 index dbaaefd4d8c9dd..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameParser.cs +++ /dev/null @@ -1,438 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; - -namespace System.Reflection -{ - // - // Parses an assembly name. - // - internal ref struct AssemblyNameParser - { - public readonly struct AssemblyNameParts - { - public AssemblyNameParts(string name, Version? version, string? cultureName, AssemblyNameFlags flags, byte[]? publicKeyOrToken) - { - _name = name; - _version = version; - _cultureName = cultureName; - _flags = flags; - _publicKeyOrToken = publicKeyOrToken; - } - - public readonly string _name; - public readonly Version? _version; - public readonly string? _cultureName; - public readonly AssemblyNameFlags _flags; - public readonly byte[]? _publicKeyOrToken; - } - - // Token categories for the lexer. - private enum Token - { - Equals = 1, - Comma = 2, - String = 3, - End = 4, - } - - private enum AttributeKind - { - Version = 1, - Culture = 2, - PublicKeyOrToken = 4, - ProcessorArchitecture = 8, - Retargetable = 16, - ContentType = 32 - } - - private readonly ReadOnlySpan _input; - private int _index; - - private AssemblyNameParser(ReadOnlySpan input) - { - if (input.Length == 0) - throw new ArgumentException(SR.Format_StringZeroLength); - - _input = input; - _index = 0; - } - - public static AssemblyNameParts Parse(string name) - { - return new AssemblyNameParser(name).Parse(); - } - - public static AssemblyNameParts Parse(ReadOnlySpan name) - { - return new AssemblyNameParser(name).Parse(); - } - - private void RecordNewSeenOrThrow(scoped ref AttributeKind seenAttributes, AttributeKind newAttribute) - { - if ((seenAttributes & newAttribute) != 0) - { - ThrowInvalidAssemblyName(); - } - seenAttributes |= newAttribute; - } - - private AssemblyNameParts Parse() - { - // Name must come first. - Token token = GetNextToken(out string name); - if (token != Token.String) - ThrowInvalidAssemblyName(); - - if (string.IsNullOrEmpty(name)) - ThrowInvalidAssemblyName(); - - Version? version = null; - string? cultureName = null; - byte[]? pkt = null; - AssemblyNameFlags flags = 0; - - AttributeKind alreadySeen = default; - token = GetNextToken(); - while (token != Token.End) - { - if (token != Token.Comma) - ThrowInvalidAssemblyName(); - - token = GetNextToken(out string attributeName); - if (token != Token.String) - ThrowInvalidAssemblyName(); - - token = GetNextToken(); - if (token != Token.Equals) - ThrowInvalidAssemblyName(); - - token = GetNextToken(out string attributeValue); - if (token != Token.String) - ThrowInvalidAssemblyName(); - - if (attributeName == string.Empty) - ThrowInvalidAssemblyName(); - - if (attributeName.Equals("Version", StringComparison.OrdinalIgnoreCase)) - { - RecordNewSeenOrThrow(ref alreadySeen, AttributeKind.Version); - version = ParseVersion(attributeValue); - } - - if (attributeName.Equals("Culture", StringComparison.OrdinalIgnoreCase)) - { - RecordNewSeenOrThrow(ref alreadySeen, AttributeKind.Culture); - cultureName = ParseCulture(attributeValue); - } - - if (attributeName.Equals("PublicKey", StringComparison.OrdinalIgnoreCase)) - { - RecordNewSeenOrThrow(ref alreadySeen, AttributeKind.PublicKeyOrToken); - pkt = ParsePKT(attributeValue, isToken: false); - flags |= AssemblyNameFlags.PublicKey; - } - - if (attributeName.Equals("PublicKeyToken", StringComparison.OrdinalIgnoreCase)) - { - RecordNewSeenOrThrow(ref alreadySeen, AttributeKind.PublicKeyOrToken); - pkt = ParsePKT(attributeValue, isToken: true); - } - - if (attributeName.Equals("ProcessorArchitecture", StringComparison.OrdinalIgnoreCase)) - { - RecordNewSeenOrThrow(ref alreadySeen, AttributeKind.ProcessorArchitecture); - flags |= (AssemblyNameFlags)(((int)ParseProcessorArchitecture(attributeValue)) << 4); - } - - if (attributeName.Equals("Retargetable", StringComparison.OrdinalIgnoreCase)) - { - RecordNewSeenOrThrow(ref alreadySeen, AttributeKind.Retargetable); - if (attributeValue.Equals("Yes", StringComparison.OrdinalIgnoreCase)) - { - flags |= AssemblyNameFlags.Retargetable; - } - else if (attributeValue.Equals("No", StringComparison.OrdinalIgnoreCase)) - { - // nothing to do - } - else - { - ThrowInvalidAssemblyName(); - } - } - - if (attributeName.Equals("ContentType", StringComparison.OrdinalIgnoreCase)) - { - RecordNewSeenOrThrow(ref alreadySeen, AttributeKind.ContentType); - if (attributeValue.Equals("WindowsRuntime", StringComparison.OrdinalIgnoreCase)) - { - flags |= (AssemblyNameFlags)(((int)AssemblyContentType.WindowsRuntime) << 9); - } - else - { - ThrowInvalidAssemblyName(); - } - } - - // Desktop compat: If we got here, the attribute name is unknown to us. Ignore it. - token = GetNextToken(); - } - - return new AssemblyNameParts(name, version, cultureName, flags, pkt); - } - - private Version ParseVersion(string attributeValue) - { - ReadOnlySpan attributeValueSpan = attributeValue; - Span parts = stackalloc Range[5]; - parts = parts.Slice(0, attributeValueSpan.Split(parts, '.')); - if (parts.Length is < 2 or > 4) - { - ThrowInvalidAssemblyName(); - } - - Span versionNumbers = stackalloc ushort[4]; - for (int i = 0; i < versionNumbers.Length; i++) - { - if ((uint)i >= (uint)parts.Length) - { - versionNumbers[i] = ushort.MaxValue; - break; - } - - if (!ushort.TryParse(attributeValueSpan[parts[i]], NumberStyles.None, NumberFormatInfo.InvariantInfo, out versionNumbers[i])) - { - ThrowInvalidAssemblyName(); - } - } - - if (versionNumbers[0] == ushort.MaxValue || - versionNumbers[1] == ushort.MaxValue) - { - ThrowInvalidAssemblyName(); - } - - return - versionNumbers[2] == ushort.MaxValue ? new Version(versionNumbers[0], versionNumbers[1]) : - versionNumbers[3] == ushort.MaxValue ? new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2]) : - new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2], versionNumbers[3]); - } - - private static string ParseCulture(string attributeValue) - { - if (attributeValue.Equals("Neutral", StringComparison.OrdinalIgnoreCase)) - { - return ""; - } - - return attributeValue; - } - - private byte[] ParsePKT(string attributeValue, bool isToken) - { - if (attributeValue.Equals("null", StringComparison.OrdinalIgnoreCase) || attributeValue == string.Empty) - return Array.Empty(); - - if (isToken && attributeValue.Length != 8 * 2) - ThrowInvalidAssemblyName(); - - byte[] pkt = new byte[attributeValue.Length / 2]; - int srcIndex = 0; - for (int i = 0; i < pkt.Length; i++) - { - char hi = attributeValue[srcIndex++]; - char lo = attributeValue[srcIndex++]; - pkt[i] = (byte)((ParseHexNybble(hi) << 4) | ParseHexNybble(lo)); - } - return pkt; - } - - private ProcessorArchitecture ParseProcessorArchitecture(string attributeValue) - { - if (attributeValue.Equals("msil", StringComparison.OrdinalIgnoreCase)) - return ProcessorArchitecture.MSIL; - if (attributeValue.Equals("x86", StringComparison.OrdinalIgnoreCase)) - return ProcessorArchitecture.X86; - if (attributeValue.Equals("ia64", StringComparison.OrdinalIgnoreCase)) - return ProcessorArchitecture.IA64; - if (attributeValue.Equals("amd64", StringComparison.OrdinalIgnoreCase)) - return ProcessorArchitecture.Amd64; - if (attributeValue.Equals("arm", StringComparison.OrdinalIgnoreCase)) - return ProcessorArchitecture.Arm; - ThrowInvalidAssemblyName(); - return default; // unreachable - } - - private byte ParseHexNybble(char c) - { - int value = HexConverter.FromChar(c); - if (value == 0xFF) - { - ThrowInvalidAssemblyName(); - } - return (byte)value; - } - - // - // Return the next token in assembly name. If you expect the result to be Token.String, - // use GetNext(out String) instead. - // - private Token GetNextToken() - { - return GetNextToken(out _); - } - - private static bool IsWhiteSpace(char ch) - { - switch (ch) - { - case '\n': - case '\r': - case ' ': - case '\t': - return true; - default: - return false; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private char GetNextChar() - { - char ch; - if (_index < _input.Length) - { - ch = _input[_index++]; - if (ch == '\0') - { - ThrowInvalidAssemblyName(); - } - } - else - { - ch = '\0'; - } - - return ch; - } - - // - // Return the next token in assembly name. If the result is Token.String, - // sets "tokenString" to the tokenized string. - // - private Token GetNextToken(out string tokenString) - { - tokenString = string.Empty; - char c; - - while (true) - { - c = GetNextChar(); - switch (c) - { - case ',': - return Token.Comma; - case '=': - return Token.Equals; - case '\0': - return Token.End; - } - - if (!IsWhiteSpace(c)) - { - break; - } - } - - ValueStringBuilder sb = new ValueStringBuilder(stackalloc char[64]); - - char quoteChar = '\0'; - if (c == '\'' || c == '\"') - { - quoteChar = c; - c = GetNextChar(); - } - - for (; ; ) - { - if (c == 0) - { - if (quoteChar != 0) - { - // EOS and unclosed quotes is an error - ThrowInvalidAssemblyName(); - } - // Reached end of input and therefore of string - break; - } - - if (quoteChar != 0 && c == quoteChar) - break; // Terminate: Found closing quote of quoted string. - - if (quoteChar == 0 && (c == ',' || c == '=')) - { - _index--; - break; // Terminate: Found start of a new ',' or '=' token. - } - - if (quoteChar == 0 && (c == '\'' || c == '\"')) - ThrowInvalidAssemblyName(); - - if (c == '\\') - { - c = GetNextChar(); - - switch (c) - { - case '\\': - case ',': - case '=': - case '\'': - case '"': - sb.Append(c); - break; - case 't': - sb.Append('\t'); - break; - case 'r': - sb.Append('\r'); - break; - case 'n': - sb.Append('\n'); - break; - default: - ThrowInvalidAssemblyName(); - break; //unreachable - } - } - else - { - sb.Append(c); - } - - c = GetNextChar(); - } - - - if (quoteChar == 0) - { - while (sb.Length > 0 && IsWhiteSpace(sb[sb.Length - 1])) - sb.Length--; - } - - tokenString = sb.ToString(); - return Token.String; - } - - [DoesNotReturn] - private void ThrowInvalidAssemblyName() - => throw new FileLoadException(SR.InvalidAssemblyName, _input.ToString()); - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs index 459fd26e6abb38..7cb85c290c7555 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncMethodBuilderCore.cs @@ -102,6 +102,12 @@ internal static string GetAsyncStateMachineDescription(IAsyncStateMachine stateM return sb.ToString(); } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void LogTraceOperationBegin(Task t, Type stateMachineType) + { + TplEventSource.Log.TraceOperationBegin(t.Id, "Async: " + stateMachineType.Name, 0); + } + internal static Action CreateContinuationWrapper(Action continuation, Action invokeAction, Task innerTask) => new ContinuationWrapper(continuation, invokeAction, innerTask).Invoke; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs index c3064ad22114bd..5a2ccb1d635493 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs @@ -157,6 +157,8 @@ private static IAsyncStateMachineBox GetStateMachineBox( { ExecutionContext? currentContext = ExecutionContext.Capture(); + IAsyncStateMachineBox result; + // Check first for the most common case: not the first yield in an async method. // In this case, the first yield will have already "boxed" the state machine in // a strongly-typed manner into an AsyncStateMachineBox. It will already contain @@ -168,9 +170,8 @@ private static IAsyncStateMachineBox GetStateMachineBox( { stronglyTypedBox.Context = currentContext; } - return stronglyTypedBox; + result = stronglyTypedBox; } - // The least common case: we have a weakly-typed boxed. This results if the debugger // or some other use of reflection accesses a property like ObjectIdForDebugger or a // method like SetNotificationForWaitCompletion prior to the first await happening. In @@ -180,7 +181,7 @@ private static IAsyncStateMachineBox GetStateMachineBox( // result in a boxing allocation when storing the TStateMachine if it's a struct, but // this only happens in active debugging scenarios where such performance impact doesn't // matter. - if (taskField is AsyncStateMachineBox weaklyTypedBox) + else if (taskField is AsyncStateMachineBox weaklyTypedBox) { // If this is the first await, we won't yet have a state machine, so store it. if (weaklyTypedBox.StateMachine == null) @@ -192,52 +193,55 @@ private static IAsyncStateMachineBox GetStateMachineBox( // Update the context. This only happens with a debugger, so no need to spend // extra IL checking for equality before doing the assignment. weaklyTypedBox.Context = currentContext; - return weaklyTypedBox; + result = weaklyTypedBox; } - - // Alert a listening debugger that we can't make forward progress unless it slips threads. - // If we don't do this, and a method that uses "await foo;" is invoked through funceval, - // we could end up hooking up a callback to push forward the async method's state machine, - // the debugger would then abort the funceval after it takes too long, and then continuing - // execution could result in another callback being hooked up. At that point we have - // multiple callbacks registered to push the state machine, which could result in bad behavior. - Debugger.NotifyOfCrossThreadDependency(); - - // At this point, taskField should really be null, in which case we want to create the box. - // However, in a variety of debugger-related (erroneous) situations, it might be non-null, - // e.g. if the Task property is examined in a Watch window, forcing it to be lazily-initialized - // as a Task rather than as an AsyncStateMachineBox. The worst that happens in such - // cases is we lose the ability to properly step in the debugger, as the debugger uses that - // object's identity to track this specific builder/state machine. As such, we proceed to - // overwrite whatever's there anyway, even if it's non-null. + else + { + // Alert a listening debugger that we can't make forward progress unless it slips threads. + // If we don't do this, and a method that uses "await foo;" is invoked through funceval, + // we could end up hooking up a callback to push forward the async method's state machine, + // the debugger would then abort the funceval after it takes too long, and then continuing + // execution could result in another callback being hooked up. At that point we have + // multiple callbacks registered to push the state machine, which could result in bad behavior. + Debugger.NotifyOfCrossThreadDependency(); + + // At this point, taskField should really be null, in which case we want to create the box. + // However, in a variety of debugger-related (erroneous) situations, it might be non-null, + // e.g. if the Task property is examined in a Watch window, forcing it to be lazily-initialized + // as a Task rather than as an AsyncStateMachineBox. The worst that happens in such + // cases is we lose the ability to properly step in the debugger, as the debugger uses that + // object's identity to track this specific builder/state machine. As such, we proceed to + // overwrite whatever's there anyway, even if it's non-null. #if NATIVEAOT - // DebugFinalizableAsyncStateMachineBox looks like a small type, but it actually is not because - // it will have a copy of all the slots from its parent. It will add another hundred(s) bytes - // per each async method in NativeAOT binaries without adding much value. Avoid - // generating this extra code until a better solution is implemented. - var box = new AsyncStateMachineBox(); + // DebugFinalizableAsyncStateMachineBox looks like a small type, but it actually is not because + // it will have a copy of all the slots from its parent. It will add another hundred(s) bytes + // per each async method in NativeAOT binaries without adding much value. Avoid + // generating this extra code until a better solution is implemented. + var box = new AsyncStateMachineBox(); #else - AsyncStateMachineBox box = AsyncMethodBuilderCore.TrackAsyncMethodCompletion ? - CreateDebugFinalizableAsyncStateMachineBox() : - new AsyncStateMachineBox(); + AsyncStateMachineBox box = AsyncMethodBuilderCore.TrackAsyncMethodCompletion ? + CreateDebugFinalizableAsyncStateMachineBox() : + new AsyncStateMachineBox(); #endif - taskField = box; // important: this must be done before storing stateMachine into box.StateMachine! - box.StateMachine = stateMachine; - box.Context = currentContext; + taskField = box; // important: this must be done before storing stateMachine into box.StateMachine! + box.StateMachine = stateMachine; + box.Context = currentContext; - // Log the creation of the state machine box object / task for this async method. - if (TplEventSource.Log.IsEnabled()) - { - TplEventSource.Log.TraceOperationBegin(box.Id, "Async: " + stateMachine.GetType().Name, 0); - } + // Log the creation of the state machine box object / task for this async method. + if (TplEventSource.Log.IsEnabled()) + { + AsyncMethodBuilderCore.LogTraceOperationBegin(box, stateMachine.GetType()); + } - // And if async debugging is enabled, track the task. - if (Threading.Tasks.Task.s_asyncDebuggingEnabled) - { - Threading.Tasks.Task.AddToActiveTasks(box); + // And if async debugging is enabled, track the task. + if (Threading.Tasks.Task.s_asyncDebuggingEnabled) + { + Threading.Tasks.Task.AddToActiveTasks(box); + } + result = box; } - return box; + return result; } #if !NATIVEAOT diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs index 37c39bbc029a24..b314daec02a93c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs @@ -992,6 +992,14 @@ static NFloat IBinaryNumber.AllBitsSet /// public static NFloat Ceiling(NFloat x) => new NFloat(NativeType.Ceiling(x._value)); + /// + public static TInteger ConvertToInteger(NFloat value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + + /// + public static TInteger ConvertToIntegerNative(NFloat value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + /// public static NFloat Floor(NFloat x) => new NFloat(NativeType.Floor(x._value)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index fbd5ee65ca748f..43eec348f76fc5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -31,6 +31,425 @@ internal Arm64() { } public static new bool IsSupported { [Intrinsic] get { return false; } } } + /// Abs : Absolute value + + /// + /// svint8_t svabs[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// svint8_t svabs[_s8]_x(svbool_t pg, svint8_t op) + /// svint8_t svabs[_s8]_z(svbool_t pg, svint8_t op) + /// + public static unsafe Vector Abs(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svabs[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// svint16_t svabs[_s16]_x(svbool_t pg, svint16_t op) + /// svint16_t svabs[_s16]_z(svbool_t pg, svint16_t op) + /// + public static unsafe Vector Abs(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svabs[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// svint32_t svabs[_s32]_x(svbool_t pg, svint32_t op) + /// svint32_t svabs[_s32]_z(svbool_t pg, svint32_t op) + /// + public static unsafe Vector Abs(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svabs[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// svint64_t svabs[_s64]_x(svbool_t pg, svint64_t op) + /// svint64_t svabs[_s64]_z(svbool_t pg, svint64_t op) + /// + public static unsafe Vector Abs(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svabs[_f32]_m(svfloat32_t inactive, svbool_t pg, svfloat32_t op) + /// svfloat32_t svabs[_f32]_x(svbool_t pg, svfloat32_t op) + /// svfloat32_t svabs[_f32]_z(svbool_t pg, svfloat32_t op) + /// + public static unsafe Vector Abs(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svabs[_f64]_m(svfloat64_t inactive, svbool_t pg, svfloat64_t op) + /// svfloat64_t svabs[_f64]_x(svbool_t pg, svfloat64_t op) + /// svfloat64_t svabs[_f64]_z(svbool_t pg, svfloat64_t op) + /// + public static unsafe Vector Abs(Vector value) { throw new PlatformNotSupportedException(); } + + + /// Add : Add + + /// + /// svint8_t svadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svadd[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svadd[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svadd[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svadd[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svadd[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svadd[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svadd[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svadd[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svadd[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svadd[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svadd[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svadd[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svadd[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svadd[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svadd[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svadd[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svadd[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svadd[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svadd[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svadd[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svadd[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svadd[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// AddAcross : Add reduction + + /// + /// float64_t svaddv[_f64](svbool_t pg, svfloat64_t op) + /// FADDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svaddv[_s16](svbool_t pg, svint16_t op) + /// SADDV Dresult, Pg, Zop.H + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svaddv[_s32](svbool_t pg, svint32_t op) + /// SADDV Dresult, Pg, Zop.S + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svaddv[_s8](svbool_t pg, svint8_t op) + /// SADDV Dresult, Pg, Zop.B + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svaddv[_s64](svbool_t pg, svint64_t op) + /// UADDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// float32_t svaddv[_f32](svbool_t pg, svfloat32_t op) + /// FADDV Sresult, Pg, Zop.S + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svaddv[_u8](svbool_t pg, svuint8_t op) + /// UADDV Dresult, Pg, Zop.B + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svaddv[_u16](svbool_t pg, svuint16_t op) + /// UADDV Dresult, Pg, Zop.H + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svaddv[_u32](svbool_t pg, svuint32_t op) + /// UADDV Dresult, Pg, Zop.S + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svaddv[_u64](svbool_t pg, svuint64_t op) + /// UADDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + + + /// And : Bitwise AND + + /// + /// svuint8_t svand[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svand[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svand[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// AND Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svand[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svand[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svand[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// AND Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svand[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svand[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svand[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// AND Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svand[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svand[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svand[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// AND Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svand[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svand[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svand[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// AND Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svand[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svand[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svand[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// AND Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svand[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svand[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svand[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// AND Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svand[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svand[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svand[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// AND Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// AndAcross : Bitwise AND reduction to scalar + + /// + /// uint8_t svandv[_u8](svbool_t pg, svuint8_t op) + /// ANDV Bresult, Pg, Zop.B + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t svandv[_s16](svbool_t pg, svint16_t op) + /// ANDV Hresult, Pg, Zop.H + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t svandv[_s32](svbool_t pg, svint32_t op) + /// ANDV Sresult, Pg, Zop.S + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svandv[_s64](svbool_t pg, svint64_t op) + /// ANDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t svandv[_s8](svbool_t pg, svint8_t op) + /// ANDV Bresult, Pg, Zop.B + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t svandv[_u16](svbool_t pg, svuint16_t op) + /// ANDV Hresult, Pg, Zop.H + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t svandv[_u32](svbool_t pg, svuint32_t op) + /// ANDV Sresult, Pg, Zop.S + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svandv[_u64](svbool_t pg, svuint64_t op) + /// ANDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AndAcross(Vector value) { throw new PlatformNotSupportedException(); } + + + /// ConditionalSelect : Conditionally select elements + + /// + /// svint8_t svsel[_s8](svbool_t pg, svint8_t op1, svint8_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svsel[_s16](svbool_t pg, svint16_t op1, svint16_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsel[_s32](svbool_t pg, svint32_t op1, svint32_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsel[_s64](svbool_t pg, svint64_t op1, svint64_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svsel[_u8](svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsel[_u16](svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsel[_u32](svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsel[_u64](svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svsel[_f32](svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svsel[_f64](svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// Count16BitElements : Count the number of 16-bit elements in a vector + + /// + /// uint64_t svcnth_pat(enum svpattern pattern) + /// CNTH Xresult, pattern + /// + public static unsafe ulong Count16BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw new PlatformNotSupportedException(); } + + + /// Count32BitElements : Count the number of 32-bit elements in a vector + + /// + /// uint64_t svcntw_pat(enum svpattern pattern) + /// CNTW Xresult, pattern + /// + public static unsafe ulong Count32BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw new PlatformNotSupportedException(); } + + + /// Count64BitElements : Count the number of 64-bit elements in a vector + + /// + /// uint64_t svcntd_pat(enum svpattern pattern) + /// CNTD Xresult, pattern + /// + public static unsafe ulong Count64BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw new PlatformNotSupportedException(); } + + + /// Count8BitElements : Count the number of 8-bit elements in a vector + + /// + /// uint64_t svcntb_pat(enum svpattern pattern) + /// CNTB Xresult, pattern + /// + public static unsafe ulong Count8BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw new PlatformNotSupportedException(); } + + /// CreateTrueMaskByte : Set predicate elements to true /// @@ -121,79 +540,1966 @@ internal Arm64() { } public static unsafe Vector CreateTrueMaskUInt64([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw new PlatformNotSupportedException(); } + /// CreateWhileLessThanMask16Bit : While incrementing scalar is less than - /// LoadVector : Unextended load + /// + /// svbool_t svwhilelt_b16[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(int left, int right) { throw new PlatformNotSupportedException(); } /// - /// svint8_t svld1[_s8](svbool_t pg, const int8_t *base) - /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] - /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b16[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.H, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask16Bit(long left, long right) { throw new PlatformNotSupportedException(); } /// - /// svint16_t svld1[_s16](svbool_t pg, const int16_t *base) - /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] - /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.H, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, short* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask16Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } /// - /// svint32_t svld1[_s32](svbool_t pg, const int32_t *base) - /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] - /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.H, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, int* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask16Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanMask32Bit : While incrementing scalar is less than /// - /// svint64_t svld1[_s64](svbool_t pg, const int64_t *base) - /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] - /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.S, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, long* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask32Bit(int left, int right) { throw new PlatformNotSupportedException(); } /// - /// svuint8_t svld1[_u8](svbool_t pg, const uint8_t *base) - /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] - /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.S, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask32Bit(long left, long right) { throw new PlatformNotSupportedException(); } /// - /// svuint16_t svld1[_u16](svbool_t pg, const uint16_t *base) - /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] - /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.S, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask32Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } /// - /// svuint32_t svld1[_u32](svbool_t pg, const uint32_t *base) - /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] - /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.S, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask32Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanMask64Bit : While incrementing scalar is less than /// - /// svuint64_t svld1[_u64](svbool_t pg, const uint64_t *base) - /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] - /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b64[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.D, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, ulong* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask64Bit(int left, int right) { throw new PlatformNotSupportedException(); } /// - /// svfloat32_t svld1[_f32](svbool_t pg, const float32_t *base) - /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] - /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b64[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.D, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, float* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask64Bit(long left, long right) { throw new PlatformNotSupportedException(); } /// - /// svfloat64_t svld1[_f64](svbool_t pg, const float64_t *base) - /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] - /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.D, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, double* address) { throw new PlatformNotSupportedException(); } + public static unsafe Vector CreateWhileLessThanMask64Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanMask8Bit : While incrementing scalar is less than + + /// + /// svbool_t svwhilelt_b8[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b8[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilelt_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + /// + /// svbool_t svwhilelt_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask16Bit : While incrementing scalar is less than or equal to + /// + /// svbool_t svwhilele_b16[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b16[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask32Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b32[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b32[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask64Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b64[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b64[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// CreateWhileLessThanOrEqualMask8Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b8[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(int left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b8[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(long left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(uint left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svbool_t svwhilele_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(ulong left, ulong right) { throw new PlatformNotSupportedException(); } + + + /// Divide : Divide + + /// + /// svfloat32_t svdiv[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FDIV Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FDIV Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svdiv[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FDIV Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FDIV Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svdiv[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; FDIV Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Divide(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svdiv[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FDIV Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FDIV Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svdiv[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FDIV Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FDIV Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svdiv[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; FDIV Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Divide(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// LoadVector : Unextended load + + /// + /// svint8_t svld1[_s8](svbool_t pg, const int8_t *base) + /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] + /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svld1[_s16](svbool_t pg, const int16_t *base) + /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] + /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, short* address) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svld1[_s32](svbool_t pg, const int32_t *base) + /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] + /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, int* address) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svld1[_s64](svbool_t pg, const int64_t *base) + /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] + /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, long* address) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svld1[_u8](svbool_t pg, const uint8_t *base) + /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] + /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svld1[_u16](svbool_t pg, const uint16_t *base) + /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] + /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svld1[_u32](svbool_t pg, const uint32_t *base) + /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] + /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svld1[_u64](svbool_t pg, const uint64_t *base) + /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] + /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, ulong* address) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svld1[_f32](svbool_t pg, const float32_t *base) + /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] + /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, float* address) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svld1[_f64](svbool_t pg, const float64_t *base) + /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] + /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, double* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorByteZeroExtendToInt16 : Load 8-bit data and zero-extend + + /// + /// svint16_t svld1ub_s16(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToInt16(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorByteZeroExtendToInt32 : Load 8-bit data and zero-extend + + /// + /// svint32_t svld1ub_s32(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToInt32(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorByteZeroExtendToInt64 : Load 8-bit data and zero-extend + + /// + /// svint64_t svld1ub_s64(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToInt64(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorByteZeroExtendToUInt16 : Load 8-bit data and zero-extend + + /// + /// svuint16_t svld1ub_u16(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToUInt16(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorByteZeroExtendToUInt32 : Load 8-bit data and zero-extend + + /// + /// svuint32_t svld1ub_u32(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToUInt32(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorByteZeroExtendToUInt64 : Load 8-bit data and zero-extend + + /// + /// svuint64_t svld1ub_u64(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToUInt64(Vector mask, byte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorInt16SignExtendToInt32 : Load 16-bit data and sign-extend + + /// + /// svint32_t svld1sh_s32(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToInt32(Vector mask, short* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorInt16SignExtendToInt64 : Load 16-bit data and sign-extend + + /// + /// svint64_t svld1sh_s64(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToInt64(Vector mask, short* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorInt16SignExtendToUInt32 : Load 16-bit data and sign-extend + + /// + /// svuint32_t svld1sh_u32(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToUInt32(Vector mask, short* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorInt16SignExtendToUInt64 : Load 16-bit data and sign-extend + + /// + /// svuint64_t svld1sh_u64(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToUInt64(Vector mask, short* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorInt32SignExtendToInt64 : Load 32-bit data and sign-extend + + /// + /// svint64_t svld1sw_s64(svbool_t pg, const int32_t *base) + /// LD1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt32SignExtendToInt64(Vector mask, int* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorInt32SignExtendToUInt64 : Load 32-bit data and sign-extend + + /// + /// svuint64_t svld1sw_u64(svbool_t pg, const int32_t *base) + /// LD1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt32SignExtendToUInt64(Vector mask, int* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorSByteSignExtendToInt16 : Load 8-bit data and sign-extend + + /// + /// svint16_t svld1sb_s16(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToInt16(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorSByteSignExtendToInt32 : Load 8-bit data and sign-extend + + /// + /// svint32_t svld1sb_s32(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToInt32(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorSByteSignExtendToInt64 : Load 8-bit data and sign-extend + + /// + /// svint64_t svld1sb_s64(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToInt64(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorSByteSignExtendToUInt16 : Load 8-bit data and sign-extend + + /// + /// svuint16_t svld1sb_u16(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToUInt16(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorSByteSignExtendToUInt32 : Load 8-bit data and sign-extend + + /// + /// svuint32_t svld1sb_u32(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToUInt32(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorSByteSignExtendToUInt64 : Load 8-bit data and sign-extend + + /// + /// svuint64_t svld1sb_u64(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToUInt64(Vector mask, sbyte* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorUInt16ZeroExtendToInt32 : Load 16-bit data and zero-extend + + /// + /// svint32_t svld1uh_s32(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToInt32(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorUInt16ZeroExtendToInt64 : Load 16-bit data and zero-extend + + /// + /// svint64_t svld1uh_s64(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToInt64(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorUInt16ZeroExtendToUInt32 : Load 16-bit data and zero-extend + + /// + /// svuint32_t svld1uh_u32(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToUInt32(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorUInt16ZeroExtendToUInt64 : Load 16-bit data and zero-extend + + /// + /// svuint64_t svld1uh_u64(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToUInt64(Vector mask, ushort* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorUInt32ZeroExtendToInt64 : Load 32-bit data and zero-extend + + /// + /// svint64_t svld1uw_s64(svbool_t pg, const uint32_t *base) + /// LD1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt32ZeroExtendToInt64(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } + + + /// LoadVectorUInt32ZeroExtendToUInt64 : Load 32-bit data and zero-extend + + /// + /// svuint64_t svld1uw_u64(svbool_t pg, const uint32_t *base) + /// LD1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt32ZeroExtendToUInt64(Vector mask, uint* address) { throw new PlatformNotSupportedException(); } + + /// Max : Maximum + + /// + /// svuint8_t svmax[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmax[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmax[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMAX Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UMAX Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svmax[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmax[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmax[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAX Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMAX Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svmax[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmax[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmax[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMAX Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SMAX Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmax[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmax[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmax[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMAX Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SMAX Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmax[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmax[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmax[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMAX Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SMAX Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svmax[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmax[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmax[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMAX Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SMAX Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svmax[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmax[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmax[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAX Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMAX Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmax[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmax[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmax[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMAX Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UMAX Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmax[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmax[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmax[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMAX Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UMAX Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmax[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmax[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmax[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMAX Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UMAX Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Max(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// MaxAcross : Maximum reduction to scalar + + /// + /// uint8_t svmaxv[_u8](svbool_t pg, svuint8_t op) + /// UMAXV Bresult, Pg, Zop.B + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// float64_t svmaxv[_f64](svbool_t pg, svfloat64_t op) + /// FMAXV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t svmaxv[_s16](svbool_t pg, svint16_t op) + /// SMAXV Hresult, Pg, Zop.H + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t svmaxv[_s32](svbool_t pg, svint32_t op) + /// SMAXV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svmaxv[_s64](svbool_t pg, svint64_t op) + /// SMAXV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t svmaxv[_s8](svbool_t pg, svint8_t op) + /// SMAXV Bresult, Pg, Zop.B + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// float32_t svmaxv[_f32](svbool_t pg, svfloat32_t op) + /// FMAXV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t svmaxv[_u16](svbool_t pg, svuint16_t op) + /// UMAXV Hresult, Pg, Zop.H + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t svmaxv[_u32](svbool_t pg, svuint32_t op) + /// UMAXV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svmaxv[_u64](svbool_t pg, svuint64_t op) + /// UMAXV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxAcross(Vector value) { throw new PlatformNotSupportedException(); } + + + /// MaxNumber : Maximum number + + /// + /// svfloat64_t svmaxnm[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxnm[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxnm[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAXNM Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMAXNM Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector MaxNumber(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svmaxnm[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxnm[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxnm[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAXNM Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMAXNM Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector MaxNumber(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// MaxNumberAcross : Maximum number reduction to scalar + + /// + /// float64_t svmaxnmv[_f64](svbool_t pg, svfloat64_t op) + /// FMAXNMV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxNumberAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// float32_t svmaxnmv[_f32](svbool_t pg, svfloat32_t op) + /// FMAXNMV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxNumberAcross(Vector value) { throw new PlatformNotSupportedException(); } + + + /// Min : Minimum + + /// + /// svuint8_t svmin[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmin[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmin[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMIN Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UMIN Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svmin[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmin[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmin[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMIN Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMIN Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svmin[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmin[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmin[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMIN Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SMIN Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmin[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmin[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmin[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMIN Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SMIN Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmin[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmin[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmin[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMIN Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SMIN Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svmin[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmin[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmin[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMIN Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SMIN Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svmin[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmin[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmin[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMIN Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMIN Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmin[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmin[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmin[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMIN Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UMIN Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmin[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmin[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmin[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMIN Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UMIN Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmin[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmin[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmin[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMIN Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UMIN Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Min(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// MinAcross : Minimum reduction to scalar + + /// + /// uint8_t svminv[_u8](svbool_t pg, svuint8_t op) + /// UMINV Bresult, Pg, Zop.B + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// float64_t svminv[_f64](svbool_t pg, svfloat64_t op) + /// FMINV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t svminv[_s16](svbool_t pg, svint16_t op) + /// SMINV Hresult, Pg, Zop.H + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t svminv[_s32](svbool_t pg, svint32_t op) + /// SMINV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svminv[_s64](svbool_t pg, svint64_t op) + /// SMINV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t svminv[_s8](svbool_t pg, svint8_t op) + /// SMINV Bresult, Pg, Zop.B + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// float32_t svminv[_f32](svbool_t pg, svfloat32_t op) + /// FMINV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t svminv[_u16](svbool_t pg, svuint16_t op) + /// UMINV Hresult, Pg, Zop.H + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t svminv[_u32](svbool_t pg, svuint32_t op) + /// UMINV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svminv[_u64](svbool_t pg, svuint64_t op) + /// UMINV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinAcross(Vector value) { throw new PlatformNotSupportedException(); } + + + /// MinNumber : Minimum number + + /// + /// svfloat64_t svminnm[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminnm[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminnm[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMINNM Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMINNM Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector MinNumber(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svminnm[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminnm[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminnm[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMINNM Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMINNM Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector MinNumber(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// MinNumberAcross : Minimum number reduction to scalar + + /// + /// float64_t svminnmv[_f64](svbool_t pg, svfloat64_t op) + /// FMINNMV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinNumberAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// float32_t svminnmv[_f32](svbool_t pg, svfloat32_t op) + /// FMINNMV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinNumberAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// Multiply : Multiply + + /// + /// svint8_t svmul[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svint8_t svmul[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MUL Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svint8_t svmul[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// MOVPRFX Zresult.B, Pg/Z, Zop2.B; MUL Zresult.B, Pg/M, Zresult.B, Zop1.B + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svmul[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svint16_t svmul[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MUL Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svint16_t svmul[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// MOVPRFX Zresult.H, Pg/Z, Zop2.H; MUL Zresult.H, Pg/M, Zresult.H, Zop1.H + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmul[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svint32_t svmul[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MUL Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svint32_t svmul[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// MOVPRFX Zresult.S, Pg/Z, Zop2.S; MUL Zresult.S, Pg/M, Zresult.S, Zop1.S + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmul[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svint64_t svmul[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MUL Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svint64_t svmul[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// MOVPRFX Zresult.D, Pg/Z, Zop2.D; MUL Zresult.D, Pg/M, Zresult.D, Zop1.D + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svmul[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svuint8_t svmul[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MUL Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svuint8_t svmul[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// MOVPRFX Zresult.B, Pg/Z, Zop2.B; MUL Zresult.B, Pg/M, Zresult.B, Zop1.B + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmul[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svuint16_t svmul[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MUL Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svuint16_t svmul[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// MOVPRFX Zresult.H, Pg/Z, Zop2.H; MUL Zresult.H, Pg/M, Zresult.H, Zop1.H + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmul[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svuint32_t svmul[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MUL Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svuint32_t svmul[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// MOVPRFX Zresult.S, Pg/Z, Zop2.S; MUL Zresult.S, Pg/M, Zresult.S, Zop1.S + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmul[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svuint64_t svmul[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MUL Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svuint64_t svmul[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// MOVPRFX Zresult.D, Pg/Z, Zop2.D; MUL Zresult.D, Pg/M, Zresult.D, Zop1.D + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svmul[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FMUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svmul[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMUL Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// FMUL Zresult.S, Zop1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FMUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svmul[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; FMUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// MOVPRFX Zresult.S, Pg/Z, Zop2.S; FMUL Zresult.S, Pg/M, Zresult.S, Zop1.S + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svmul[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FMUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svmul[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMUL Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// FMUL Zresult.D, Zop1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FMUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svmul[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; FMUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// MOVPRFX Zresult.D, Pg/Z, Zop2.D; FMUL Zresult.D, Pg/M, Zresult.D, Zop1.D + /// + public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// Or : Bitwise inclusive OR + + /// + /// svuint8_t svorr[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svorr[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svorr[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// ORR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svorr[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svorr[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svorr[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// ORR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svorr[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svorr[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svorr[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// ORR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svorr[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svorr[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svorr[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// ORR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svorr[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svorr[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svorr[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// ORR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svorr[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svorr[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svorr[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// ORR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svorr[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svorr[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svorr[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// ORR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svorr[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svorr[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svorr[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// ORR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// OrAcross : Bitwise inclusive OR reduction to scalar + + /// + /// uint8_t svorv[_u8](svbool_t pg, svuint8_t op) + /// ORV Bresult, Pg, Zop.B + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t svorv[_s16](svbool_t pg, svint16_t op) + /// ORV Hresult, Pg, Zop.H + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t svorv[_s32](svbool_t pg, svint32_t op) + /// ORV Sresult, Pg, Zop.S + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t svorv[_s64](svbool_t pg, svint64_t op) + /// ORV Dresult, Pg, Zop.D + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t svorv[_s8](svbool_t pg, svint8_t op) + /// ORV Bresult, Pg, Zop.B + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t svorv[_u16](svbool_t pg, svuint16_t op) + /// ORV Hresult, Pg, Zop.H + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t svorv[_u32](svbool_t pg, svuint32_t op) + /// ORV Sresult, Pg, Zop.S + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t svorv[_u64](svbool_t pg, svuint64_t op) + /// ORV Dresult, Pg, Zop.D + /// + public static unsafe Vector OrAcross(Vector value) { throw new PlatformNotSupportedException(); } + + + /// SignExtend16 : Sign-extend the low 16 bits + + /// + /// svint32_t svexth[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_x(svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svexth[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_x(svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + + /// SignExtend32 : Sign-extend the low 32 bits + + /// + /// svint64_t svextw[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_x(svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend32(Vector value) { throw new PlatformNotSupportedException(); } + + + /// SignExtend8 : Sign-extend the low 8 bits + + /// + /// svint16_t svextb[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_x(svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Ztied.H + /// MOVPRFX Zresult, Zop; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_z(svbool_t pg, svint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; SXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector SignExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svextb[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_x(svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svextb[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_x(svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// Subtract : Subtract + + /// + /// svint8_t svsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svint8_t svsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SUB Zresult.B, Zop1.B, Zop2.B + /// svint8_t svsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svint16_t svsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SUB Zresult.H, Zop1.H, Zop2.H + /// svint16_t svsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svint32_t svsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SUB Zresult.S, Zop1.S, Zop2.S + /// svint32_t svsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svint64_t svsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SUB Zresult.D, Zop1.D, Zop2.D + /// svint64_t svsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svuint8_t svsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SUB Zresult.B, Zop1.B, Zop2.B + /// svuint8_t svsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svuint16_t svsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SUB Zresult.H, Zop1.H, Zop2.H + /// svuint16_t svsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svuint32_t svsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SUB Zresult.S, Zop1.S, Zop2.S + /// svuint32_t svsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svuint64_t svsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SUB Zresult.D, Zop1.D, Zop2.D + /// svuint64_t svsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svsub[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FSUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svsub[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FSUB Zresult.S, Zop1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FSUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svsub[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; FSUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svsub[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FSUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svsub[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FSUB Zresult.D, Zop1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FSUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svsub[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; FSUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Subtract(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// SignExtendWideningLower : Unpack and extend low half + + /// + /// svint16_t svunpklo[_s16](svint8_t op) + /// SUNPKLO Zresult.H, Zop.B + /// + public static unsafe Vector SignExtendWideningLower(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svunpklo[_s32](svint16_t op) + /// SUNPKLO Zresult.S, Zop.H + /// + public static unsafe Vector SignExtendWideningLower(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svunpklo[_s64](svint32_t op) + /// SUNPKLO Zresult.D, Zop.S + /// + public static unsafe Vector SignExtendWideningLower(Vector value) { throw new PlatformNotSupportedException(); } + + + /// SignExtendWideningUpper : Unpack and extend high half + + /// + /// svint16_t svunpkhi[_s16](svint8_t op) + /// SUNPKHI Zresult.H, Zop.B + /// + public static unsafe Vector SignExtendWideningUpper(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svunpkhi[_s32](svint16_t op) + /// SUNPKHI Zresult.S, Zop.H + /// + public static unsafe Vector SignExtendWideningUpper(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svunpkhi[_s64](svint32_t op) + /// SUNPKHI Zresult.D, Zop.S + /// + public static unsafe Vector SignExtendWideningUpper(Vector value) { throw new PlatformNotSupportedException(); } + + + /// UnzipEven : Concatenate even elements from two inputs + + /// + /// svint8_t svuzp1[_s8](svint8_t op1, svint8_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svuzp1[_s16](svint16_t op1, svint16_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svuzp1[_s32](svint32_t op1, svint32_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svuzp1[_s64](svint64_t op1, svint64_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svuzp1[_u8](svuint8_t op1, svuint8_t op2) + /// svbool_t svuzp1_b8(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svuzp1[_u16](svuint16_t op1, svuint16_t op2) + /// svbool_t svuzp1_b16(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svuzp1[_u32](svuint32_t op1, svuint32_t op2) + /// svbool_t svuzp1_b32(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svuzp1[_u64](svuint64_t op1, svuint64_t op2) + /// svbool_t svuzp1_b64(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svuzp1[_f32](svfloat32_t op1, svfloat32_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svuzp1[_f64](svfloat64_t op1, svfloat64_t op2) + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// UnzipOdd : Concatenate odd elements from two inputs + + /// + /// svuint8_t svuzp2[_u8](svuint8_t op1, svuint8_t op2) + /// svbool_t svuzp2_b8(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svuzp2[_f64](svfloat64_t op1, svfloat64_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svuzp2[_s16](svint16_t op1, svint16_t op2) + /// UZP2 Zresult.H, Zop1.H, Zop2.H + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svuzp2[_s32](svint32_t op1, svint32_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svuzp2[_s64](svint64_t op1, svint64_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svuzp2[_s8](svint8_t op1, svint8_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svuzp2[_f32](svfloat32_t op1, svfloat32_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svuzp2[_u16](svuint16_t op1, svuint16_t op2) + /// svbool_t svuzp2_b16(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svuzp2[_u32](svuint32_t op1, svuint32_t op2) + /// svbool_t svuzp2_b32(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svuzp2[_u64](svuint64_t op1, svuint64_t op2) + /// svbool_t svuzp2_b64(svbool_t op1, svbool_t op2) + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// Xor : Bitwise exclusive OR + + /// + /// svuint8_t sveor[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t sveor[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t sveor[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// EOR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t sveor[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t sveor[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t sveor[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// EOR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t sveor[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t sveor[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t sveor[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// EOR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t sveor[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t sveor[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t sveor[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// EOR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t sveor[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t sveor[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t sveor[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// EOR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t sveor[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t sveor[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t sveor[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// EOR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t sveor[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t sveor[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t sveor[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// EOR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t sveor[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t sveor[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t sveor[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// EOR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// XorAcross : Bitwise exclusive OR reduction to scalar + + /// + /// uint8_t sveorv[_u8](svbool_t pg, svuint8_t op) + /// EORV Bresult, Pg, Zop.B + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t sveorv[_s16](svbool_t pg, svint16_t op) + /// EORV Hresult, Pg, Zop.H + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t sveorv[_s32](svbool_t pg, svint32_t op) + /// EORV Sresult, Pg, Zop.S + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int64_t sveorv[_s64](svbool_t pg, svint64_t op) + /// EORV Dresult, Pg, Zop.D + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t sveorv[_s8](svbool_t pg, svint8_t op) + /// EORV Bresult, Pg, Zop.B + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t sveorv[_u16](svbool_t pg, svuint16_t op) + /// EORV Hresult, Pg, Zop.H + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t sveorv[_u32](svbool_t pg, svuint32_t op) + /// EORV Sresult, Pg, Zop.S + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64_t sveorv[_u64](svbool_t pg, svuint64_t op) + /// EORV Dresult, Pg, Zop.D + /// + public static unsafe Vector XorAcross(Vector value) { throw new PlatformNotSupportedException(); } + + + /// ZeroExtend16 : Zero-extend the low 16 bits + + /// + /// svuint32_t svexth[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.S, Pg/M, Zop.S + /// svuint32_t svexth[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #65535 + /// svuint32_t svexth[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svexth[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.D, Pg/M, Zop.D + /// svuint64_t svexth[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #65535 + /// svuint64_t svexth[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + + /// ZeroExtend32 : Zero-extend the low 32 bits + + /// + /// svuint64_t svextw[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTW Zresult.D, Pg/M, Zop.D + /// svuint64_t svextw[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #4294967295 + /// svuint64_t svextw[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend32(Vector value) { throw new PlatformNotSupportedException(); } + + /// ZeroExtend8 : Zero-extend the low 8 bits + + /// + /// svuint16_t svextb[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.H, Pg/M, Zop.H + /// svuint16_t svextb[_u16]_x(svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Ztied.H + /// AND Ztied.H, Ztied.H, #255 + /// svuint16_t svextb[_u16]_z(svbool_t pg, svuint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; UXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector ZeroExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svextb[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.S, Pg/M, Zop.S + /// svuint32_t svextb[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #255 + /// svuint32_t svextb[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svextb[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.D, Pg/M, Zop.D + /// svuint64_t svextb[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #255 + /// svuint64_t svextb[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// ZeroExtendWideningLower : Unpack and extend low half + + /// + /// svuint16_t svunpklo[_u16](svuint8_t op) + /// UUNPKLO Zresult.H, Zop.B + /// + public static unsafe Vector ZeroExtendWideningLower(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svunpklo[_u32](svuint16_t op) + /// UUNPKLO Zresult.S, Zop.H + /// + public static unsafe Vector ZeroExtendWideningLower(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svunpklo[_u64](svuint32_t op) + /// UUNPKLO Zresult.D, Zop.S + /// + public static unsafe Vector ZeroExtendWideningLower(Vector value) { throw new PlatformNotSupportedException(); } + + + /// ZeroExtendWideningUpper : Unpack and extend high half + + /// + /// svuint16_t svunpkhi[_u16](svuint8_t op) + /// UUNPKHI Zresult.H, Zop.B + /// + public static unsafe Vector ZeroExtendWideningUpper(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svunpkhi[_u32](svuint16_t op) + /// UUNPKHI Zresult.S, Zop.H + /// + public static unsafe Vector ZeroExtendWideningUpper(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svunpkhi[_u64](svuint32_t op) + /// UUNPKHI Zresult.D, Zop.S + /// + public static unsafe Vector ZeroExtendWideningUpper(Vector value) { throw new PlatformNotSupportedException(); } + + /// ZipHigh : Interleave elements from high halves of two inputs + + /// + /// svuint8_t svzip2[_u8](svuint8_t op1, svuint8_t op2) + /// ZIP2 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svzip2[_f64](svfloat64_t op1, svfloat64_t op2) + /// ZIP2 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svzip2[_s16](svint16_t op1, svint16_t op2) + /// ZIP2 Zresult.H, Zop1.H, Zop2.H + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svzip2[_s32](svint32_t op1, svint32_t op2) + /// ZIP2 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svzip2[_s64](svint64_t op1, svint64_t op2) + /// ZIP2 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svzip2[_s8](svint8_t op1, svint8_t op2) + /// ZIP2 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svzip2[_f32](svfloat32_t op1, svfloat32_t op2) + /// ZIP2 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svzip2[_u16](svuint16_t op1, svuint16_t op2) + /// ZIP2 Zresult.H, Zop1.H, Zop2.H + /// svbool_t svzip2_b16(svbool_t op1, svbool_t op2) + /// ZIP2 Presult.H, Pop1.H, Pop2.H + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svzip2[_u32](svuint32_t op1, svuint32_t op2) + /// ZIP2 Zresult.S, Zop1.S, Zop2.S + /// svbool_t svzip2_b32(svbool_t op1, svbool_t op2) + /// ZIP2 Presult.S, Pop1.S, Pop2.S + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svzip2[_u64](svuint64_t op1, svuint64_t op2) + /// ZIP2 Zresult.D, Zop1.D, Zop2.D + /// svbool_t svzip2_b64(svbool_t op1, svbool_t op2) + /// ZIP2 Presult.D, Pop1.D, Pop2.D + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + /// ZipLow : Interleave elements from low halves of two inputs + + /// + /// svuint8_t svzip1[_u8](svuint8_t op1, svuint8_t op2) + /// ZIP1 Zresult.B, Zop1.B, Zop2.B + /// svbool_t svzip1_b8(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.B, Pop1.B, Pop2.B + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svzip1[_f64](svfloat64_t op1, svfloat64_t op2) + /// ZIP1 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svzip1[_s16](svint16_t op1, svint16_t op2) + /// ZIP1 Zresult.H, Zop1.H, Zop2.H + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svzip1[_s32](svint32_t op1, svint32_t op2) + /// ZIP1 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svzip1[_s64](svint64_t op1, svint64_t op2) + /// ZIP1 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svzip1[_s8](svint8_t op1, svint8_t op2) + /// ZIP1 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svzip1[_f32](svfloat32_t op1, svfloat32_t op2) + /// ZIP1 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svzip1[_u16](svuint16_t op1, svuint16_t op2) + /// ZIP1 Zresult.H, Zop1.H, Zop2.H + /// svbool_t svzip1_b16(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.H, Pop1.H, Pop2.H + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svzip1[_u32](svuint32_t op1, svuint32_t op2) + /// ZIP1 Zresult.S, Zop1.S, Zop2.S + /// svbool_t svzip1_b32(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.S, Pop1.S, Pop2.S + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svzip1[_u64](svuint64_t op1, svuint64_t op2) + /// ZIP1 Zresult.D, Zop1.D, Zop2.D + /// svbool_t svzip1_b64(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.D, Pop1.D, Pop2.D + /// + public static unsafe Vector ZipLow(Vector left, Vector right) { throw new PlatformNotSupportedException(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 6ba2a2c67bc8a7..6814d2f8317aa7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -29,6 +29,484 @@ internal Arm64() { } } + /// Abs : Absolute value + + /// + /// svint8_t svabs[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// ABS Ztied.B, Pg/M, Zop.B + /// MOVPRFX Zresult, Zinactive; ABS Zresult.B, Pg/M, Zop.B + /// svint8_t svabs[_s8]_x(svbool_t pg, svint8_t op) + /// ABS Ztied.B, Pg/M, Ztied.B + /// MOVPRFX Zresult, Zop; ABS Zresult.B, Pg/M, Zop.B + /// svint8_t svabs[_s8]_z(svbool_t pg, svint8_t op) + /// MOVPRFX Zresult.B, Pg/Z, Zop.B; ABS Zresult.B, Pg/M, Zop.B + /// + public static unsafe Vector Abs(Vector value) => Abs(value); + + /// + /// svint16_t svabs[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// ABS Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; ABS Zresult.H, Pg/M, Zop.H + /// svint16_t svabs[_s16]_x(svbool_t pg, svint16_t op) + /// ABS Ztied.H, Pg/M, Ztied.H + /// MOVPRFX Zresult, Zop; ABS Zresult.H, Pg/M, Zop.H + /// svint16_t svabs[_s16]_z(svbool_t pg, svint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; ABS Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector Abs(Vector value) => Abs(value); + + /// + /// svint32_t svabs[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// ABS Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; ABS Zresult.S, Pg/M, Zop.S + /// svint32_t svabs[_s32]_x(svbool_t pg, svint32_t op) + /// ABS Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; ABS Zresult.S, Pg/M, Zop.S + /// svint32_t svabs[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; ABS Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector Abs(Vector value) => Abs(value); + + /// + /// svint64_t svabs[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// ABS Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; ABS Zresult.D, Pg/M, Zop.D + /// svint64_t svabs[_s64]_x(svbool_t pg, svint64_t op) + /// ABS Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; ABS Zresult.D, Pg/M, Zop.D + /// svint64_t svabs[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; ABS Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector Abs(Vector value) => Abs(value); + + /// + /// svfloat32_t svabs[_f32]_m(svfloat32_t inactive, svbool_t pg, svfloat32_t op) + /// FABS Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; FABS Zresult.S, Pg/M, Zop.S + /// svfloat32_t svabs[_f32]_x(svbool_t pg, svfloat32_t op) + /// FABS Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; FABS Zresult.S, Pg/M, Zop.S + /// svfloat32_t svabs[_f32]_z(svbool_t pg, svfloat32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; FABS Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector Abs(Vector value) => Abs(value); + + /// + /// svfloat64_t svabs[_f64]_m(svfloat64_t inactive, svbool_t pg, svfloat64_t op) + /// FABS Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; FABS Zresult.D, Pg/M, Zop.D + /// svfloat64_t svabs[_f64]_x(svbool_t pg, svfloat64_t op) + /// FABS Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; FABS Zresult.D, Pg/M, Zop.D + /// svfloat64_t svabs[_f64]_z(svbool_t pg, svfloat64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; FABS Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector Abs(Vector value) => Abs(value); + + + /// Add : Add + + /// + /// svint8_t svadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svadd[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svadd[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svint16_t svadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svadd[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svadd[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svint32_t svadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svadd[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svadd[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svint64_t svadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svadd[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svadd[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svuint8_t svadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svadd[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svadd[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svuint16_t svadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svadd[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svadd[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svuint32_t svadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svadd[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svadd[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svuint64_t svadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svadd[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svadd[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svfloat32_t svadd[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svadd[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svadd[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + /// + /// svfloat64_t svadd[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svadd[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svadd[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// + public static unsafe Vector Add(Vector left, Vector right) => Add(left, right); + + + /// AddAcross : Add reduction + + /// + /// float64_t svaddv[_f64](svbool_t pg, svfloat64_t op) + /// FADDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// int64_t svaddv[_s16](svbool_t pg, svint16_t op) + /// SADDV Dresult, Pg, Zop.H + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// int64_t svaddv[_s32](svbool_t pg, svint32_t op) + /// SADDV Dresult, Pg, Zop.S + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// int64_t svaddv[_s8](svbool_t pg, svint8_t op) + /// SADDV Dresult, Pg, Zop.B + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// int64_t svaddv[_s64](svbool_t pg, svint64_t op) + /// UADDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// float32_t svaddv[_f32](svbool_t pg, svfloat32_t op) + /// FADDV Sresult, Pg, Zop.S + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// uint64_t svaddv[_u8](svbool_t pg, svuint8_t op) + /// UADDV Dresult, Pg, Zop.B + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// uint64_t svaddv[_u16](svbool_t pg, svuint16_t op) + /// UADDV Dresult, Pg, Zop.H + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// uint64_t svaddv[_u32](svbool_t pg, svuint32_t op) + /// UADDV Dresult, Pg, Zop.S + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + /// + /// uint64_t svaddv[_u64](svbool_t pg, svuint64_t op) + /// UADDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + + + /// And : Bitwise AND + + /// + /// svuint8_t svand[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svand[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svand[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// AND Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + /// + /// svint16_t svand[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svand[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svand[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// AND Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + /// + /// svint32_t svand[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svand[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svand[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// AND Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + /// + /// svint64_t svand[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svand[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svand[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// AND Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + /// + /// svint8_t svand[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svand[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svand[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// AND Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + /// + /// svuint16_t svand[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svand[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svand[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// AND Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + /// + /// svuint32_t svand[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svand[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svand[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// AND Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + /// + /// svuint64_t svand[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svand[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svand[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// AND Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// AND Zresult.D, Zop1.D, Zop2.D + /// svbool_t svand[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// AND Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector And(Vector left, Vector right) => And(left, right); + + + /// AndAcross : Bitwise AND reduction to scalar + + /// + /// uint8_t svandv[_u8](svbool_t pg, svuint8_t op) + /// ANDV Bresult, Pg, Zop.B + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + /// + /// int16_t svandv[_s16](svbool_t pg, svint16_t op) + /// ANDV Hresult, Pg, Zop.H + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + /// + /// int32_t svandv[_s32](svbool_t pg, svint32_t op) + /// ANDV Sresult, Pg, Zop.S + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + /// + /// int64_t svandv[_s64](svbool_t pg, svint64_t op) + /// ANDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + /// + /// int8_t svandv[_s8](svbool_t pg, svint8_t op) + /// ANDV Bresult, Pg, Zop.B + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + /// + /// uint16_t svandv[_u16](svbool_t pg, svuint16_t op) + /// ANDV Hresult, Pg, Zop.H + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + /// + /// uint32_t svandv[_u32](svbool_t pg, svuint32_t op) + /// ANDV Sresult, Pg, Zop.S + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + /// + /// uint64_t svandv[_u64](svbool_t pg, svuint64_t op) + /// ANDV Dresult, Pg, Zop.D + /// + public static unsafe Vector AndAcross(Vector value) => AndAcross(value); + + + /// ConditionalSelect : Conditionally select elements + + /// + /// svint8_t svsel[_s8](svbool_t pg, svint8_t op1, svint8_t op2) + /// SEL Zresult.B, Pg, Zop1.B, Zop2.B + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svint16_t svsel[_s16](svbool_t pg, svint16_t op1, svint16_t op2) + /// SEL Zresult.H, Pg, Zop1.H, Zop2.H + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svint32_t svsel[_s32](svbool_t pg, svint32_t op1, svint32_t op2) + /// SEL Zresult.S, Pg, Zop1.S, Zop2.S + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svint64_t svsel[_s64](svbool_t pg, svint64_t op1, svint64_t op2) + /// SEL Zresult.D, Pg, Zop1.D, Zop2.D + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svuint8_t svsel[_u8](svbool_t pg, svuint8_t op1, svuint8_t op2) + /// SEL Zresult.B, Pg, Zop1.B, Zop2.B + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svuint16_t svsel[_u16](svbool_t pg, svuint16_t op1, svuint16_t op2) + /// SEL Zresult.H, Pg, Zop1.H, Zop2.H + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svuint32_t svsel[_u32](svbool_t pg, svuint32_t op1, svuint32_t op2) + /// SEL Zresult.S, Pg, Zop1.S, Zop2.S + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svuint64_t svsel[_u64](svbool_t pg, svuint64_t op1, svuint64_t op2) + /// SEL Zresult.D, Pg, Zop1.D, Zop2.D + /// svbool_t svsel[_b](svbool_t pg, svbool_t op1, svbool_t op2) + /// SEL Presult.B, Pg, Pop1.B, Pop2.B + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svfloat32_t svsel[_f32](svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// SEL Zresult.S, Pg, Zop1.S, Zop2.S + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + /// + /// svfloat64_t svsel[_f64](svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// SEL Zresult.D, Pg, Zop1.D, Zop2.D + /// + /// + public static unsafe Vector ConditionalSelect(Vector mask, Vector left, Vector right) => ConditionalSelect(mask, left, right); + + + /// Count16BitElements : Count the number of 16-bit elements in a vector + + /// + /// uint64_t svcnth_pat(enum svpattern pattern) + /// CNTH Xresult, pattern + /// + public static unsafe ulong Count16BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) => Count16BitElements(pattern); + + + /// Count32BitElements : Count the number of 32-bit elements in a vector + + /// + /// uint64_t svcntw_pat(enum svpattern pattern) + /// CNTW Xresult, pattern + /// + public static unsafe ulong Count32BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) => Count32BitElements(pattern); + + + /// Count64BitElements : Count the number of 64-bit elements in a vector + + /// + /// uint64_t svcntd_pat(enum svpattern pattern) + /// CNTD Xresult, pattern + /// + public static unsafe ulong Count64BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) => Count64BitElements(pattern); + + + /// Count8BitElements : Count the number of 8-bit elements in a vector + + /// + /// uint64_t svcntb_pat(enum svpattern pattern) + /// CNTB Xresult, pattern + /// + public static unsafe ulong Count8BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) => Count8BitElements(pattern); + + /// CreateTrueMaskByte : Set predicate elements to true /// @@ -119,78 +597,1994 @@ internal Arm64() { } public static unsafe Vector CreateTrueMaskUInt64([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) => CreateTrueMaskUInt64(pattern); + /// CreateWhileLessThanMask16Bit : While incrementing scalar is less than - /// LoadVector : Unextended load + /// + /// svbool_t svwhilelt_b16[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask16Bit(int left, int right) => CreateWhileLessThanMask16Bit(left, right); /// - /// svint8_t svld1[_s8](svbool_t pg, const int8_t *base) - /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] - /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b16[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.H, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, sbyte* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask16Bit(long left, long right) => CreateWhileLessThanMask16Bit(left, right); /// - /// svint16_t svld1[_s16](svbool_t pg, const int16_t *base) - /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] - /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.H, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, short* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask16Bit(uint left, uint right) => CreateWhileLessThanMask16Bit(left, right); /// - /// svint32_t svld1[_s32](svbool_t pg, const int32_t *base) - /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] - /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.H, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, int* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask16Bit(ulong left, ulong right) => CreateWhileLessThanMask16Bit(left, right); + + + /// CreateWhileLessThanMask32Bit : While incrementing scalar is less than /// - /// svint64_t svld1[_s64](svbool_t pg, const int64_t *base) - /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] - /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.S, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, long* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask32Bit(int left, int right) => CreateWhileLessThanMask32Bit(left, right); /// - /// svuint8_t svld1[_u8](svbool_t pg, const uint8_t *base) - /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] - /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.S, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, byte* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask32Bit(long left, long right) => CreateWhileLessThanMask32Bit(left, right); /// - /// svuint16_t svld1[_u16](svbool_t pg, const uint16_t *base) - /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] - /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.S, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, ushort* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask32Bit(uint left, uint right) => CreateWhileLessThanMask32Bit(left, right); /// - /// svuint32_t svld1[_u32](svbool_t pg, const uint32_t *base) - /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] - /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.S, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, uint* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask32Bit(ulong left, ulong right) => CreateWhileLessThanMask32Bit(left, right); + + + /// CreateWhileLessThanMask64Bit : While incrementing scalar is less than /// - /// svuint64_t svld1[_u64](svbool_t pg, const uint64_t *base) - /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] - /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b64[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.D, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, ulong* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask64Bit(int left, int right) => CreateWhileLessThanMask64Bit(left, right); /// - /// svfloat32_t svld1[_f32](svbool_t pg, const float32_t *base) - /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] - /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b64[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.D, Xop1, Xop2 /// - public static unsafe Vector LoadVector(Vector mask, float* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask64Bit(long left, long right) => CreateWhileLessThanMask64Bit(left, right); /// - /// svfloat64_t svld1[_f64](svbool_t pg, const float64_t *base) - /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] - /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// svbool_t svwhilelt_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.D, Wop1, Wop2 /// - public static unsafe Vector LoadVector(Vector mask, double* address) => LoadVector(mask, address); + public static unsafe Vector CreateWhileLessThanMask64Bit(uint left, uint right) => CreateWhileLessThanMask64Bit(left, right); + + /// + /// svbool_t svwhilelt_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask64Bit(ulong left, ulong right) => CreateWhileLessThanMask64Bit(left, right); + + + /// CreateWhileLessThanMask8Bit : While incrementing scalar is less than + /// + /// svbool_t svwhilelt_b8[_s32](int32_t op1, int32_t op2) + /// WHILELT Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(int left, int right) => CreateWhileLessThanMask8Bit(left, right); + + /// + /// svbool_t svwhilelt_b8[_s64](int64_t op1, int64_t op2) + /// WHILELT Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(long left, long right) => CreateWhileLessThanMask8Bit(left, right); + + /// + /// svbool_t svwhilelt_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELO Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(uint left, uint right) => CreateWhileLessThanMask8Bit(left, right); + + /// + /// svbool_t svwhilelt_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELO Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanMask8Bit(ulong left, ulong right) => CreateWhileLessThanMask8Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask16Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b16[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(int left, int right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + /// + /// svbool_t svwhilele_b16[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(long left, long right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + /// + /// svbool_t svwhilele_b16[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.H, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + /// + /// svbool_t svwhilele_b16[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.H, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask16Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask16Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask32Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b32[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(int left, int right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + /// + /// svbool_t svwhilele_b32[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(long left, long right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + /// + /// svbool_t svwhilele_b32[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.S, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + /// + /// svbool_t svwhilele_b32[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.S, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask32Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask32Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask64Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b64[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(int left, int right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + /// + /// svbool_t svwhilele_b64[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(long left, long right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + /// + /// svbool_t svwhilele_b64[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.D, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + /// + /// svbool_t svwhilele_b64[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.D, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask64Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask64Bit(left, right); + + + /// CreateWhileLessThanOrEqualMask8Bit : While incrementing scalar is less than or equal to + + /// + /// svbool_t svwhilele_b8[_s32](int32_t op1, int32_t op2) + /// WHILELE Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(int left, int right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + /// + /// svbool_t svwhilele_b8[_s64](int64_t op1, int64_t op2) + /// WHILELE Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(long left, long right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + /// + /// svbool_t svwhilele_b8[_u32](uint32_t op1, uint32_t op2) + /// WHILELS Presult.B, Wop1, Wop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(uint left, uint right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + /// + /// svbool_t svwhilele_b8[_u64](uint64_t op1, uint64_t op2) + /// WHILELS Presult.B, Xop1, Xop2 + /// + public static unsafe Vector CreateWhileLessThanOrEqualMask8Bit(ulong left, ulong right) => CreateWhileLessThanOrEqualMask8Bit(left, right); + + + /// Divide : Divide + + /// + /// svfloat32_t svdiv[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FDIV Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FDIV Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svdiv[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FDIV Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FDIV Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svdiv[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; FDIV Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Divide(Vector left, Vector right) => Divide(left, right); + + /// + /// svfloat64_t svdiv[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FDIV Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FDIV Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svdiv[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FDIV Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FDIV Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svdiv[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; FDIV Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Divide(Vector left, Vector right) => Divide(left, right); + + /// LoadVector : Unextended load + + /// + /// svint8_t svld1[_s8](svbool_t pg, const int8_t *base) + /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] + /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, sbyte* address) => LoadVector(mask, address); + + /// + /// svint16_t svld1[_s16](svbool_t pg, const int16_t *base) + /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] + /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, short* address) => LoadVector(mask, address); + + /// + /// svint32_t svld1[_s32](svbool_t pg, const int32_t *base) + /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] + /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, int* address) => LoadVector(mask, address); + + /// + /// svint64_t svld1[_s64](svbool_t pg, const int64_t *base) + /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] + /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, long* address) => LoadVector(mask, address); + + /// + /// svuint8_t svld1[_u8](svbool_t pg, const uint8_t *base) + /// LD1B Zresult.B, Pg/Z, [Xarray, Xindex] + /// LD1B Zresult.B, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, byte* address) => LoadVector(mask, address); + + /// + /// svuint16_t svld1[_u16](svbool_t pg, const uint16_t *base) + /// LD1H Zresult.H, Pg/Z, [Xarray, Xindex, LSL #1] + /// LD1H Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, ushort* address) => LoadVector(mask, address); + + /// + /// svuint32_t svld1[_u32](svbool_t pg, const uint32_t *base) + /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] + /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, uint* address) => LoadVector(mask, address); + + /// + /// svuint64_t svld1[_u64](svbool_t pg, const uint64_t *base) + /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] + /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, ulong* address) => LoadVector(mask, address); + + /// + /// svfloat32_t svld1[_f32](svbool_t pg, const float32_t *base) + /// LD1W Zresult.S, Pg/Z, [Xarray, Xindex, LSL #2] + /// LD1W Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, float* address) => LoadVector(mask, address); + + /// + /// svfloat64_t svld1[_f64](svbool_t pg, const float64_t *base) + /// LD1D Zresult.D, Pg/Z, [Xarray, Xindex, LSL #3] + /// LD1D Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVector(Vector mask, double* address) => LoadVector(mask, address); + + + /// LoadVectorByteZeroExtendToInt16 : Load 8-bit data and zero-extend + + /// + /// svint16_t svld1ub_s16(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToInt16(Vector mask, byte* address) => LoadVectorByteZeroExtendToInt16(mask, address); + + + /// LoadVectorByteZeroExtendToInt32 : Load 8-bit data and zero-extend + + /// + /// svint32_t svld1ub_s32(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToInt32(Vector mask, byte* address) => LoadVectorByteZeroExtendToInt32(mask, address); + + + /// LoadVectorByteZeroExtendToInt64 : Load 8-bit data and zero-extend + + /// + /// svint64_t svld1ub_s64(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToInt64(Vector mask, byte* address) => LoadVectorByteZeroExtendToInt64(mask, address); + + + /// LoadVectorByteZeroExtendToUInt16 : Load 8-bit data and zero-extend + + /// + /// svuint16_t svld1ub_u16(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToUInt16(Vector mask, byte* address) => LoadVectorByteZeroExtendToUInt16(mask, address); + + + /// LoadVectorByteZeroExtendToUInt32 : Load 8-bit data and zero-extend + + /// + /// svuint32_t svld1ub_u32(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToUInt32(Vector mask, byte* address) => LoadVectorByteZeroExtendToUInt32(mask, address); + + + /// LoadVectorByteZeroExtendToUInt64 : Load 8-bit data and zero-extend + + /// + /// svuint64_t svld1ub_u64(svbool_t pg, const uint8_t *base) + /// LD1B Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorByteZeroExtendToUInt64(Vector mask, byte* address) => LoadVectorByteZeroExtendToUInt64(mask, address); + + + /// LoadVectorInt16SignExtendToInt32 : Load 16-bit data and sign-extend + + /// + /// svint32_t svld1sh_s32(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToInt32(Vector mask, short* address) => LoadVectorInt16SignExtendToInt32(mask, address); + + + /// LoadVectorInt16SignExtendToInt64 : Load 16-bit data and sign-extend + + /// + /// svint64_t svld1sh_s64(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToInt64(Vector mask, short* address) => LoadVectorInt16SignExtendToInt64(mask, address); + + + /// LoadVectorInt16SignExtendToUInt32 : Load 16-bit data and sign-extend + + /// + /// svuint32_t svld1sh_u32(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToUInt32(Vector mask, short* address) => LoadVectorInt16SignExtendToUInt32(mask, address); + + + /// LoadVectorInt16SignExtendToUInt64 : Load 16-bit data and sign-extend + + /// + /// svuint64_t svld1sh_u64(svbool_t pg, const int16_t *base) + /// LD1SH Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt16SignExtendToUInt64(Vector mask, short* address) => LoadVectorInt16SignExtendToUInt64(mask, address); + + + /// LoadVectorInt32SignExtendToInt64 : Load 32-bit data and sign-extend + + /// + /// svint64_t svld1sw_s64(svbool_t pg, const int32_t *base) + /// LD1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt32SignExtendToInt64(Vector mask, int* address) => LoadVectorInt32SignExtendToInt64(mask, address); + + + /// LoadVectorInt32SignExtendToUInt64 : Load 32-bit data and sign-extend + + /// + /// svuint64_t svld1sw_u64(svbool_t pg, const int32_t *base) + /// LD1SW Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorInt32SignExtendToUInt64(Vector mask, int* address) => LoadVectorInt32SignExtendToUInt64(mask, address); + + + /// LoadVectorSByteSignExtendToInt16 : Load 8-bit data and sign-extend + + /// + /// svint16_t svld1sb_s16(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToInt16(Vector mask, sbyte* address) => LoadVectorSByteSignExtendToInt16(mask, address); + + + /// LoadVectorSByteSignExtendToInt32 : Load 8-bit data and sign-extend + + /// + /// svint32_t svld1sb_s32(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToInt32(Vector mask, sbyte* address) => LoadVectorSByteSignExtendToInt32(mask, address); + + + /// LoadVectorSByteSignExtendToInt64 : Load 8-bit data and sign-extend + + /// + /// svint64_t svld1sb_s64(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToInt64(Vector mask, sbyte* address) => LoadVectorSByteSignExtendToInt64(mask, address); + + + /// LoadVectorSByteSignExtendToUInt16 : Load 8-bit data and sign-extend + + /// + /// svuint16_t svld1sb_u16(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.H, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToUInt16(Vector mask, sbyte* address) => LoadVectorSByteSignExtendToUInt16(mask, address); + + + /// LoadVectorSByteSignExtendToUInt32 : Load 8-bit data and sign-extend + + /// + /// svuint32_t svld1sb_u32(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToUInt32(Vector mask, sbyte* address) => LoadVectorSByteSignExtendToUInt32(mask, address); + + + /// LoadVectorSByteSignExtendToUInt64 : Load 8-bit data and sign-extend + + /// + /// svuint64_t svld1sb_u64(svbool_t pg, const int8_t *base) + /// LD1SB Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorSByteSignExtendToUInt64(Vector mask, sbyte* address) => LoadVectorSByteSignExtendToUInt64(mask, address); + + + /// LoadVectorUInt16ZeroExtendToInt32 : Load 16-bit data and zero-extend + + /// + /// svint32_t svld1uh_s32(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToInt32(Vector mask, ushort* address) => LoadVectorUInt16ZeroExtendToInt32(mask, address); + + + /// LoadVectorUInt16ZeroExtendToInt64 : Load 16-bit data and zero-extend + + /// + /// svint64_t svld1uh_s64(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToInt64(Vector mask, ushort* address) => LoadVectorUInt16ZeroExtendToInt64(mask, address); + + + /// LoadVectorUInt16ZeroExtendToUInt32 : Load 16-bit data and zero-extend + + /// + /// svuint32_t svld1uh_u32(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.S, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToUInt32(Vector mask, ushort* address) => LoadVectorUInt16ZeroExtendToUInt32(mask, address); + + + /// LoadVectorUInt16ZeroExtendToUInt64 : Load 16-bit data and zero-extend + + /// + /// svuint64_t svld1uh_u64(svbool_t pg, const uint16_t *base) + /// LD1H Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt16ZeroExtendToUInt64(Vector mask, ushort* address) => LoadVectorUInt16ZeroExtendToUInt64(mask, address); + + + /// LoadVectorUInt32ZeroExtendToInt64 : Load 32-bit data and zero-extend + + /// + /// svint64_t svld1uw_s64(svbool_t pg, const uint32_t *base) + /// LD1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt32ZeroExtendToInt64(Vector mask, uint* address) => LoadVectorUInt32ZeroExtendToInt64(mask, address); + + + /// LoadVectorUInt32ZeroExtendToUInt64 : Load 32-bit data and zero-extend + + /// + /// svuint64_t svld1uw_u64(svbool_t pg, const uint32_t *base) + /// LD1W Zresult.D, Pg/Z, [Xbase, #0, MUL VL] + /// + public static unsafe Vector LoadVectorUInt32ZeroExtendToUInt64(Vector mask, uint* address) => LoadVectorUInt32ZeroExtendToUInt64(mask, address); + + /// Max : Maximum + + /// + /// svuint8_t svmax[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmax[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmax[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMAX Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UMAX Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svfloat64_t svmax[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmax[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmax[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAX Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMAX Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svint16_t svmax[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmax[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmax[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMAX Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SMAX Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svint32_t svmax[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmax[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmax[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMAX Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SMAX Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svint64_t svmax[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmax[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmax[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMAX Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SMAX Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svint8_t svmax[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmax[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmax[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMAX Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SMAX Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svfloat32_t svmax[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmax[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmax[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAX Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMAX Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svuint16_t svmax[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmax[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmax[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMAX Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UMAX Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svuint32_t svmax[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmax[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmax[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMAX Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UMAX Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + /// + /// svuint64_t svmax[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmax[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmax[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMAX Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UMAX Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Max(Vector left, Vector right) => Max(left, right); + + + /// MaxAcross : Maximum reduction to scalar + + /// + /// uint8_t svmaxv[_u8](svbool_t pg, svuint8_t op) + /// UMAXV Bresult, Pg, Zop.B + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// float64_t svmaxv[_f64](svbool_t pg, svfloat64_t op) + /// FMAXV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// int16_t svmaxv[_s16](svbool_t pg, svint16_t op) + /// SMAXV Hresult, Pg, Zop.H + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// int32_t svmaxv[_s32](svbool_t pg, svint32_t op) + /// SMAXV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// int64_t svmaxv[_s64](svbool_t pg, svint64_t op) + /// SMAXV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// int8_t svmaxv[_s8](svbool_t pg, svint8_t op) + /// SMAXV Bresult, Pg, Zop.B + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// float32_t svmaxv[_f32](svbool_t pg, svfloat32_t op) + /// FMAXV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// uint16_t svmaxv[_u16](svbool_t pg, svuint16_t op) + /// UMAXV Hresult, Pg, Zop.H + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// uint32_t svmaxv[_u32](svbool_t pg, svuint32_t op) + /// UMAXV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + /// + /// uint64_t svmaxv[_u64](svbool_t pg, svuint64_t op) + /// UMAXV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxAcross(Vector value) => MaxAcross(value); + + + /// MaxNumber : Maximum number + + /// + /// svfloat64_t svmaxnm[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxnm[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmaxnm[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMAXNM Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMAXNM Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector MaxNumber(Vector left, Vector right) => MaxNumber(left, right); + + /// + /// svfloat32_t svmaxnm[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxnm[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmaxnm[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMAXNM Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMAXNM Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector MaxNumber(Vector left, Vector right) => MaxNumber(left, right); + + + /// MaxNumberAcross : Maximum number reduction to scalar + + /// + /// float64_t svmaxnmv[_f64](svbool_t pg, svfloat64_t op) + /// FMAXNMV Dresult, Pg, Zop.D + /// + public static unsafe Vector MaxNumberAcross(Vector value) => MaxNumberAcross(value); + + /// + /// float32_t svmaxnmv[_f32](svbool_t pg, svfloat32_t op) + /// FMAXNMV Sresult, Pg, Zop.S + /// + public static unsafe Vector MaxNumberAcross(Vector value) => MaxNumberAcross(value); + + + /// Min : Minimum + + /// + /// svuint8_t svmin[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmin[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svmin[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UMIN Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UMIN Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svfloat64_t svmin[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmin[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svmin[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMIN Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMIN Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svint16_t svmin[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmin[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svmin[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SMIN Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SMIN Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svint32_t svmin[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmin[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svmin[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SMIN Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SMIN Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svint64_t svmin[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmin[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svmin[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SMIN Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SMIN Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svint8_t svmin[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmin[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svmin[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SMIN Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SMIN Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svfloat32_t svmin[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmin[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svmin[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMIN Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMIN Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svuint16_t svmin[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmin[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svmin[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UMIN Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UMIN Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svuint32_t svmin[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmin[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svmin[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UMIN Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UMIN Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + /// + /// svuint64_t svmin[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmin[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svmin[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UMIN Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UMIN Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector Min(Vector left, Vector right) => Min(left, right); + + + /// MinAcross : Minimum reduction to scalar + + /// + /// uint8_t svminv[_u8](svbool_t pg, svuint8_t op) + /// UMINV Bresult, Pg, Zop.B + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// float64_t svminv[_f64](svbool_t pg, svfloat64_t op) + /// FMINV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// int16_t svminv[_s16](svbool_t pg, svint16_t op) + /// SMINV Hresult, Pg, Zop.H + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// int32_t svminv[_s32](svbool_t pg, svint32_t op) + /// SMINV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// int64_t svminv[_s64](svbool_t pg, svint64_t op) + /// SMINV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// int8_t svminv[_s8](svbool_t pg, svint8_t op) + /// SMINV Bresult, Pg, Zop.B + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// float32_t svminv[_f32](svbool_t pg, svfloat32_t op) + /// FMINV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// uint16_t svminv[_u16](svbool_t pg, svuint16_t op) + /// UMINV Hresult, Pg, Zop.H + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// uint32_t svminv[_u32](svbool_t pg, svuint32_t op) + /// UMINV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + /// + /// uint64_t svminv[_u64](svbool_t pg, svuint64_t op) + /// UMINV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinAcross(Vector value) => MinAcross(value); + + + /// MinNumber : Minimum number + + /// + /// svfloat64_t svminnm[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminnm[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// svfloat64_t svminnm[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMINNM Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMINNM Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static unsafe Vector MinNumber(Vector left, Vector right) => MinNumber(left, right); + + /// + /// svfloat32_t svminnm[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminnm[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// svfloat32_t svminnm[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMINNM Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMINNM Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static unsafe Vector MinNumber(Vector left, Vector right) => MinNumber(left, right); + + + /// MinNumberAcross : Minimum number reduction to scalar + + /// + /// float64_t svminnmv[_f64](svbool_t pg, svfloat64_t op) + /// FMINNMV Dresult, Pg, Zop.D + /// + public static unsafe Vector MinNumberAcross(Vector value) => MinNumberAcross(value); + + /// + /// float32_t svminnmv[_f32](svbool_t pg, svfloat32_t op) + /// FMINNMV Sresult, Pg, Zop.S + /// + public static unsafe Vector MinNumberAcross(Vector value) => MinNumberAcross(value); + + + /// + /// svint8_t svmul[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svint8_t svmul[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MUL Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svint8_t svmul[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// MOVPRFX Zresult.B, Pg/Z, Zop2.B; MUL Zresult.B, Pg/M, Zresult.B, Zop1.B + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svint16_t svmul[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svint16_t svmul[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MUL Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svint16_t svmul[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// MOVPRFX Zresult.H, Pg/Z, Zop2.H; MUL Zresult.H, Pg/M, Zresult.H, Zop1.H + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svint32_t svmul[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svint32_t svmul[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MUL Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svint32_t svmul[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// MOVPRFX Zresult.S, Pg/Z, Zop2.S; MUL Zresult.S, Pg/M, Zresult.S, Zop1.S + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svint64_t svmul[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svint64_t svmul[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MUL Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svint64_t svmul[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// MOVPRFX Zresult.D, Pg/Z, Zop2.D; MUL Zresult.D, Pg/M, Zresult.D, Zop1.D + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svuint8_t svmul[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svuint8_t svmul[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MUL Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MUL Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// MOVPRFX Zresult, Zop1; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svuint8_t svmul[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; MUL Zresult.B, Pg/M, Zresult.B, Zop2.B + /// MOVPRFX Zresult.B, Pg/Z, Zop2.B; MUL Zresult.B, Pg/M, Zresult.B, Zop1.B + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svuint16_t svmul[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svuint16_t svmul[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MUL Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MUL Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// MOVPRFX Zresult, Zop1; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svuint16_t svmul[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; MUL Zresult.H, Pg/M, Zresult.H, Zop2.H + /// MOVPRFX Zresult.H, Pg/Z, Zop2.H; MUL Zresult.H, Pg/M, Zresult.H, Zop1.H + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svuint32_t svmul[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svuint32_t svmul[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MUL Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// MOVPRFX Zresult, Zop1; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svuint32_t svmul[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; MUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// MOVPRFX Zresult.S, Pg/Z, Zop2.S; MUL Zresult.S, Pg/M, Zresult.S, Zop1.S + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svuint64_t svmul[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svuint64_t svmul[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MUL Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// MOVPRFX Zresult, Zop1; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svuint64_t svmul[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; MUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// MOVPRFX Zresult.D, Pg/Z, Zop2.D; MUL Zresult.D, Pg/M, Zresult.D, Zop1.D + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svfloat32_t svmul[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FMUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svmul[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FMUL Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FMUL Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// FMUL Zresult.S, Zop1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FMUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svmul[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; FMUL Zresult.S, Pg/M, Zresult.S, Zop2.S + /// MOVPRFX Zresult.S, Pg/Z, Zop2.S; FMUL Zresult.S, Pg/M, Zresult.S, Zop1.S + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + /// + /// svfloat64_t svmul[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FMUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svmul[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FMUL Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FMUL Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// FMUL Zresult.D, Zop1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FMUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svmul[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; FMUL Zresult.D, Pg/M, Zresult.D, Zop2.D + /// MOVPRFX Zresult.D, Pg/Z, Zop2.D; FMUL Zresult.D, Pg/M, Zresult.D, Zop1.D + /// + public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + + + /// Or : Bitwise inclusive OR + + /// + /// svuint8_t svorr[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svorr[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svorr[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// ORR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + /// + /// svint16_t svorr[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svorr[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svorr[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// ORR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + /// + /// svint32_t svorr[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svorr[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svorr[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// ORR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + /// + /// svint64_t svorr[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svorr[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svorr[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// ORR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + /// + /// svint8_t svorr[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svorr[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svorr[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// ORR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + /// + /// svuint16_t svorr[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svorr[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svorr[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// ORR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + /// + /// svuint32_t svorr[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svorr[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svorr[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// ORR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + /// + /// svuint64_t svorr[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svorr[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svorr[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// ORR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// ORR Zresult.D, Zop1.D, Zop2.D + /// svbool_t svorr[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// ORR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Or(Vector left, Vector right) => Or(left, right); + + + /// OrAcross : Bitwise inclusive OR reduction to scalar + + /// + /// uint8_t svorv[_u8](svbool_t pg, svuint8_t op) + /// ORV Bresult, Pg, Zop.B + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + /// + /// int16_t svorv[_s16](svbool_t pg, svint16_t op) + /// ORV Hresult, Pg, Zop.H + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + /// + /// int32_t svorv[_s32](svbool_t pg, svint32_t op) + /// ORV Sresult, Pg, Zop.S + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + /// + /// int64_t svorv[_s64](svbool_t pg, svint64_t op) + /// ORV Dresult, Pg, Zop.D + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + /// + /// int8_t svorv[_s8](svbool_t pg, svint8_t op) + /// ORV Bresult, Pg, Zop.B + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + /// + /// uint16_t svorv[_u16](svbool_t pg, svuint16_t op) + /// ORV Hresult, Pg, Zop.H + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + /// + /// uint32_t svorv[_u32](svbool_t pg, svuint32_t op) + /// ORV Sresult, Pg, Zop.S + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + /// + /// uint64_t svorv[_u64](svbool_t pg, svuint64_t op) + /// ORV Dresult, Pg, Zop.D + /// + public static unsafe Vector OrAcross(Vector value) => OrAcross(value); + + + /// SignExtend16 : Sign-extend the low 16 bits + + /// + /// svint32_t svexth[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_x(svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend16(Vector value) => SignExtend16(value); + + /// + /// svint64_t svexth[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_x(svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend16(Vector value) => SignExtend16(value); + + /// SignExtend32 : Sign-extend the low 32 bits + + /// + /// svint64_t svextw[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_x(svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend32(Vector value) => SignExtend32(value); + + + /// SignExtend8 : Sign-extend the low 8 bits + + /// + /// svint16_t svextb[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_x(svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Ztied.H + /// MOVPRFX Zresult, Zop; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_z(svbool_t pg, svint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; SXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector SignExtend8(Vector value) => SignExtend8(value); + + /// + /// svint32_t svextb[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_x(svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend8(Vector value) => SignExtend8(value); + + /// + /// svint64_t svextb[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_x(svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend8(Vector value) => SignExtend8(value); + + + /// SignExtendWideningLower : Unpack and extend low half + + /// + /// svint16_t svunpklo[_s16](svint8_t op) + /// SUNPKLO Zresult.H, Zop.B + /// + public static unsafe Vector SignExtendWideningLower(Vector value) => SignExtendWideningLower(value); + + /// + /// svint32_t svunpklo[_s32](svint16_t op) + /// SUNPKLO Zresult.S, Zop.H + /// + public static unsafe Vector SignExtendWideningLower(Vector value) => SignExtendWideningLower(value); + + /// + /// svint64_t svunpklo[_s64](svint32_t op) + /// SUNPKLO Zresult.D, Zop.S + /// + public static unsafe Vector SignExtendWideningLower(Vector value) => SignExtendWideningLower(value); + + + /// SignExtendWideningUpper : Unpack and extend high half + + /// + /// svint16_t svunpkhi[_s16](svint8_t op) + /// SUNPKHI Zresult.H, Zop.B + /// + public static unsafe Vector SignExtendWideningUpper(Vector value) => SignExtendWideningUpper(value); + + /// + /// svint32_t svunpkhi[_s32](svint16_t op) + /// SUNPKHI Zresult.S, Zop.H + /// + public static unsafe Vector SignExtendWideningUpper(Vector value) => SignExtendWideningUpper(value); + + /// + /// svint64_t svunpkhi[_s64](svint32_t op) + /// SUNPKHI Zresult.D, Zop.S + /// + public static unsafe Vector SignExtendWideningUpper(Vector value) => SignExtendWideningUpper(value); + + /// Subtract : Subtract + + /// + /// svint8_t svsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svint8_t svsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SUB Zresult.B, Zop1.B, Zop2.B + /// svint8_t svsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svint16_t svsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svint16_t svsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SUB Zresult.H, Zop1.H, Zop2.H + /// svint16_t svsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svint32_t svsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svint32_t svsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SUB Zresult.S, Zop1.S, Zop2.S + /// svint32_t svsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svint64_t svsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svint64_t svsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SUB Zresult.D, Zop1.D, Zop2.D + /// svint64_t svsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svuint8_t svsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// MOVPRFX Zresult, Zop1; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// svuint8_t svsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// SUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SUB Zresult.B, Zop1.B, Zop2.B + /// svuint8_t svsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// MOVPRFX Zresult.B, Pg/Z, Zop1.B; SUB Zresult.B, Pg/M, Zresult.B, Zop2.B + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svuint16_t svsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// MOVPRFX Zresult, Zop1; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// svuint16_t svsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// SUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SUB Zresult.H, Zop1.H, Zop2.H + /// svuint16_t svsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// MOVPRFX Zresult.H, Pg/Z, Zop1.H; SUB Zresult.H, Pg/M, Zresult.H, Zop2.H + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svuint32_t svsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svuint32_t svsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// SUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SUB Zresult.S, Zop1.S, Zop2.S + /// svuint32_t svsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; SUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svuint64_t svsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svuint64_t svsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// SUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SUB Zresult.D, Zop1.D, Zop2.D + /// svuint64_t svsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; SUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svfloat32_t svsub[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FSUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svsub[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// FSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// FSUB Zresult.S, Zop1.S, Zop2.S + /// MOVPRFX Zresult, Zop1; FSUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// svfloat32_t svsub[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2) + /// MOVPRFX Zresult.S, Pg/Z, Zop1.S; FSUB Zresult.S, Pg/M, Zresult.S, Zop2.S + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// + /// svfloat64_t svsub[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FSUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svsub[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// FSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// FSUB Zresult.D, Zop1.D, Zop2.D + /// MOVPRFX Zresult, Zop1; FSUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// svfloat64_t svsub[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2) + /// MOVPRFX Zresult.D, Pg/Z, Zop1.D; FSUB Zresult.D, Pg/M, Zresult.D, Zop2.D + /// + public static unsafe Vector Subtract(Vector left, Vector right) => Subtract(left, right); + + /// UnzipEven : Concatenate even elements from two inputs + + /// + /// svuint8_t svuzp1[_u8](svuint8_t op1, svuint8_t op2) + /// UZP1 Zresult.B, Zop1.B, Zop2.B + /// svbool_t svuzp1_b8(svbool_t op1, svbool_t op2) + /// UZP1 Presult.B, Pop1.B, Pop2.B + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svfloat64_t svuzp1[_f64](svfloat64_t op1, svfloat64_t op2) + /// UZP1 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svint16_t svuzp1[_s16](svint16_t op1, svint16_t op2) + /// UZP1 Zresult.H, Zop1.H, Zop2.H + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svint32_t svuzp1[_s32](svint32_t op1, svint32_t op2) + /// UZP1 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svint64_t svuzp1[_s64](svint64_t op1, svint64_t op2) + /// UZP1 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svint8_t svuzp1[_s8](svint8_t op1, svint8_t op2) + /// UZP1 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svfloat32_t svuzp1[_f32](svfloat32_t op1, svfloat32_t op2) + /// UZP1 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svuint16_t svuzp1[_u16](svuint16_t op1, svuint16_t op2) + /// UZP1 Zresult.H, Zop1.H, Zop2.H + /// svbool_t svuzp1_b16(svbool_t op1, svbool_t op2) + /// UZP1 Presult.H, Pop1.H, Pop2.H + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svuint32_t svuzp1[_u32](svuint32_t op1, svuint32_t op2) + /// UZP1 Zresult.S, Zop1.S, Zop2.S + /// svbool_t svuzp1_b32(svbool_t op1, svbool_t op2) + /// UZP1 Presult.S, Pop1.S, Pop2.S + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + /// + /// svuint64_t svuzp1[_u64](svuint64_t op1, svuint64_t op2) + /// UZP1 Zresult.D, Zop1.D, Zop2.D + /// svbool_t svuzp1_b64(svbool_t op1, svbool_t op2) + /// UZP1 Presult.D, Pop1.D, Pop2.D + /// + public static unsafe Vector UnzipEven(Vector left, Vector right) => UnzipEven(left, right); + + + /// UnzipOdd : Concatenate odd elements from two inputs + + /// + /// svuint8_t svuzp2[_u8](svuint8_t op1, svuint8_t op2) + /// UZP2 Zresult.B, Zop1.B, Zop2.B + /// svbool_t svuzp2_b8(svbool_t op1, svbool_t op2) + /// UZP2 Presult.B, Pop1.B, Pop2.B + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svfloat64_t svuzp2[_f64](svfloat64_t op1, svfloat64_t op2) + /// UZP2 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svint16_t svuzp2[_s16](svint16_t op1, svint16_t op2) + /// UZP2 Zresult.H, Zop1.H, Zop2.H + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svint32_t svuzp2[_s32](svint32_t op1, svint32_t op2) + /// UZP2 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svint64_t svuzp2[_s64](svint64_t op1, svint64_t op2) + /// UZP2 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svint8_t svuzp2[_s8](svint8_t op1, svint8_t op2) + /// UZP2 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svfloat32_t svuzp2[_f32](svfloat32_t op1, svfloat32_t op2) + /// UZP2 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svuint16_t svuzp2[_u16](svuint16_t op1, svuint16_t op2) + /// UZP2 Zresult.H, Zop1.H, Zop2.H + /// svbool_t svuzp2_b16(svbool_t op1, svbool_t op2) + /// UZP2 Presult.H, Pop1.H, Pop2.H + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svuint32_t svuzp2[_u32](svuint32_t op1, svuint32_t op2) + /// UZP2 Zresult.S, Zop1.S, Zop2.S + /// svbool_t svuzp2_b32(svbool_t op1, svbool_t op2) + /// UZP2 Presult.S, Pop1.S, Pop2.S + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// + /// svuint64_t svuzp2[_u64](svuint64_t op1, svuint64_t op2) + /// UZP2 Zresult.D, Zop1.D, Zop2.D + /// svbool_t svuzp2_b64(svbool_t op1, svbool_t op2) + /// UZP2 Presult.D, Pop1.D, Pop2.D + /// + public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + + /// Xor : Bitwise exclusive OR + + /// + /// svuint8_t sveor[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t sveor[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t sveor[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// EOR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + /// + /// svint16_t sveor[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t sveor[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t sveor[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// EOR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + /// + /// svint32_t sveor[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t sveor[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t sveor[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// EOR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + /// + /// svint64_t sveor[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t sveor[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t sveor[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// EOR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + /// + /// svint8_t sveor[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t sveor[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t sveor[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// EOR Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + /// + /// svuint16_t sveor[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t sveor[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t sveor[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// EOR Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + /// + /// svuint32_t sveor[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t sveor[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t sveor[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// EOR Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + /// + /// svuint64_t sveor[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t sveor[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t sveor[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// EOR Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// EOR Zresult.D, Zop1.D, Zop2.D + /// svbool_t sveor[_b]_z(svbool_t pg, svbool_t op1, svbool_t op2) + /// EOR Presult.B, Pg/Z, Pop1.B, Pop2.B + /// + public static unsafe Vector Xor(Vector left, Vector right) => Xor(left, right); + + + /// XorAcross : Bitwise exclusive OR reduction to scalar + + /// + /// uint8_t sveorv[_u8](svbool_t pg, svuint8_t op) + /// EORV Bresult, Pg, Zop.B + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + /// + /// int16_t sveorv[_s16](svbool_t pg, svint16_t op) + /// EORV Hresult, Pg, Zop.H + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + /// + /// int32_t sveorv[_s32](svbool_t pg, svint32_t op) + /// EORV Sresult, Pg, Zop.S + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + /// + /// int64_t sveorv[_s64](svbool_t pg, svint64_t op) + /// EORV Dresult, Pg, Zop.D + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + /// + /// int8_t sveorv[_s8](svbool_t pg, svint8_t op) + /// EORV Bresult, Pg, Zop.B + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + /// + /// uint16_t sveorv[_u16](svbool_t pg, svuint16_t op) + /// EORV Hresult, Pg, Zop.H + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + /// + /// uint32_t sveorv[_u32](svbool_t pg, svuint32_t op) + /// EORV Sresult, Pg, Zop.S + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + /// + /// uint64_t sveorv[_u64](svbool_t pg, svuint64_t op) + /// EORV Dresult, Pg, Zop.D + /// + public static unsafe Vector XorAcross(Vector value) => XorAcross(value); + + + /// ZeroExtend16 : Zero-extend the low 16 bits + + /// + /// svuint32_t svexth[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.S, Pg/M, Zop.S + /// svuint32_t svexth[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #65535 + /// svuint32_t svexth[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend16(Vector value) => ZeroExtend16(value); + + /// + /// svuint64_t svexth[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.D, Pg/M, Zop.D + /// svuint64_t svexth[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #65535 + /// svuint64_t svexth[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend16(Vector value) => ZeroExtend16(value); + + + /// ZeroExtend32 : Zero-extend the low 32 bits + + /// + /// svuint64_t svextw[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTW Zresult.D, Pg/M, Zop.D + /// svuint64_t svextw[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #4294967295 + /// svuint64_t svextw[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend32(Vector value) => ZeroExtend32(value); + + + /// ZeroExtend8 : Zero-extend the low 8 bits + + /// + /// svuint16_t svextb[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.H, Pg/M, Zop.H + /// svuint16_t svextb[_u16]_x(svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Ztied.H + /// AND Ztied.H, Ztied.H, #255 + /// svuint16_t svextb[_u16]_z(svbool_t pg, svuint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; UXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector ZeroExtend8(Vector value) => ZeroExtend8(value); + + /// + /// svuint32_t svextb[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.S, Pg/M, Zop.S + /// svuint32_t svextb[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #255 + /// svuint32_t svextb[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend8(Vector value) => ZeroExtend8(value); + + /// + /// svuint64_t svextb[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.D, Pg/M, Zop.D + /// svuint64_t svextb[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #255 + /// svuint64_t svextb[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend8(Vector value) => ZeroExtend8(value); + + /// ZeroExtendWideningLower : Unpack and extend low half + + /// + /// svuint16_t svunpklo[_u16](svuint8_t op) + /// UUNPKLO Zresult.H, Zop.B + /// + public static unsafe Vector ZeroExtendWideningLower(Vector value) => ZeroExtendWideningLower(value); + + /// + /// svuint32_t svunpklo[_u32](svuint16_t op) + /// UUNPKLO Zresult.S, Zop.H + /// + public static unsafe Vector ZeroExtendWideningLower(Vector value) => ZeroExtendWideningLower(value); + + /// + /// svuint64_t svunpklo[_u64](svuint32_t op) + /// UUNPKLO Zresult.D, Zop.S + /// + public static unsafe Vector ZeroExtendWideningLower(Vector value) => ZeroExtendWideningLower(value); + + + /// ZeroExtendWideningUpper : Unpack and extend high half + + /// + /// svuint16_t svunpkhi[_u16](svuint8_t op) + /// UUNPKHI Zresult.H, Zop.B + /// + public static unsafe Vector ZeroExtendWideningUpper(Vector value) => ZeroExtendWideningUpper(value); + + /// + /// svuint32_t svunpkhi[_u32](svuint16_t op) + /// UUNPKHI Zresult.S, Zop.H + /// svbool_t svunpkhi[_b](svbool_t op) + /// PUNPKHI Presult.H, Pop.B + /// + public static unsafe Vector ZeroExtendWideningUpper(Vector value) => ZeroExtendWideningUpper(value); + + /// + /// svuint64_t svunpkhi[_u64](svuint32_t op) + /// UUNPKHI Zresult.D, Zop.S + /// + public static unsafe Vector ZeroExtendWideningUpper(Vector value) => ZeroExtendWideningUpper(value); + + /// ZipHigh : Interleave elements from high halves of two inputs + + /// + /// svuint8_t svzip2[_u8](svuint8_t op1, svuint8_t op2) + /// ZIP2 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svfloat64_t svzip2[_f64](svfloat64_t op1, svfloat64_t op2) + /// ZIP2 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svint16_t svzip2[_s16](svint16_t op1, svint16_t op2) + /// ZIP2 Zresult.H, Zop1.H, Zop2.H + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svint32_t svzip2[_s32](svint32_t op1, svint32_t op2) + /// ZIP2 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svint64_t svzip2[_s64](svint64_t op1, svint64_t op2) + /// ZIP2 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svint8_t svzip2[_s8](svint8_t op1, svint8_t op2) + /// ZIP2 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svfloat32_t svzip2[_f32](svfloat32_t op1, svfloat32_t op2) + /// ZIP2 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svuint16_t svzip2[_u16](svuint16_t op1, svuint16_t op2) + /// ZIP2 Zresult.H, Zop1.H, Zop2.H + /// svbool_t svzip2_b16(svbool_t op1, svbool_t op2) + /// ZIP2 Presult.H, Pop1.H, Pop2.H + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svuint32_t svzip2[_u32](svuint32_t op1, svuint32_t op2) + /// ZIP2 Zresult.S, Zop1.S, Zop2.S + /// svbool_t svzip2_b32(svbool_t op1, svbool_t op2) + /// ZIP2 Presult.S, Pop1.S, Pop2.S + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + /// + /// svuint64_t svzip2[_u64](svuint64_t op1, svuint64_t op2) + /// ZIP2 Zresult.D, Zop1.D, Zop2.D + /// svbool_t svzip2_b64(svbool_t op1, svbool_t op2) + /// ZIP2 Presult.D, Pop1.D, Pop2.D + /// + public static unsafe Vector ZipHigh(Vector left, Vector right) => ZipHigh(left, right); + + + /// ZipLow : Interleave elements from low halves of two inputs + + /// + /// svuint8_t svzip1[_u8](svuint8_t op1, svuint8_t op2) + /// ZIP1 Zresult.B, Zop1.B, Zop2.B + /// svbool_t svzip1_b8(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.B, Pop1.B, Pop2.B + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svfloat64_t svzip1[_f64](svfloat64_t op1, svfloat64_t op2) + /// ZIP1 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svint16_t svzip1[_s16](svint16_t op1, svint16_t op2) + /// ZIP1 Zresult.H, Zop1.H, Zop2.H + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svint32_t svzip1[_s32](svint32_t op1, svint32_t op2) + /// ZIP1 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svint64_t svzip1[_s64](svint64_t op1, svint64_t op2) + /// ZIP1 Zresult.D, Zop1.D, Zop2.D + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svint8_t svzip1[_s8](svint8_t op1, svint8_t op2) + /// ZIP1 Zresult.B, Zop1.B, Zop2.B + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svfloat32_t svzip1[_f32](svfloat32_t op1, svfloat32_t op2) + /// ZIP1 Zresult.S, Zop1.S, Zop2.S + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svuint16_t svzip1[_u16](svuint16_t op1, svuint16_t op2) + /// ZIP1 Zresult.H, Zop1.H, Zop2.H + /// svbool_t svzip1_b16(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.H, Pop1.H, Pop2.H + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svuint32_t svzip1[_u32](svuint32_t op1, svuint32_t op2) + /// ZIP1 Zresult.S, Zop1.S, Zop2.S + /// svbool_t svzip1_b32(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.S, Pop1.S, Pop2.S + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); + + /// + /// svuint64_t svzip1[_u64](svuint64_t op1, svuint64_t op2) + /// ZIP1 Zresult.D, Zop1.D, Zop2.D + /// svbool_t svzip1_b64(svbool_t op1, svbool_t op2) + /// ZIP1 Presult.D, Pop1.D, Pop2.D + /// + public static unsafe Vector ZipLow(Vector left, Vector right) => ZipLow(left, right); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 66c0a47734429c..4080b06c92b77b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -468,7 +468,7 @@ public static unsafe Vector128 ConvertToDouble(Vector128 vector) } } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -481,7 +481,20 @@ public static unsafe Vector128 ConvertToInt32(Vector128 vector) ); } - /// Converts a to a . + /// Converts a to a platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector128 ConvertToInt32Native(Vector128 vector) + { + return Create( + Vector64.ConvertToInt32Native(vector._lower), + Vector64.ConvertToInt32Native(vector._upper) + ); + } + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -494,6 +507,19 @@ public static unsafe Vector128 ConvertToInt64(Vector128 vector) ); } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector128 ConvertToInt64Native(Vector128 vector) + { + return Create( + Vector64.ConvertToInt64Native(vector._lower), + Vector64.ConvertToInt64Native(vector._upper) + ); + } + /// Converts a to a . /// The vector to convert. /// The converted vector. @@ -564,7 +590,7 @@ static Vector128 SoftwareFallback(Vector128 vector) } } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -578,7 +604,21 @@ public static unsafe Vector128 ConvertToUInt32(Vector128 vector) ); } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector128 ConvertToUInt32Native(Vector128 vector) + { + return Create( + Vector64.ConvertToUInt32Native(vector._lower), + Vector64.ConvertToUInt32Native(vector._upper) + ); + } + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -592,6 +632,20 @@ public static unsafe Vector128 ConvertToUInt64(Vector128 vector) ); } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector128 ConvertToUInt64Native(Vector128 vector) + { + return Create( + Vector64.ConvertToUInt64Native(vector._lower), + Vector64.ConvertToUInt64Native(vector._upper) + ); + } + /// Copies a to a given array. /// The type of the elements in the vector. /// The vector to be copied. @@ -1041,7 +1095,7 @@ public static Vector128 Create(Vector64 lower, Vector64 upper) } else { - ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType(); + ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); Unsafe.SkipInit(out Vector128 result); result.SetLowerUnsafe(lower); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs index 1347a082afab97..4d174eef197544 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs @@ -386,7 +386,7 @@ public static Vector256 ConvertToDouble(Vector256 vector) } } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -399,7 +399,20 @@ public static Vector256 ConvertToInt32(Vector256 vector) ); } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 ConvertToInt32Native(Vector256 vector) + { + return Create( + Vector128.ConvertToInt32Native(vector._lower), + Vector128.ConvertToInt32Native(vector._upper) + ); + } + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -412,6 +425,19 @@ public static Vector256 ConvertToInt64(Vector256 vector) ); } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 ConvertToInt64Native(Vector256 vector) + { + return Create( + Vector128.ConvertToInt64Native(vector._lower), + Vector128.ConvertToInt64Native(vector._upper) + ); + } + /// Converts a to a . /// The vector to convert. /// The converted vector. @@ -472,7 +498,7 @@ public static Vector256 ConvertToSingle(Vector256 vector) } } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -486,7 +512,21 @@ public static Vector256 ConvertToUInt32(Vector256 vector) ); } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 ConvertToUInt32Native(Vector256 vector) + { + return Create( + Vector128.ConvertToUInt32Native(vector._lower), + Vector128.ConvertToUInt32Native(vector._upper) + ); + } + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -500,6 +540,20 @@ public static Vector256 ConvertToUInt64(Vector256 vector) ); } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector256 ConvertToUInt64Native(Vector256 vector) + { + return Create( + Vector128.ConvertToUInt64Native(vector._lower), + Vector128.ConvertToUInt64Native(vector._upper) + ); + } + /// Copies a to a given array. /// The type of the elements in the vector. /// The vector to be copied. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index edb84585a987de..d63f12afb64d9c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -348,7 +348,7 @@ public static Vector512 ConvertToDouble(Vector512 vector) ); } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -361,7 +361,20 @@ public static Vector512 ConvertToInt32(Vector512 vector) ); } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 ConvertToInt32Native(Vector512 vector) + { + return Create( + Vector256.ConvertToInt32Native(vector._lower), + Vector256.ConvertToInt32Native(vector._upper) + ); + } + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -374,6 +387,19 @@ public static Vector512 ConvertToInt64(Vector512 vector) ); } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 ConvertToInt64Native(Vector512 vector) + { + return Create( + Vector256.ConvertToInt64Native(vector._lower), + Vector256.ConvertToInt64Native(vector._upper) + ); + } + /// Converts a to a . /// The vector to convert. /// The converted vector. @@ -401,7 +427,7 @@ public static Vector512 ConvertToSingle(Vector512 vector) ); } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -415,7 +441,21 @@ public static Vector512 ConvertToUInt32(Vector512 vector) ); } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 ConvertToUInt32Native(Vector512 vector) + { + return Create( + Vector256.ConvertToUInt32Native(vector._lower), + Vector256.ConvertToUInt32Native(vector._upper) + ); + } + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -429,6 +469,20 @@ public static Vector512 ConvertToUInt64(Vector512 vector) ); } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector512 ConvertToUInt64Native(Vector512 vector) + { + return Create( + Vector256.ConvertToUInt64Native(vector._lower), + Vector256.ConvertToUInt64Native(vector._upper) + ); + } + /// Copies a to a given array. /// The type of the elements in the vector. /// The vector to be copied. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs index 50e9f697c94f44..04c5e0672a9d1b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs @@ -339,7 +339,7 @@ public static unsafe Vector64 ConvertToDouble(Vector64 vector) return result; } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -357,7 +357,14 @@ public static unsafe Vector64 ConvertToInt32(Vector64 vector) return result; } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector64 ConvertToInt32Native(Vector64 vector) => ConvertToInt32(vector); + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -375,6 +382,13 @@ public static unsafe Vector64 ConvertToInt64(Vector64 vector) return result; } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector64 ConvertToInt64Native(Vector64 vector) => ConvertToInt64(vector); + /// Converts a to a . /// The vector to convert. /// The converted vector. @@ -412,7 +426,7 @@ public static unsafe Vector64 ConvertToSingle(Vector64 vector) return result; } - /// Converts a to a . + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -431,7 +445,15 @@ public static unsafe Vector64 ConvertToUInt32(Vector64 vector) return result; } - /// Converts a to a . + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector64 ConvertToUInt32Native(Vector64 vector) => ConvertToUInt32(vector); + + /// Converts a to a using saturation on overflow. /// The vector to convert. /// The converted vector. [Intrinsic] @@ -450,6 +472,14 @@ public static unsafe Vector64 ConvertToUInt64(Vector64 vector) return result; } + /// Converts a to a using platform specific behavior on overflow. + /// The vector to convert. + /// The converted vector. + [Intrinsic] + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe Vector64 ConvertToUInt64Native(Vector64 vector) => ConvertToUInt64(vector); + /// Copies a to a given array. /// The type of the elements in the vector. /// The vector to be copied. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index 1bacef78f3257e..498aa1e4d4a9c2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -30,7 +30,7 @@ private enum InternalState Unloading } - private static volatile Dictionary>? s_allContexts; + private static Dictionary>? s_allContexts; private static long s_nextId; [MemberNotNull(nameof(s_allContexts))] diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs index 9cc7c6b56c0adf..fe96bb1b419f7a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Single.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs @@ -650,6 +650,16 @@ public static bool IsPow2(float value) [Intrinsic] public static float Ceiling(float x) => MathF.Ceiling(x); + /// + [Intrinsic] + public static TInteger ConvertToInteger(float value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + + /// + [Intrinsic] + public static TInteger ConvertToIntegerNative(float value) + where TInteger : IBinaryInteger => TInteger.CreateSaturating(value); + /// [Intrinsic] public static float Floor(float x) => MathF.Floor(x); @@ -838,9 +848,11 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinatio public static float Lerp(float value1, float value2, float amount) => (value1 * (1.0f - amount)) + (value2 * amount); /// + [Intrinsic] public static float ReciprocalEstimate(float x) => MathF.ReciprocalEstimate(x); /// + [Intrinsic] public static float ReciprocalSqrtEstimate(float x) => MathF.ReciprocalSqrtEstimate(x); /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Span.cs b/src/libraries/System.Private.CoreLib/src/System/Span.cs index 38b94e872b0cb3..691b2eb558f35b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Span.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Span.cs @@ -9,7 +9,7 @@ using EditorBrowsableAttribute = System.ComponentModel.EditorBrowsableAttribute; using EditorBrowsableState = System.ComponentModel.EditorBrowsableState; -#pragma warning disable 0809 //warning CS0809: Obsolete member 'Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' +#pragma warning disable 0809 // Obsolete member 'Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' #pragma warning disable 8500 // address / sizeof of managed types namespace System diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs index 7f4f642526d451..596e743ebe215d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs @@ -62,10 +62,19 @@ public static string Concat(object? arg0, object? arg1, object? arg2) => public static string Concat(params object?[] args) { ArgumentNullException.ThrowIfNull(args); + return Concat((ReadOnlySpan)args); + } + /// + /// Concatenates the string representations of the elements in a specified span of objects. + /// + /// A span of objects that contains the elements to concatenate. + /// The concatenated string representations of the values of the elements in . + public static string Concat(/*params*/ ReadOnlySpan args) + { if (args.Length <= 1) { - return args.Length == 0 ? + return args.IsEmpty ? Empty : args[0]?.ToString() ?? Empty; } @@ -355,10 +364,19 @@ internal static string Concat(ReadOnlySpan str0, ReadOnlySpan str1, public static string Concat(params string?[] values) { ArgumentNullException.ThrowIfNull(values); + return Concat((ReadOnlySpan)values); + } + /// + /// Concatenates the elements of a specified span of . + /// + /// A span of instances. + /// The concatenated elements of . + public static string Concat(/*params*/ ReadOnlySpan values) + { if (values.Length <= 1) { - return values.Length == 0 ? + return values.IsEmpty ? Empty : values[0] ?? Empty; } @@ -416,7 +434,7 @@ public static string Concat(params string?[] values) // something changed concurrently to mutate the input array: fall back to // doing the concatenation again, but this time with a defensive copy. This // fall back should be extremely rare. - return copiedLength == totalLength ? result : Concat((string?[])values.Clone()); + return copiedLength == totalLength ? result : Concat((ReadOnlySpan)values.ToArray()); } public static string Format([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0) @@ -445,6 +463,17 @@ public static string Format([StringSyntax(StringSyntaxAttribute.CompositeFormat) ArgumentNullException.Throw(format is null ? nameof(format) : nameof(args)); } + return FormatHelper(null, format, (ReadOnlySpan)args); + } + + /// + /// Replaces the format item in a specified string with the string representation of a corresponding object in a specified span. + /// + /// A composite format string. + /// An object span that contains zero or more objects to format. + /// A copy of in which the format items have been replaced by the string representation of the corresponding objects in . + public static string Format([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan args) + { return FormatHelper(null, format, args); } @@ -474,6 +503,19 @@ public static string Format(IFormatProvider? provider, [StringSyntax(StringSynta ArgumentNullException.Throw(format is null ? nameof(format) : nameof(args)); } + return FormatHelper(provider, format, (ReadOnlySpan)args); + } + + /// + /// Replaces the format items in a string with the string representations of corresponding objects in a specified span. + /// A parameter supplies culture-specific formatting information. + /// + /// An object that supplies culture-specific formatting information. + /// A composite format string. + /// An object span that contains zero or more objects to format. + /// A copy of in which the format items have been replaced by the string representation of the corresponding objects in . + public static string Format(IFormatProvider? provider, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan args) + { return FormatHelper(provider, format, args); } @@ -575,7 +617,7 @@ public static string Format(IFormatProvider? provider, CompositeFormat format, p /// The formatted string. /// is null. /// The index of a format item is greater than or equal to the number of supplied arguments. - public static string Format(IFormatProvider? provider, CompositeFormat format, ReadOnlySpan args) + public static string Format(IFormatProvider? provider, CompositeFormat format, /*params*/ ReadOnlySpan args) { ArgumentNullException.ThrowIfNull(format); format.ValidateNumberOfArgs(args.Length); @@ -669,6 +711,21 @@ public static string Join(char separator, params string?[] value) return JoinCore(new ReadOnlySpan(in separator), new ReadOnlySpan(value)); } + /// + /// Concatenates a span of strings, using the specified separator between each member. + /// + /// The character to use as a separator. is included in the returned string only if has more than one element. + /// A span that contains the elements to concatenate. + /// + /// A string that consists of the elements of delimited by the string. + /// -or- + /// if has zero elements. + /// + public static string Join(char separator, /*params*/ ReadOnlySpan value) + { + return JoinCore(new ReadOnlySpan(in separator), value); + } + public static string Join(string? separator, params string?[] value) { if (value == null) @@ -679,6 +736,21 @@ public static string Join(string? separator, params string?[] value) return JoinCore(separator.AsSpan(), new ReadOnlySpan(value)); } + /// + /// Concatenates a span of strings, using the specified separator between each member. + /// + /// The string to use as a separator. is included in the returned string only if has more than one element. + /// A span that contains the elements to concatenate. + /// + /// A string that consists of the elements of delimited by the string. + /// -or- + /// if has zero elements. + /// + public static string Join(string? separator, /*params*/ ReadOnlySpan value) + { + return JoinCore(separator.AsSpan(), value); + } + public static string Join(char separator, string?[] value, int startIndex, int count) => JoinCore(new ReadOnlySpan(in separator), value, startIndex, count); @@ -743,20 +815,55 @@ public static string Join(string? separator, IEnumerable values) } } - public static string Join(char separator, params object?[] values) => - JoinCore(new ReadOnlySpan(in separator), values); + public static string Join(char separator, params object?[] values) + { + if (values == null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } - public static string Join(string? separator, params object?[] values) => - JoinCore(separator.AsSpan(), values); + return JoinCore(new ReadOnlySpan(in separator), (ReadOnlySpan)values); + } - private static string JoinCore(ReadOnlySpan separator, object?[] values) + /// + /// Concatenates the string representations of a span of objects, using the specified separator between each member. + /// + /// The character to use as a separator. is included in the returned string only if value has more than one element. + /// A span of objects whose string representations will be concatenated. + /// + /// A string that consists of the elements of delimited by the character. + /// -or- + /// if has zero elements. + /// + public static string Join(char separator, /*params*/ ReadOnlySpan values) => + JoinCore(new ReadOnlySpan(in separator), values); + + public static string Join(string? separator, params object?[] values) { if (values == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); } - if (values.Length == 0) + return JoinCore(separator.AsSpan(), (ReadOnlySpan)values); + } + + /// + /// Concatenates the string representations of a span of objects, using the specified separator between each member. + /// + /// The string to use as a separator. is included in the returned string only if has more than one element. + /// A span of objects whose string representations will be concatenated. + /// + /// A string that consists of the elements of delimited by the string. + /// -or- + /// if has zero elements. + /// + public static string Join(string? separator, /*params*/ ReadOnlySpan values) => + JoinCore(separator.AsSpan(), values); + + private static string JoinCore(ReadOnlySpan separator, ReadOnlySpan values) + { + if (values.IsEmpty) { return Empty; } @@ -793,11 +900,16 @@ public static string Join(string? separator, IEnumerable values) => private static string JoinCore(ReadOnlySpan separator, IEnumerable values) { + if (values is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } + if (typeof(T) == typeof(string)) { - if (values is List valuesList) + if (values.GetType() == typeof(List)) // avoid accidentally bypassing a derived type's reimplementation of IEnumerable { - return JoinCore(separator, CollectionsMarshal.AsSpan(valuesList)); + return JoinCore(separator, CollectionsMarshal.AsSpan(Unsafe.As>(values))); } if (values is string?[] valuesArray) @@ -806,11 +918,6 @@ private static string JoinCore(ReadOnlySpan separator, IEnumerable v } } - if (values == null) - { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); - } - using (IEnumerator e = values.GetEnumerator()) { if (!e.MoveNext()) @@ -1548,6 +1655,16 @@ public string[] Split(params char[]? separator) return SplitInternal(separator, int.MaxValue, StringSplitOptions.None); } + /// + /// Splits a string into substrings based on specified delimiting characters. + /// + /// A span of delimiting characters, or an empty span that contains no delimiters. + /// An array whose elements contain the substrings from this instance that are delimited by one or more characters in . + public string[] Split(/*params*/ ReadOnlySpan separator) + { + return SplitInternal(separator, int.MaxValue, StringSplitOptions.None); + } + // Creates an array of strings by splitting this string at each // occurrence of a separator. The separator is searched for, and if found, // the substring preceding the occurrence is stored as the first element in @@ -2241,6 +2358,28 @@ public unsafe string Trim(params char[]? trimChars) } } + /// + /// Removes all leading and trailing occurrences of a set of characters specified in a span from the current string. + /// + /// A span of Unicode characters to remove. + /// + /// The string that remains after all occurrences of the characters in the parameter are removed from the start and end of the current string. + /// If is empty, white-space characters are removed instead. + /// If no characters can be trimmed from the current instance, the method returns the current instance unchanged. + /// + public unsafe string Trim(/*params*/ ReadOnlySpan trimChars) + { + if (trimChars.IsEmpty) + { + return TrimWhiteSpaceHelper(TrimType.Both); + } + + fixed (char* pTrimChars = &MemoryMarshal.GetReference(trimChars)) + { + return TrimHelper(pTrimChars, trimChars.Length, TrimType.Both); + } + } + // Removes a set of characters from the beginning of this string. public string TrimStart() => TrimWhiteSpaceHelper(TrimType.Head); @@ -2260,6 +2399,28 @@ public unsafe string TrimStart(params char[]? trimChars) } } + /// + /// Removes all the leading occurrences of a set of characters specified in a span from the current string. + /// + /// A span of Unicode characters to remove. + /// + /// The string that remains after all occurrences of characters in the parameter are removed from the start of the current string. + /// If is empty, white-space characters are removed instead. + /// If no characters can be trimmed from the current instance, the method returns the current instance unchanged. + /// + public unsafe string TrimStart(/*params*/ ReadOnlySpan trimChars) + { + if (trimChars.IsEmpty) + { + return TrimWhiteSpaceHelper(TrimType.Head); + } + + fixed (char* pTrimChars = &MemoryMarshal.GetReference(trimChars)) + { + return TrimHelper(pTrimChars, trimChars.Length, TrimType.Head); + } + } + // Removes a set of characters from the end of this string. public string TrimEnd() => TrimWhiteSpaceHelper(TrimType.Tail); @@ -2279,6 +2440,28 @@ public unsafe string TrimEnd(params char[]? trimChars) } } + /// + /// Removes all the trailing occurrences of a set of characters specified in a span from the current string. + /// + /// A span of Unicode characters to remove. + /// + /// The string that remains after all occurrences of characters in the parameter are removed from the end of the current string. + /// If is empty, white-space characters are removed instead. + /// If no characters can be trimmed from the current instance, the method returns the current instance unchanged. + /// + public unsafe string TrimEnd(/*params*/ ReadOnlySpan trimChars) + { + if (trimChars.IsEmpty) + { + return TrimWhiteSpaceHelper(TrimType.Tail); + } + + fixed (char* pTrimChars = &trimChars[0]) + { + return TrimHelper(pTrimChars, trimChars.Length, TrimType.Tail); + } + } + private string TrimWhiteSpaceHelper(TrimType trimType) { // end will point to the first non-trimmed character on the right. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/EncodingProvider.cs b/src/libraries/System.Private.CoreLib/src/System/Text/EncodingProvider.cs index 11b284f8e04d96..b939492ed97530 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/EncodingProvider.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/EncodingProvider.cs @@ -118,10 +118,10 @@ internal static void AddProvider(EncodingProvider provider) internal static Encoding? GetEncodingFromProvider(string encodingName) { - if (s_providers == null) + EncodingProvider[]? providers = s_providers; + if (providers == null) return null; - EncodingProvider[] providers = s_providers; foreach (EncodingProvider provider in providers) { Encoding? enc = provider.GetEncoding(encodingName); @@ -134,10 +134,10 @@ internal static void AddProvider(EncodingProvider provider) internal static Encoding? GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec) { - if (s_providers == null) + EncodingProvider[]? providers = s_providers; + if (providers == null) return null; - EncodingProvider[] providers = s_providers; foreach (EncodingProvider provider in providers) { Encoding? encoding = provider.GetEncoding(codepage, enc, dec); @@ -150,10 +150,10 @@ internal static void AddProvider(EncodingProvider provider) internal static Encoding? GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec) { - if (s_providers == null) + EncodingProvider[]? providers = s_providers; + if (providers == null) return null; - EncodingProvider[] providers = s_providers; foreach (EncodingProvider provider in providers) { Encoding? encoding = provider.GetEncoding(encodingName, enc, dec); diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs index 6f7b0abfa9b91f..e7bee231dbf45d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs @@ -1123,6 +1123,24 @@ public StringBuilder Append(ReadOnlySpan value) #region AppendJoin public StringBuilder AppendJoin(string? separator, params object?[] values) + { + if (values is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } + + separator ??= string.Empty; + return AppendJoinCore(ref separator.GetRawStringData(), separator.Length, values); + } + + /// + /// Concatenates the string representations of the elements in the provided span of objects, using the specified separator between each member, + /// then appends the result to the current instance of the string builder. + /// + /// The string to use as a separator. is included in the joined strings only if has more than one element. + /// A span that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + public StringBuilder AppendJoin(string? separator, /*params*/ ReadOnlySpan values) { separator ??= string.Empty; return AppendJoinCore(ref separator.GetRawStringData(), separator.Length, values); @@ -1130,11 +1148,34 @@ public StringBuilder AppendJoin(string? separator, params object?[] values) public StringBuilder AppendJoin(string? separator, IEnumerable values) { + if (values is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } + separator ??= string.Empty; return AppendJoinCore(ref separator.GetRawStringData(), separator.Length, values); } public StringBuilder AppendJoin(string? separator, params string?[] values) + { + if (values is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } + + separator ??= string.Empty; + return AppendJoinCore(ref separator.GetRawStringData(), separator.Length, values); + } + + /// + /// Concatenates the strings of the provided span, using the specified separator between each string, + /// then appends the result to the current instance of the string builder. + /// + /// The string to use as a separator. is included in the joined strings only if has more than one element. + /// A span that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + public StringBuilder AppendJoin(string? separator, /*params*/ ReadOnlySpan values) { separator ??= string.Empty; return AppendJoinCore(ref separator.GetRawStringData(), separator.Length, values); @@ -1142,30 +1183,60 @@ public StringBuilder AppendJoin(string? separator, params string?[] values) public StringBuilder AppendJoin(char separator, params object?[] values) { - return AppendJoinCore(ref separator, 1, values); + if (values is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } + + return AppendJoinCore(ref separator, 1, (ReadOnlySpan)values); } + /// + /// Concatenates the string representations of the elements in the provided span of objects, using the specified char separator between each member, + /// then appends the result to the current instance of the string builder. + /// + /// The character to use as a separator. is included in the joined strings only if has more than one element. + /// A span that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + public StringBuilder AppendJoin(char separator, /*params*/ ReadOnlySpan values) => + AppendJoinCore(ref separator, 1, values); + public StringBuilder AppendJoin(char separator, IEnumerable values) { + if (values is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } + return AppendJoinCore(ref separator, 1, values); } public StringBuilder AppendJoin(char separator, params string?[] values) { - return AppendJoinCore(ref separator, 1, values); + if (values is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); + } + + return AppendJoinCore(ref separator, 1, (ReadOnlySpan)values); } + /// + /// Concatenates the strings of the provided span, using the specified char separator between each string, + /// then appends the result to the current instance of the string builder. + /// + /// The character to use as a separator. is included in the joined strings only if has more than one element. + /// A span that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + public StringBuilder AppendJoin(char separator, /*params*/ ReadOnlySpan values) => + AppendJoinCore(ref separator, 1, values); + private StringBuilder AppendJoinCore(ref char separator, int separatorLength, IEnumerable values) { + Debug.Assert(values != null); Debug.Assert(!Unsafe.IsNullRef(ref separator)); Debug.Assert(separatorLength >= 0); - if (values == null) - { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); - } - - Debug.Assert(values != null); using (IEnumerator en = values.GetEnumerator()) { if (!en.MoveNext()) @@ -1192,15 +1263,9 @@ private StringBuilder AppendJoinCore(ref char separator, int separatorLength, return this; } - private StringBuilder AppendJoinCore(ref char separator, int separatorLength, T[] values) + private StringBuilder AppendJoinCore(ref char separator, int separatorLength, ReadOnlySpan values) { - if (values == null) - { - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); - } - - Debug.Assert(values != null); - if (values.Length == 0) + if (values.IsEmpty) { return this; } @@ -1360,19 +1425,19 @@ private StringBuilder InsertSpanFormattable(int index, T value) where T : ISp public StringBuilder AppendFormat([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0) { - return AppendFormatHelper(null, format, new ReadOnlySpan(in arg0)); + return AppendFormat(null, format, new ReadOnlySpan(in arg0)); } public StringBuilder AppendFormat([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1) { TwoObjects two = new TwoObjects(arg0, arg1); - return AppendFormatHelper(null, format, two); + return AppendFormat(null, format, (ReadOnlySpan)two); } public StringBuilder AppendFormat([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1, object? arg2) { ThreeObjects three = new ThreeObjects(arg0, arg1, arg2); - return AppendFormatHelper(null, format, three); + return AppendFormat(null, format, (ReadOnlySpan)three); } public StringBuilder AppendFormat([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, params object?[] args) @@ -1380,28 +1445,47 @@ public StringBuilder AppendFormat([StringSyntax(StringSyntaxAttribute.CompositeF if (args is null) { // To preserve the original exception behavior, throw an exception about format if both - // args and format are null. The actual null check for format is in AppendFormatHelper. + // args and format are null. The actual null check for format is in AppendFormat(..., span). ArgumentNullException.Throw(format is null ? nameof(format) : nameof(args)); } - return AppendFormatHelper(null, format, args); + return AppendFormat(null, format, args); + } + + /// + /// Appends the string returned by processing a composite format string, which contains zero or more format items, to this instance. + /// Each format item is replaced by the string representation of a corresponding argument in a parameter span. + /// + /// A composite format string. + /// A span of objects to format. + /// A reference to this instance after the append operation has completed. + /// is null. + /// The length of the expanded string would exceed . + /// + /// is invalid. + /// -or- + /// The index of a format item is less than 0 (zero), or greater than or equal to the length of the span. + /// + public StringBuilder AppendFormat([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan args) + { + return AppendFormat(null, format, args); } public StringBuilder AppendFormat(IFormatProvider? provider, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0) { - return AppendFormatHelper(provider, format, new ReadOnlySpan(in arg0)); + return AppendFormat(provider, format, new ReadOnlySpan(in arg0)); } public StringBuilder AppendFormat(IFormatProvider? provider, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1) { TwoObjects two = new TwoObjects(arg0, arg1); - return AppendFormatHelper(provider, format, two); + return AppendFormat(provider, format, (ReadOnlySpan)two); } public StringBuilder AppendFormat(IFormatProvider? provider, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, object? arg0, object? arg1, object? arg2) { ThreeObjects three = new ThreeObjects(arg0, arg1, arg2); - return AppendFormatHelper(provider, format, three); + return AppendFormat(provider, format, (ReadOnlySpan)three); } public StringBuilder AppendFormat(IFormatProvider? provider, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, params object?[] args) @@ -1409,14 +1493,29 @@ public StringBuilder AppendFormat(IFormatProvider? provider, [StringSyntax(Strin if (args is null) { // To preserve the original exception behavior, throw an exception about format if both - // args and format are null. The actual null check for format is in AppendFormatHelper. + // args and format are null. The actual null check for format is in AppendFormat(..., span). ArgumentNullException.Throw(format is null ? nameof(format) : nameof(args)); } - return AppendFormatHelper(provider, format, args); + return AppendFormat(provider, format, (ReadOnlySpan)args); } - internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string format, ReadOnlySpan args) + /// + /// Appends the string returned by processing a composite format string, which contains zero or more format items, to this instance. + /// Each format item is replaced by the string representation of a corresponding argument in a parameter span using a specified format provider. + /// + /// An object that supplies culture-specific formatting information. + /// A composite format string. + /// A span of objects to format. + /// A reference to this instance after the append operation has completed. + /// is null. + /// The length of the expanded string would exceed . + /// + /// is invalid. + /// -or- + /// The index of a format item is less than 0 (zero), or greater than or equal to the length of the span. + /// + public StringBuilder AppendFormat(IFormatProvider? provider, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string format, /*params*/ ReadOnlySpan args) { ArgumentNullException.ThrowIfNull(format); @@ -1776,7 +1875,7 @@ public StringBuilder AppendFormat(IFormatProvider? provider, CompositeFormat for /// A reference to this instance after the append operation has completed. /// is null. /// The index of a format item is greater than or equal to the number of supplied arguments. - public StringBuilder AppendFormat(IFormatProvider? provider, CompositeFormat format, ReadOnlySpan args) + public StringBuilder AppendFormat(IFormatProvider? provider, CompositeFormat format, /*params*/ ReadOnlySpan args) { ArgumentNullException.ThrowIfNull(format); format.ValidateNumberOfArgs(args.Length); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs index ace2ed4b943d93..092b9467232157 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs @@ -868,7 +868,17 @@ public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken public static CancellationTokenSource CreateLinkedTokenSource(params CancellationToken[] tokens) { ArgumentNullException.ThrowIfNull(tokens); + return CreateLinkedTokenSource((ReadOnlySpan)tokens); + } + /// + /// Creates a that will be in the canceled state + /// when any of the source tokens are in the canceled state. + /// + /// The CancellationToken instances to observe. + /// A that is linked to the source tokens. + public static CancellationTokenSource CreateLinkedTokenSource(/*params*/ ReadOnlySpan tokens) + { return tokens.Length switch { 0 => throw new ArgumentException(SR.CancellationToken_CreateLinkedToken_TokensIsEmpty), @@ -935,7 +945,7 @@ private sealed class LinkedNCancellationTokenSource : CancellationTokenSource }; private CancellationTokenRegistration[]? _linkingRegistrations; - internal LinkedNCancellationTokenSource(CancellationToken[] tokens) + internal LinkedNCancellationTokenSource(ReadOnlySpan tokens) { _linkingRegistrations = new CancellationTokenRegistration[tokens.Length]; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs index 986ea1bd62ce94..c455235faf9585 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs @@ -20,7 +20,7 @@ namespace System.Threading public sealed class ExecutionContext : IDisposable, ISerializable { internal static readonly ExecutionContext Default = new ExecutionContext(); - private static volatile ExecutionContext? s_defaultFlowSuppressed; + private static ExecutionContext? s_defaultFlowSuppressed; private readonly IAsyncLocalValueMap? m_localValues; private readonly IAsyncLocal[]? m_localChangeNotifications; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs index 45ebce76f7b0ee..6e33ce716fd6a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs @@ -126,7 +126,7 @@ public static unsafe ushort Exchange(ref ushort location1, ushort value) nuint offset = Unsafe.OpportunisticMisalignment(ref location1, sizeof(uint)); ref uint alignedRef = ref Unsafe.As(ref Unsafe.SubtractByteOffset(ref location1, offset)); int bitOffset = - (int)((BitConverter.IsLittleEndian ? offset : sizeof(uint) - offset - sizeof(byte)) * 8); // to bit offset + (int)((BitConverter.IsLittleEndian ? offset : sizeof(uint) - offset - sizeof(ushort)) * 8); // to bit offset Debug.Assert(bitOffset is 0 or 16); uint mask = ~((uint)ushort.MaxValue << bitOffset); uint shiftedValue = (uint)value << bitOffset; @@ -308,7 +308,7 @@ public static unsafe ushort CompareExchange(ref ushort location1, ushort value, nuint offset = Unsafe.OpportunisticMisalignment(ref location1, sizeof(uint)); ref uint alignedRef = ref Unsafe.As(ref Unsafe.SubtractByteOffset(ref location1, offset)); int bitOffset = - (int)((BitConverter.IsLittleEndian ? offset : sizeof(uint) - offset - sizeof(byte)) * 8); // to bit offset + (int)((BitConverter.IsLittleEndian ? offset : sizeof(uint) - offset - sizeof(ushort)) * 8); // to bit offset Debug.Assert(bitOffset is 0 or 16); uint mask = ~((uint)ushort.MaxValue << bitOffset); uint shiftedValue = (uint)value << bitOffset; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.NonNativeAot.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.NonNativeAot.cs index 9386b7ed174601..bd3a0be6902af9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.NonNativeAot.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.NonNativeAot.cs @@ -9,13 +9,19 @@ namespace System.Threading public sealed partial class Lock { private static readonly short s_maxSpinCount = DetermineMaxSpinCount(); - private static readonly short s_minSpinCount = DetermineMinSpinCount(); + private static readonly short s_minSpinCountForAdaptiveSpin = DetermineMinSpinCountForAdaptiveSpin(); /// /// Initializes a new instance of the class. /// public Lock() => _spinCount = s_maxSpinCount; + internal ulong OwningOSThreadId => _owningThreadId; + +#pragma warning disable CA1822 // can be marked as static - varies between runtimes + internal int OwningManagedThreadId => 0; +#pragma warning restore CA1822 + private static TryLockResult LazyInitializeOrEnter() => TryLockResult.Spin; private static bool IsSingleProcessor => Environment.IsSingleProcessor; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs index b7961869eac5d2..4572c9c310ecef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs @@ -37,7 +37,15 @@ public sealed partial class Lock private uint _state; // see State for layout private uint _recursionCount; + + // This field serves a few purposes currently: + // - When positive, it indicates the number of spin-wait iterations that most threads would do upon contention + // - When zero, it indicates that spin-waiting is to be attempted by a thread to test if it is successful + // - When negative, it serves as a rough counter for contentions that would increment it towards zero + // + // See references to this field and "AdaptiveSpin" in TryEnterSlow for more information. private short _spinCount; + private ushort _waiterStartTimeMs; private AutoResetEvent? _waitEvent; @@ -297,7 +305,7 @@ private void ExitImpl() } } - private static bool IsAdaptiveSpinEnabled(short minSpinCount) => minSpinCount <= 0; + private static bool IsAdaptiveSpinEnabled(short minSpinCountForAdaptiveSpin) => minSpinCountForAdaptiveSpin <= 0; [MethodImpl(MethodImplOptions.NoInlining)] private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) @@ -334,25 +342,35 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) return new ThreadId(0); } + // + // At this point, a full lock attempt has been made, and it's time to retry or wait for the lock. + // + + // Notify the debugger that this thread is about to wait for a lock that is likely held by another thread. The + // debugger may choose to enable other threads to run to help resolve the dependency, or it may choose to abort the + // FuncEval here. The lock state is consistent here for an abort, whereas letting a FuncEval continue to run could + // lead to the FuncEval timing out and potentially aborting at an arbitrary place where the lock state may not be + // consistent. + Debugger.NotifyOfCrossThreadDependency(); + if (LazyInitializeOrEnter() == TryLockResult.Locked) { goto Locked; } - bool isSingleProcessor = IsSingleProcessor; short maxSpinCount = s_maxSpinCount; if (maxSpinCount == 0) { goto Wait; } - short minSpinCount = s_minSpinCount; + short minSpinCountForAdaptiveSpin = s_minSpinCountForAdaptiveSpin; short spinCount = _spinCount; if (spinCount < 0) { // When negative, the spin count serves as a counter for contentions such that a spin-wait can be attempted // periodically to see if it would be beneficial. Increment the spin count and skip spin-waiting. - Debug.Assert(IsAdaptiveSpinEnabled(minSpinCount)); + Debug.Assert(IsAdaptiveSpinEnabled(minSpinCountForAdaptiveSpin)); _spinCount = (short)(spinCount + 1); goto Wait; } @@ -377,7 +395,7 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) for (short spinIndex = 0; ;) { - LowLevelSpinWaiter.Wait(spinIndex, SpinSleep0Threshold, isSingleProcessor); + LowLevelSpinWaiter.Wait(spinIndex, SpinSleep0Threshold, isSingleProcessor: false); if (++spinIndex >= spinCount) { @@ -394,7 +412,7 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) if (tryLockResult == TryLockResult.Locked) { - if (isFirstSpinner && IsAdaptiveSpinEnabled(minSpinCount)) + if (isFirstSpinner && IsAdaptiveSpinEnabled(minSpinCountForAdaptiveSpin)) { // Since the first spinner does a full-length spin-wait, and to keep upward and downward changes to the // spin count more balanced, only the first spinner adjusts the spin count @@ -415,7 +433,7 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) // Unregister the spinner and try to acquire the lock tryLockResult = State.TryLockAfterSpinLoop(this); - if (isFirstSpinner && IsAdaptiveSpinEnabled(minSpinCount)) + if (isFirstSpinner && IsAdaptiveSpinEnabled(minSpinCountForAdaptiveSpin)) { // Since the first spinner does a full-length spin-wait, and to keep upward and downward changes to the // spin count more balanced, only the first spinner adjusts the spin count @@ -433,7 +451,7 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) // number of contentions, the first spinner will attempt a spin-wait again to see if it is effective. Debug.Assert(tryLockResult == TryLockResult.Wait); spinCount = _spinCount; - _spinCount = spinCount > 0 ? (short)(spinCount - 1) : minSpinCount; + _spinCount = spinCount > 0 ? (short)(spinCount - 1) : minSpinCountForAdaptiveSpin; } } @@ -477,6 +495,8 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) waitStartTimeTicks = Stopwatch.GetTimestamp(); } + using ThreadBlockingInfo.Scope threadBlockingScope = new(this, timeoutMs); + bool acquiredLock = false; int waitStartTimeMs = timeoutMs < 0 ? 0 : Environment.TickCount; int remainingTimeoutMs = timeoutMs; @@ -504,7 +524,7 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) break; } - LowLevelSpinWaiter.Wait(spinIndex, SpinSleep0Threshold, isSingleProcessor); + LowLevelSpinWaiter.Wait(spinIndex, SpinSleep0Threshold, isSingleProcessor: false); } if (acquiredLock) @@ -648,14 +668,25 @@ internal nint LockIdForEvents internal ulong OwningThreadId => _owningThreadId; - private static short DetermineMaxSpinCount() => - AppContextConfigHelper.GetInt16Config( - "System.Threading.Lock.SpinCount", - "DOTNET_Lock_SpinCount", - DefaultMaxSpinCount, - allowNegative: false); + private static short DetermineMaxSpinCount() + { + if (IsSingleProcessor) + { + return 0; + } + + return + AppContextConfigHelper.GetInt16Config( + "System.Threading.Lock.SpinCount", + "DOTNET_Lock_SpinCount", + DefaultMaxSpinCount, + allowNegative: false); + } - private static short DetermineMinSpinCount() + // When the returned value is zero or negative, indicates the lowest value that the _spinCount field will have when + // adaptive spin chooses to pause spin-waiting, see the comment on the _spinCount field for more information. When the + // returned value is positive, adaptive spin is disabled. + private static short DetermineMinSpinCountForAdaptiveSpin() { // The config var can be set to -1 to disable adaptive spin short adaptiveSpinPeriod = diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs index 516fb42bf0a52e..37f8c06af04565 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; namespace System.Threading @@ -35,7 +36,7 @@ public class ManualResetEventSlim : IDisposable // These are the default spin counts we use on single-proc and MP machines. private const int DEFAULT_SPIN_SP = 1; - private volatile object? m_lock; + private object? m_lock; // A lock used for waiting and pulsing. Lazily initialized via EnsureLockObjectCreated() private volatile ManualResetEvent? m_eventObj; // A true Win32 event used for waiting. @@ -199,13 +200,13 @@ private void Initialize(bool initialState, int spinCount) /// /// Helper to ensure the lock object is created before first use. /// + [MemberNotNull(nameof(m_lock))] private void EnsureLockObjectCreated() { - if (m_lock != null) - return; - - object newObj = new object(); - Interlocked.CompareExchange(ref m_lock, newObj, null); // failure is benign. Someone else set the value. + if (m_lock is null) + { + Interlocked.CompareExchange(ref m_lock, new object(), null); // failure is benign. Someone else set the value. + } } /// @@ -538,7 +539,7 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) // We must register and unregister the token outside of the lock, to avoid deadlocks. using (cancellationToken.UnsafeRegister(s_cancellationTokenCallback, this)) { - lock (m_lock!) + lock (m_lock) { // Loop to cope with spurious wakeups from other waits being canceled while (!IsSet) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index fa03b43aff87cc..ab532be3e3da4e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -4690,6 +4690,26 @@ public static void WaitAll(params Task[] tasks) Debug.Assert(waitResult, "expected wait to succeed"); } + /// + /// Waits for all of the provided objects to complete execution. + /// + /// + /// An array of instances on which to wait. + /// + /// + /// The argument contains a null element. + /// + /// + /// At least one of the instances was canceled -or- an exception was thrown during + /// the execution of at least one of the instances. + /// + [UnsupportedOSPlatform("browser")] + public static void WaitAll(/*params*/ ReadOnlySpan tasks) + { + bool waitResult = WaitAllCore(tasks, Timeout.Infinite, default); + Debug.Assert(waitResult, "expected wait to succeed"); + } + /// /// Waits for all of the provided objects to complete execution. /// @@ -4724,7 +4744,7 @@ public static void WaitAll(params Task[] tasks) public static bool WaitAll(Task[] tasks, TimeSpan timeout) { long totalMilliseconds = (long)timeout.TotalMilliseconds; - if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) + if (totalMilliseconds is < -1 or > int.MaxValue) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.timeout); } @@ -5953,7 +5973,7 @@ public static Task WhenAll(params Task[] tasks) /// /// /// The array contained a null task. - internal static Task WhenAll(ReadOnlySpan tasks) => // TODO https://github.com/dotnet/runtime/issues/77873: Make this public. + public static Task WhenAll(/*params*/ ReadOnlySpan tasks) => tasks.Length != 0 ? new WhenAllPromise(tasks) : CompletedTask; /// A Task that gets completed when all of its constituent tasks complete. @@ -6172,7 +6192,13 @@ public static Task WhenAll(IEnumerable> tasks) // Skip a List allocation/copy if tasks is a collection if (tasks is ICollection> taskCollection) { - taskArray = new Task[taskCollection.Count]; + int count = taskCollection.Count; + if (count == 0) + { + return new Task(false, Array.Empty(), TaskCreationOptions.None, default); + } + + taskArray = new Task[count]; taskCollection.CopyTo(taskArray, 0); foreach (Task task in taskArray) { @@ -6181,20 +6207,30 @@ public static Task WhenAll(IEnumerable> tasks) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); } } - return InternalWhenAll(taskArray); + + return new WhenAllPromise(taskArray); } // Do some argument checking and convert tasks into a List (later an array) - if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); + if (tasks is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); + } + List> taskList = new List>(); foreach (Task task in tasks) { - if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); + if (task is null) + { + ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); + } + taskList.Add(task); } - // Delegate the rest to InternalWhenAll(). - return InternalWhenAll(taskList.ToArray()); + return taskList.Count == 0 ? + new Task(false, Array.Empty(), TaskCreationOptions.None, default) : + new WhenAllPromise(taskList.ToArray()); } /// @@ -6229,13 +6265,49 @@ public static Task WhenAll(IEnumerable> tasks) /// public static Task WhenAll(params Task[] tasks) { - // Do some argument checking and make a defensive copy of the tasks array - if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); + if (tasks is null) + { + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); + } - int taskCount = tasks.Length; - if (taskCount == 0) return InternalWhenAll(tasks); // small optimization in the case of an empty task array + return WhenAll((ReadOnlySpan>)tasks); + } + + /// + /// Creates a task that will complete when all of the supplied tasks have completed. + /// + /// The tasks to wait on for completion. + /// A task that represents the completion of all of the supplied tasks. + /// + /// + /// If any of the supplied tasks completes in a faulted state, the returned task will also complete in a Faulted state, + /// where its exceptions will contain the aggregation of the set of unwrapped exceptions from each of the supplied tasks. + /// + /// + /// If none of the supplied tasks faulted but at least one of them was canceled, the returned task will end in the Canceled state. + /// + /// + /// If none of the tasks faulted and none of the tasks were canceled, the resulting task will end in the RanToCompletion state. + /// The Result of the returned task will be set to an array containing all of the results of the + /// supplied tasks in the same order as they were provided (e.g. if the input tasks array contained t1, t2, t3, the output + /// task's Result will return an TResult[] where arr[0] == t1.Result, arr[1] == t2.Result, and arr[2] == t3.Result). + /// + /// + /// If the supplied array/enumerable contains no tasks, the returned task will immediately transition to a RanToCompletion + /// state before it's returned to the caller. The returned TResult[] will be an array of 0 elements. + /// + /// + /// + /// The array contained a null task. + /// + public static Task WhenAll(/*params*/ ReadOnlySpan> tasks) + { + if (tasks.IsEmpty) + { + return new Task(false, Array.Empty(), TaskCreationOptions.None, default); + } - Task[] tasksCopy = (Task[])tasks.Clone(); + Task[] tasksCopy = tasks.ToArray(); foreach (Task task in tasksCopy) { if (task is null) @@ -6244,17 +6316,7 @@ public static Task WhenAll(params Task[] tasks) } } - // Delegate the rest to InternalWhenAll() - return InternalWhenAll(tasksCopy); - } - - // Some common logic to support WhenAll methods - private static Task InternalWhenAll(Task[] tasks) - { - Debug.Assert(tasks != null, "Expected a non-null tasks array"); - return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait - new Task(false, Array.Empty(), TaskCreationOptions.None, default) : - new WhenAllPromise(tasks); + return new WhenAllPromise(tasksCopy); } // A Task that gets completed when all of its constituent tasks complete. @@ -6394,7 +6456,7 @@ public static Task WhenAny(params Task[] tasks) { ArgumentNullException.ThrowIfNull(tasks); - return WhenAny((ReadOnlySpan)tasks); + return WhenAnyCore((ReadOnlySpan)tasks); } /// @@ -6409,7 +6471,22 @@ public static Task WhenAny(params Task[] tasks) /// /// The array contained a null task, or was empty. /// - private static Task WhenAny(ReadOnlySpan tasks) where TTask : Task + public static Task WhenAny(/*params*/ ReadOnlySpan tasks) => + WhenAnyCore(tasks); + + /// + /// Creates a task that will complete when any of the supplied tasks have completed. + /// + /// The tasks to wait on for completion. + /// A task that represents the completion of one of the supplied tasks. The return Task's Result is the task that completed. + /// + /// The returned task will complete when any of the supplied tasks has completed. The returned task will always end in the RanToCompletion state + /// with its Result set to the first task to complete. This is true even if the first task to complete ended in the Canceled or Faulted state. + /// + /// + /// The array contained a null task, or was empty. + /// + private static Task WhenAnyCore(ReadOnlySpan tasks) where TTask : Task { if (tasks.Length == 2) { @@ -6589,13 +6666,13 @@ private static Task WhenAny(IEnumerable tasks) where TTask { // Take a more efficient path if tasks is actually a list or an array. Arrays are a bit less common, // since if argument was strongly-typed as an array, it would have bound to the array-based overload. - if (tasks is List tasksAsList) + if (tasks.GetType() == typeof(List)) { - return WhenAny((ReadOnlySpan)CollectionsMarshal.AsSpan(tasksAsList)); + return WhenAnyCore((ReadOnlySpan)CollectionsMarshal.AsSpan(Unsafe.As>(tasks))); } if (tasks is TTask[] tasksAsArray) { - return WhenAny((ReadOnlySpan)tasksAsArray); + return WhenAnyCore((ReadOnlySpan)tasksAsArray); } int count = tasksAsCollection.Count; @@ -6663,9 +6740,24 @@ public static Task> WhenAny(params Task[] tasks) { ArgumentNullException.ThrowIfNull(tasks); - return WhenAny((ReadOnlySpan>)tasks); + return WhenAnyCore((ReadOnlySpan>)tasks); } + /// + /// Creates a task that will complete when any of the supplied tasks have completed. + /// + /// The tasks to wait on for completion. + /// A task that represents the completion of one of the supplied tasks. The return Task's Result is the task that completed. + /// + /// The returned task will complete when any of the supplied tasks has completed. The returned task will always end in the RanToCompletion state + /// with its Result set to the first task to complete. This is true even if the first task to complete ended in the Canceled or Faulted state. + /// + /// + /// The array contained a null task, or was empty. + /// + public static Task> WhenAny(/*params*/ ReadOnlySpan> tasks) => + WhenAnyCore(tasks); + /// Creates a task that will complete when either of the supplied tasks have completed. /// The first task to wait on for completion. /// The second task to wait on for completion. diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadBlockingInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadBlockingInfo.cs new file mode 100644 index 00000000000000..6deed17e8f5dc5 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadBlockingInfo.cs @@ -0,0 +1,194 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Threading +{ + // Tracks some kinds of blocking on the thread, like waiting on locks where it may be useful to know when debugging which + // thread owns the lock. + // + // Notes: + // - The type, some fields, and some other members may be used by debuggers (noted specifically below), so take care when + // renaming them + // - There is a native version of this struct in CoreCLR, used by Monitor to fold in its blocking info here. The struct is + // blittable with sequential layout to support that. + // + // Debuggers may use this info by evaluating expressions to enumerate the blocking infos for a thread. For example: + // - Evaluate "System.Threading.ThreadBlockingInfo.t_first" to obtain the first pointer to a blocking info for the current + // thread + // - While there is a non-null pointer to a blocking info: + // - Evaluate "(*(System.Threading.ThreadBlockingInfo*)ptr).fieldOrProperty", where "ptr" is the blocking info pointer + // value, to get the field and relevant property getter values below + // - Use the _objectKind field value to determine what kind of blocking is occurring + // - Get the LockOwnerOSThreadId and LockOwnerManagedThreadId property getter values. If the blocking is waiting for a + // lock and the lock is currently owned by a thread, one of these properties will return a nonzero value that can be + // used to identify the lock owner thread. + // - Use the _next field value to obtain the next pointer to a blocking info for the thread + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct ThreadBlockingInfo + { +#if CORECLR + // In CoreCLR, for the Monitor object kinds, the object ptr will be a pointer to a native AwareLock object. This + // relative offset indicates the location of the field holding the lock owner OS thread ID (the field is of type + // size_t), and is used to get that info by the LockOwnerOSThreadId property. The offset is not zero currently, so zero + // is used to determine if the static field has been initialized. + // + // This mechanism is used instead of using an FCall in the property getter such that the property can be more easily + // evaluated by a debugger. + private static int s_monitorObjectOffsetOfLockOwnerOSThreadId; +#endif + + // Points to the first (most recent) blocking info for the thread. The _next field points to the next-most-recent + // blocking info for the thread, or null if there are no more. Blocking can be reentrant in some cases, such as on UI + // threads where reentrant waits are used, or if a SynchronizationContext wait override is set. + [ThreadStatic] + private static ThreadBlockingInfo* t_first; // may be used by debuggers + + // This pointer can be used to obtain the object relevant to the blocking. For native object kinds, it points to the + // native object (for Monitor object kinds in CoreCLR, it points to a native AwareLock object). For managed object + // kinds, it points to a stack location containing the managed object reference. + private void* _objectPtr; // may be used by debuggers + + // Indicates the type of object relevant to the blocking + private ObjectKind _objectKind; // may be used by debuggers + + // The timeout in milliseconds for the wait, -1 for infinite timeout + private int _timeoutMs; // may be used by debuggers + + // Points to the next-most-recent blocking info for the thread + private ThreadBlockingInfo* _next; // may be used by debuggers + + private void Push(void* objectPtr, ObjectKind objectKind, int timeoutMs) + { + Debug.Assert(objectPtr != null); + + _objectPtr = objectPtr; + _objectKind = objectKind; + _timeoutMs = timeoutMs; + _next = t_first; + t_first = (ThreadBlockingInfo*)Unsafe.AsPointer(ref this); + } + + private void Pop() + { + Debug.Assert(_objectPtr != null); + Debug.Assert(t_first != null); + Debug.Assert(t_first->_next == _next); + + t_first = _next; + _objectPtr = null; + } + + // If the blocking is associated with a lock of some kind that has thread affinity and tracks the owner's OS thread ID, + // returns the OS thread ID of the thread that currently owns the lock. Otherwise, returns 0. A return value of 0 may + // indicate that the associated lock is currently not owned by a thread, or that the information could not be + // determined. + // + // Calls to native helpers are avoided in the property getter such that it can be more easily evaluated by a debugger. + public ulong LockOwnerOSThreadId // the getter may be used by debuggers + { + get + { + Debug.Assert(_objectPtr != null); + + switch (_objectKind) + { + case ObjectKind.MonitorLock: + case ObjectKind.MonitorWait: + // The Monitor object kinds are only used by CoreCLR, and only the OS thread ID is reported +#if CORECLR + if (s_monitorObjectOffsetOfLockOwnerOSThreadId != 0) + { + return *(nuint*)((nint)_objectPtr + s_monitorObjectOffsetOfLockOwnerOSThreadId); + } +#endif + return 0; + + case ObjectKind.Lock: + return ((Lock)Unsafe.AsRef(_objectPtr)).OwningOSThreadId; + + default: + Debug.Assert(_objectKind == ObjectKind.Condition); +#if NATIVEAOT + return ((Condition)Unsafe.AsRef(_objectPtr)).AssociatedLock.OwningOSThreadId; +#else + return 0; +#endif + } + } + } + + // If the blocking is associated with a lock of some kind that has thread affinity and tracks the owner's managed thread + // ID, returns the managed thread ID of the thread that currently owns the lock. Otherwise, returns 0. A return value of + // 0 may indicate that the associated lock is currently not owned by a thread, or that the information could not be + // determined. + // + // Calls to native helpers are avoided in the property getter such that it can be more easily evaluated by a debugger. + public int LockOwnerManagedThreadId // the getter may be used by debuggers + { + get + { + Debug.Assert(_objectPtr != null); + + switch (_objectKind) + { + case ObjectKind.MonitorLock: + case ObjectKind.MonitorWait: + // The Monitor object kinds are only used by CoreCLR, and only the OS thread ID is reported + return 0; + + case ObjectKind.Lock: + return ((Lock)Unsafe.AsRef(_objectPtr)).OwningManagedThreadId; + + default: + Debug.Assert(_objectKind == ObjectKind.Condition); +#if NATIVEAOT + return ((Condition)Unsafe.AsRef(_objectPtr)).AssociatedLock.OwningManagedThreadId; +#else + return 0; +#endif + } + } + } + + public unsafe ref struct Scope + { + private object? _object; + private ThreadBlockingInfo _blockingInfo; + +#pragma warning disable CS9216 // casting Lock to object + public Scope(Lock lockObj, int timeoutMs) : this(lockObj, ObjectKind.Lock, timeoutMs) { } +#pragma warning restore CS9216 + +#if NATIVEAOT + public Scope(Condition condition, int timeoutMs) : this(condition, ObjectKind.Condition, timeoutMs) { } +#endif + + private Scope(object obj, ObjectKind objectKind, int timeoutMs) + { + _object = obj; + _blockingInfo.Push(Unsafe.AsPointer(ref _object), objectKind, timeoutMs); + } + + public void Dispose() + { + if (_object is not null) + { + _blockingInfo.Pop(); + _object = null; + } + } + } + + public enum ObjectKind // may be used by debuggers + { + MonitorLock, // maps to DebugBlockingItemType::DebugBlock_MonitorCriticalSection in coreclr + MonitorWait, // maps to DebugBlockingItemType::DebugBlock_MonitorEvent in coreclr + Lock, + Condition + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs index 8890cde64f70d4..aa0c2e4478ca64 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Numerics; // A class that provides a simple, lightweight implementation of thread-local lazy-initialization, where a value is initialized once per accessing // thread; this provides an alternative to using a ThreadStatic static variable and having @@ -552,40 +553,15 @@ private static int GetNewTableSize(int minSize) } Debug.Assert(minSize > 0); - // - // Round up the size to the next power of 2 - // - // The algorithm takes three steps: - // input -> subtract one -> propagate 1-bits to the right -> add one - // - // Let's take a look at the 3 steps in both interesting cases: where the input - // is (Example 1) and isn't (Example 2) a power of 2. - // - // Example 1: 100000 -> 011111 -> 011111 -> 100000 - // Example 2: 011010 -> 011001 -> 011111 -> 100000 - // - int newSize = minSize; - - // Step 1: Decrement - newSize--; - - // Step 2: Propagate 1-bits to the right. - newSize |= newSize >> 1; - newSize |= newSize >> 2; - newSize |= newSize >> 4; - newSize |= newSize >> 8; - newSize |= newSize >> 16; - - // Step 3: Increment - newSize++; + uint newSize = BitOperations.RoundUpToPowerOf2((uint)minSize); // Don't set newSize to more than Array.MaxArrayLength - if ((uint)newSize > Array.MaxLength) + if (newSize > Array.MaxLength) { - newSize = Array.MaxLength; + newSize = (uint)Array.MaxLength; } - return newSize; + return (int)newSize; } /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs index cc7c76922d9964..7eef607ef10699 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs @@ -21,23 +21,23 @@ internal sealed partial class ThreadPoolWorkQueue internal static class WorkStealingQueueList { #pragma warning disable CA1825 // avoid the extra generic instantiation for Array.Empty(); this is the only place we'll ever create this array - private static volatile WorkStealingQueue[] _queues = new WorkStealingQueue[0]; + private static WorkStealingQueue[] s_queues = new WorkStealingQueue[0]; #pragma warning restore CA1825 - public static WorkStealingQueue[] Queues => _queues; + public static WorkStealingQueue[] Queues => s_queues; public static void Add(WorkStealingQueue queue) { Debug.Assert(queue != null); while (true) { - WorkStealingQueue[] oldQueues = _queues; + WorkStealingQueue[] oldQueues = s_queues; Debug.Assert(Array.IndexOf(oldQueues, queue) < 0); var newQueues = new WorkStealingQueue[oldQueues.Length + 1]; Array.Copy(oldQueues, newQueues, oldQueues.Length); newQueues[^1] = queue; - if (Interlocked.CompareExchange(ref _queues, newQueues, oldQueues) == oldQueues) + if (Interlocked.CompareExchange(ref s_queues, newQueues, oldQueues) == oldQueues) { break; } @@ -49,7 +49,7 @@ public static void Remove(WorkStealingQueue queue) Debug.Assert(queue != null); while (true) { - WorkStealingQueue[] oldQueues = _queues; + WorkStealingQueue[] oldQueues = s_queues; if (oldQueues.Length == 0) { return; @@ -77,7 +77,7 @@ public static void Remove(WorkStealingQueue queue) Array.Copy(oldQueues, pos + 1, newQueues, pos, newQueues.Length - pos); } - if (Interlocked.CompareExchange(ref _queues, newQueues, oldQueues) == oldQueues) + if (Interlocked.CompareExchange(ref s_queues, newQueues, oldQueues) == oldQueues) { break; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 24be352778c841..7281867487a083 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -705,20 +705,12 @@ public override int GetHashCode() [Obsolete(Obsoletions.ReflectionOnlyLoadingMessage, DiagnosticId = Obsoletions.ReflectionOnlyLoadingDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public static Type? ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase) => throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); - public static Binder DefaultBinder - { - get - { - if (s_defaultBinder == null) - { - DefaultBinder binder = new DefaultBinder(); - Interlocked.CompareExchange(ref s_defaultBinder, binder, null); - } - return s_defaultBinder!; - } - } + public static Binder DefaultBinder => + s_defaultBinder ?? + Interlocked.CompareExchange(ref s_defaultBinder, new DefaultBinder(), null) ?? + s_defaultBinder; - private static volatile Binder? s_defaultBinder; + private static Binder? s_defaultBinder; public static readonly char Delimiter = '.'; public static readonly Type[] EmptyTypes = Array.Empty(); diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs index dd48ebd0d9e00f..c2588f7fde3314 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs @@ -72,7 +72,7 @@ public override SecurityRuleSet SecurityRuleSet get { return UnderlyingAssembly.SecurityRuleSet; } } -#if NETCOREAPP +#if NET [Obsolete] [RequiresAssemblyFiles] #endif @@ -91,7 +91,7 @@ public override MethodInfo? EntryPoint get { return UnderlyingAssembly.EntryPoint; } } -#if NETCOREAPP +#if NET [Obsolete] [RequiresAssemblyFiles] #endif @@ -200,7 +200,7 @@ public override Type[] GetTypes() return UnderlyingAssembly.GetTypes(); } -#if NETCOREAPP +#if NET [Obsolete] #endif public override bool GlobalAssemblyCache diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingModule.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingModule.cs index d69e26494a779c..21e19635db409f 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingModule.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingModule.cs @@ -25,7 +25,7 @@ public override Assembly Assembly internal const string UnknownStringMessageInRAF = "Returns for modules with no file path"; -#if NETCOREAPP +#if NET [RequiresAssemblyFiles(UnknownStringMessageInRAF)] #endif public override string FullyQualifiedName @@ -48,7 +48,7 @@ public override Guid ModuleVersionId get { return UnderlyingModule.ModuleVersionId; } } -#if NETCOREAPP +#if NET [RequiresAssemblyFiles(UnknownStringMessageInRAF)] #endif public override string Name diff --git a/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj b/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj index 2d021999f5869c..17c279ab521382 100644 --- a/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj +++ b/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj @@ -16,6 +16,7 @@ + diff --git a/src/libraries/System.Reflection.DispatchProxy/tests/DispatchProxyTests.cs b/src/libraries/System.Reflection.DispatchProxy/tests/DispatchProxyTests.cs index 96091763187549..df16833b724e29 100644 --- a/src/libraries/System.Reflection.DispatchProxy/tests/DispatchProxyTests.cs +++ b/src/libraries/System.Reflection.DispatchProxy/tests/DispatchProxyTests.cs @@ -557,7 +557,7 @@ public static void Proxy_Declares_Interface_Properties(bool useGenericCreate) Assert.NotNull(propertyInfo); } -#if NETCOREAPP +#if NET [Fact] public static void Invoke_Event_Add_And_Remove_And_Raise_Invokes_Correct_Methods_Generic_And_Non_Generic_Tests() { diff --git a/src/libraries/System.Reflection.DispatchProxy/tests/TrimmingTests/System.Reflection.DispatchProxy.TrimmingTests.proj b/src/libraries/System.Reflection.DispatchProxy/tests/TrimmingTests/System.Reflection.DispatchProxy.TrimmingTests.proj index da4a46f2ae141a..adb54eab7335a0 100644 --- a/src/libraries/System.Reflection.DispatchProxy/tests/TrimmingTests/System.Reflection.DispatchProxy.TrimmingTests.proj +++ b/src/libraries/System.Reflection.DispatchProxy/tests/TrimmingTests/System.Reflection.DispatchProxy.TrimmingTests.proj @@ -1,5 +1,12 @@ + + + + true + + + diff --git a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs index d656738565288c..6eaf4ea70e61ee 100644 --- a/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs +++ b/src/libraries/System.Reflection.Metadata/ref/System.Reflection.Metadata.cs @@ -2408,6 +2408,49 @@ public readonly partial struct TypeLayout public int PackingSize { get { throw null; } } public int Size { get { throw null; } } } + public sealed partial class AssemblyNameInfo + { + public AssemblyNameInfo(string name, System.Version? version = null, string? cultureName = null, System.Reflection.AssemblyNameFlags flags = AssemblyNameFlags.None, + Collections.Immutable.ImmutableArray publicKeyOrToken = default) { } + public string Name { get { throw null; } } + public string? CultureName { get { throw null; } } + public string FullName { get { throw null; } } + public System.Version? Version { get { throw null; } } + public System.Reflection.AssemblyNameFlags Flags { get { throw null; } } + public System.Collections.Immutable.ImmutableArray PublicKeyOrToken { get { throw null; } } + public static System.Reflection.Metadata.AssemblyNameInfo Parse(System.ReadOnlySpan assemblyName) { throw null; } + public static bool TryParse(System.ReadOnlySpan assemblyName, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Reflection.Metadata.AssemblyNameInfo? result) { throw null; } + public System.Reflection.AssemblyName ToAssemblyName() { throw null; } + } + public sealed partial class TypeName + { + internal TypeName() { } + public string AssemblyQualifiedName { get { throw null; } } + public AssemblyNameInfo? AssemblyName { get { throw null; } } + public System.Reflection.Metadata.TypeName? DeclaringType { get { throw null; } } + public string FullName { get { throw null; } } + public bool IsArray { get { throw null; } } + public bool IsByRef { get { throw null; } } + public bool IsConstructedGenericType { get { throw null; } } + public bool IsNested { get { throw null; } } + public bool IsPointer { get { throw null; } } + public bool IsSimple { get { throw null; } } + public bool IsSZArray { get { throw null; } } + public bool IsVariableBoundArrayType { get { throw null; } } + public string Name { get { throw null; } } + public static System.Reflection.Metadata.TypeName Parse(System.ReadOnlySpan typeName, System.Reflection.Metadata.TypeNameParseOptions? options = null) { throw null; } + public static bool TryParse(System.ReadOnlySpan typeName, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Reflection.Metadata.TypeName? result, System.Reflection.Metadata.TypeNameParseOptions? options = null) { throw null; } + public int GetArrayRank() { throw null; } + public System.Collections.Immutable.ImmutableArray GetGenericArguments() { throw null; } + public System.Reflection.Metadata.TypeName GetGenericTypeDefinition() { throw null; } + public System.Reflection.Metadata.TypeName GetElementType() { throw null; } + public int GetNodeCount() { throw null; } + } + public sealed partial class TypeNameParseOptions + { + public TypeNameParseOptions() { } + public int MaxNodes { get { throw null; } set { } } + } public readonly partial struct TypeReference { private readonly object _dummy; diff --git a/src/libraries/System.Reflection.Metadata/src/Resources/Strings.resx b/src/libraries/System.Reflection.Metadata/src/Resources/Strings.resx index c035a3efee098f..963e4d0af9f8a3 100644 --- a/src/libraries/System.Reflection.Metadata/src/Resources/Strings.resx +++ b/src/libraries/System.Reflection.Metadata/src/Resources/Strings.resx @@ -411,4 +411,25 @@ The SwitchInstructionEncoder.Branch method was invoked too many times. + + The name of the type is invalid. + + + Maximum node count of {0} exceeded. + + + Must be an array type. + + + This operation is only valid on generic types. + + + This operation is only valid on nested types. + + + This operation is only valid on arrays, pointers and references. + + + The given assembly name was invalid. + \ No newline at end of file diff --git a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj index e713d6210651f9..266d4c6f55fddd 100644 --- a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj +++ b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj @@ -16,6 +16,7 @@ The System.Reflection.Metadata library is built-in as part of the shared framewo $(DefineConstants);FEATURE_CER + $(DefineConstants);SYSTEM_REFLECTION_METADATA @@ -250,7 +251,17 @@ The System.Reflection.Metadata library is built-in as part of the shared framewo + + + + + + + + + + diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs index 7ad3c4aba6e618..43e7f2aad0f6e5 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -#if NETCOREAPP +#if NET using System.Numerics; #endif @@ -17,7 +17,7 @@ internal static int CountBits(int v) internal static int CountBits(uint v) { -#if NETCOREAPP +#if NET return BitOperations.PopCount(v); #else unchecked @@ -31,7 +31,7 @@ internal static int CountBits(uint v) internal static int CountBits(ulong v) { -#if NETCOREAPP +#if NET return BitOperations.PopCount(v); #else const ulong Mask01010101 = 0x5555555555555555UL; diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs index 843e95e616d34b..462d2408b1d3e1 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs @@ -20,7 +20,7 @@ public static void WriteBytes(this byte[] buffer, int start, byte value, int byt public static void WriteDouble(this byte[] buffer, int start, double value) { -#if NETCOREAPP +#if NET WriteUInt64(buffer, start, BitConverter.DoubleToUInt64Bits(value)); #else WriteUInt64(buffer, start, *(ulong*)&value); @@ -29,7 +29,7 @@ public static void WriteDouble(this byte[] buffer, int start, double value) public static void WriteSingle(this byte[] buffer, int start, float value) { -#if NETCOREAPP +#if NET WriteUInt32(buffer, start, BitConverter.SingleToUInt32Bits(value)); #else WriteUInt32(buffer, start, *(uint*)&value); @@ -76,7 +76,7 @@ public static void WriteDecimal(this byte[] buffer, int start, decimal value) public static void WriteGuid(this byte[] buffer, int start, Guid value) { -#if NETCOREAPP +#if NET bool written = value.TryWriteBytes(buffer.AsSpan(start)); // This function is not public, callers have to ensure that enough space is available. Debug.Assert(written); diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/DecimalUtilities.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/DecimalUtilities.cs index 3733a4b45a5a0e..be69480203e924 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/DecimalUtilities.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/DecimalUtilities.cs @@ -7,7 +7,7 @@ internal static class DecimalUtilities { public static int GetScale(this decimal value) { -#if NETCOREAPP +#if NET Span bits = stackalloc int[4]; decimal.GetBits(value, bits); return unchecked((byte)(bits[3] >> 16)); @@ -18,7 +18,7 @@ public static int GetScale(this decimal value) public static void GetBits(this decimal value, out bool isNegative, out byte scale, out uint low, out uint mid, out uint high) { -#if NETCOREAPP +#if NET Span bits = stackalloc int[4]; decimal.GetBits(value, bits); #else diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableMemoryStream.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableMemoryStream.cs index 26dc9290ab4e6f..fe94886ac859d9 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableMemoryStream.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ImmutableMemoryStream.cs @@ -72,7 +72,7 @@ public override int Read(byte[] buffer, int offset, int count) return result; } -#if NETCOREAPP +#if NET // Duplicate the Read(byte[]) logic here instead of refactoring both to use Spans // so we don't affect perf on .NET Framework. public override int Read(Span buffer) diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs index 2a31a96a154058..b3fe0044c43c92 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs @@ -36,7 +36,7 @@ public override int Read(byte[] buffer, int offset, int count) return bytesRead; } -#if NETCOREAPP +#if NET // Duplicate the Read(byte[]) logic here instead of refactoring both to use Spans // so we don't affect perf on .NET Framework. public override int Read(Span buffer) diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/StreamExtensions.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/StreamExtensions.cs index bb52925254c277..484f138762fe41 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/StreamExtensions.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/StreamExtensions.cs @@ -76,9 +76,9 @@ internal static int TryReadAll(this Stream stream, byte[] buffer, int offset, in return totalBytesRead; } -#if NETCOREAPP +#if NET internal static int TryReadAll(this Stream stream, Span buffer) -#if NET7_0_OR_GREATER +#if NET => stream.ReadAtLeast(buffer, buffer.Length, throwOnEndOfStream: false); #else { diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEHeaderBuilder.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEHeaderBuilder.cs index f93b8bc0716de8..9ddb82d35aa4e3 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEHeaderBuilder.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEHeaderBuilder.cs @@ -105,7 +105,7 @@ public static PEHeaderBuilder CreateLibraryHeader() return new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll); } - internal bool Is32Bit => Machine != Machine.Amd64 && Machine != Machine.IA64 && Machine != Machine.Arm64 && Machine != Machine.RiscV64; + internal bool Is32Bit => Machine != Machine.Amd64 && Machine != Machine.IA64 && Machine != Machine.Arm64 && Machine != Machine.LoongArch64 && Machine != Machine.RiscV64; internal int ComputeSizeOfPEHeaders(int sectionCount) => PEBuilder.DosHeaderSize + diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs index 51eff57e43c03f..e9d3b25e95af50 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs @@ -99,7 +99,7 @@ internal static unsafe NativeHeapMemoryBlock DecodeEmbeddedPortablePdbDebugDirec try { -#if NETCOREAPP +#if NET actualLength = deflate.TryReadAll(new Span(decompressed.Pointer, decompressed.Size)); #else using var decompressedStream = new UnmanagedMemoryStream(decompressed.Pointer, decompressed.Size, decompressed.Size, FileAccess.Write); diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/AssemblyNameInfoTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/AssemblyNameInfoTests.cs new file mode 100644 index 00000000000000..230e051ab045cb --- /dev/null +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/AssemblyNameInfoTests.cs @@ -0,0 +1,105 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Reflection.Metadata.Tests.Metadata +{ + public class AssemblyNameInfoTests + { + [Theory] + [InlineData("MyAssemblyName, Version=1.0.0.0, PublicKeyToken=b77a5c561934e089")] + public void WithPublicTokenKey(string fullName) + { + AssemblyName assemblyName = new AssemblyName(fullName); + + AssemblyNameInfo assemblyNameInfo = AssemblyNameInfo.Parse(fullName.AsSpan()); + + Assert.Equal(fullName, assemblyName.FullName); + Assert.Equal(fullName, assemblyNameInfo.FullName); + + Roundtrip(assemblyName); + } + + [Fact] + public void NoPublicKeyOrToken() + { + AssemblyName source = new AssemblyName(); + source.Name = "test"; + source.Version = new Version(1, 2, 3, 4); + source.CultureName = "en-US"; + + Roundtrip(source); + } + + [Theory] + [InlineData(ProcessorArchitecture.MSIL)] + [InlineData(ProcessorArchitecture.X86)] + [InlineData(ProcessorArchitecture.IA64)] + [InlineData(ProcessorArchitecture.Amd64)] + [InlineData(ProcessorArchitecture.Arm)] + public void ProcessorArchitectureIsPropagated(ProcessorArchitecture architecture) + { + string input = $"Abc, ProcessorArchitecture={architecture}"; + AssemblyNameInfo assemblyNameInfo = AssemblyNameInfo.Parse(input.AsSpan()); + + AssemblyName assemblyName = assemblyNameInfo.ToAssemblyName(); + + Assert.Equal(architecture, assemblyName.ProcessorArchitecture); + Assert.Equal(AssemblyContentType.Default, assemblyName.ContentType); + // By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture. + Assert.Equal(assemblyName.FullName, assemblyNameInfo.FullName); + Assert.DoesNotContain("ProcessorArchitecture", assemblyNameInfo.FullName); + } + + [Fact] + public void AssemblyContentTypeIsPropagated() + { + const string input = "Abc, ContentType=WindowsRuntime"; + AssemblyNameInfo assemblyNameInfo = AssemblyNameInfo.Parse(input.AsSpan()); + + AssemblyName assemblyName = assemblyNameInfo.ToAssemblyName(); + + Assert.Equal(AssemblyContentType.WindowsRuntime, assemblyName.ContentType); + Assert.Equal(ProcessorArchitecture.None, assemblyName.ProcessorArchitecture); + Assert.Equal(input, assemblyNameInfo.FullName); + Assert.Equal(assemblyName.FullName, assemblyNameInfo.FullName); + } + + [Fact] + public void RetargetableIsPropagated() + { + const string input = "Abc, Retargetable=Yes"; + AssemblyNameInfo assemblyNameInfo = AssemblyNameInfo.Parse(input.AsSpan()); + Assert.True((assemblyNameInfo.Flags & AssemblyNameFlags.Retargetable) != 0); + + AssemblyName assemblyName = assemblyNameInfo.ToAssemblyName(); + + Assert.True((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0); + Assert.Equal(AssemblyContentType.Default, assemblyName.ContentType); + Assert.Equal(ProcessorArchitecture.None, assemblyName.ProcessorArchitecture); + Assert.Equal(input, assemblyNameInfo.FullName); + Assert.Equal(assemblyName.FullName, assemblyNameInfo.FullName); + } + + [Fact] + public void EscapedSquareBracketIsNotAllowedInTheName() + => Assert.False(AssemblyNameInfo.TryParse("Esc\\[aped".AsSpan(), out _)); + + static void Roundtrip(AssemblyName source) + { + AssemblyNameInfo parsed = AssemblyNameInfo.Parse(source.FullName.AsSpan()); + Assert.Equal(source.Name, parsed.Name); + Assert.Equal(source.Version, parsed.Version); + Assert.Equal(source.CultureName, parsed.CultureName); + Assert.Equal(source.FullName, parsed.FullName); + + AssemblyName fromParsed = parsed.ToAssemblyName(); + Assert.Equal(source.Name, fromParsed.Name); + Assert.Equal(source.Version, fromParsed.Version); + Assert.Equal(source.CultureName, fromParsed.CultureName); + Assert.Equal(source.FullName, fromParsed.FullName); + Assert.Equal(source.GetPublicKeyToken(), fromParsed.GetPublicKeyToken()); + } + } +} diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs index 62944bef46d208..b697f7fadab38d 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/Decoding/CustomAttributeDecoderTests.cs @@ -197,7 +197,7 @@ public void TestCustomAttributeDecoderUsingReflection() } } -#if NETCOREAPP && !TARGET_BROWSER // Generic attribute is not supported on .NET Framework. +#if NET && !TARGET_BROWSER // Generic attribute is not supported on .NET Framework. [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] [ActiveIssue("https://github.com/dotnet/runtime/issues/60579", TestPlatforms.iOS | TestPlatforms.tvOS)] public void TestCustomAttributeDecoderGenericUsingReflection() diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs new file mode 100644 index 00000000000000..b9d23a2be15244 --- /dev/null +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs @@ -0,0 +1,173 @@ +// 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.Collections.Immutable; +using System.Linq; +using System.Text; +using Xunit; + +namespace System.Reflection.Metadata.Tests +{ + public class TypeNameParserHelpersTests + { + [Theory] + [InlineData("A[]", 1, false)] + [InlineData("AB[a,b]", 2, false)] + [InlineData("AB[[a, b],[c,d]]", 2, false)] + [InlineData("12]]", 2, false)] + [InlineData("ABC&", 3, false)] + [InlineData("ABCD*", 4, false)] + [InlineData("ABCDE,otherType]]", 5, false)] + [InlineData("Containing+Nested", 10, true)] + [InlineData("NoSpecial.Characters", 20, false)] + [InlineData("Requires\\+Escaping", 18, false)] + [InlineData("Requires\\[Escaping+Nested", 18, true)] + [InlineData("Worst\\[\\]\\&\\*\\,\\+Case", 21, false)] + [InlineData("EscapingSthThatShouldNotBeEscaped\\A", -1 , false)] + [InlineData("EndsWithEscaping\\", -1, false)] + public void GetFullTypeNameLengthReturnsExpectedValue(string input, int expected, bool expectedIsNested) + { + Assert.Equal(expected, TypeNameParserHelpers.GetFullTypeNameLength(input.AsSpan(), out bool isNested)); + Assert.Equal(expectedIsNested, isNested); + + string withNamespace = $"Namespace1.Namespace2.Namespace3.{input}"; + int expectedWithNamespace = expected < 0 ? expected : expected + withNamespace.Length - input.Length; + Assert.Equal(expectedWithNamespace, TypeNameParserHelpers.GetFullTypeNameLength(withNamespace.AsSpan(), out isNested)); + Assert.Equal(expectedIsNested, isNested); + } + + [Theory] + [InlineData("JustTypeName", "JustTypeName")] + [InlineData("Namespace.TypeName", "TypeName")] + [InlineData("Namespace1.Namespace2.TypeName", "TypeName")] + [InlineData("Namespace.NotNamespace\\.TypeName", "NotNamespace\\.TypeName")] + [InlineData("Namespace1.Namespace2.Containing+Nested", "Nested")] + [InlineData("Namespace1.Namespace2.Not\\+Nested", "Not\\+Nested")] + [InlineData("NotNamespace1\\.NotNamespace2\\.TypeName", "NotNamespace1\\.NotNamespace2\\.TypeName")] + [InlineData("NotNamespace1\\.NotNamespace2\\.Not\\+Nested", "NotNamespace1\\.NotNamespace2\\.Not\\+Nested")] + public void GetNameReturnsJustName(string fullName, string expected) + => Assert.Equal(expected, TypeNameParserHelpers.GetName(fullName.AsSpan()).ToString()); + + [Theory] + [InlineData("simple", "simple")] + [InlineData("simple]", "simple")] + [InlineData("esc\\]aped", "esc\\]aped")] + [InlineData("esc\\]aped]", "esc\\]aped")] + public void GetAssemblyNameCandidateReturnsExpectedValue(string input, string expected) + => Assert.Equal(expected, TypeNameParserHelpers.GetAssemblyNameCandidate(input.AsSpan()).ToString()); + + [Theory] + [InlineData(TypeNameParserHelpers.SZArray, "[]")] + [InlineData(TypeNameParserHelpers.Pointer, "*")] + [InlineData(TypeNameParserHelpers.ByRef, "&")] + [InlineData(1, "[*]")] + [InlineData(2, "[,]")] + [InlineData(3, "[,,]")] + [InlineData(4, "[,,,]")] + public void AppendRankOrModifierStringRepresentationAppendsExpectedString(int input, string expected) + { + ValueStringBuilder builder = new ValueStringBuilder(initialCapacity: 10); + Assert.Equal(expected, TypeNameParserHelpers.GetRankOrModifierStringRepresentation(input, ref builder)); + } + + [Theory] + [InlineData(typeof(List))] + [InlineData(typeof(int?))] + [InlineData(typeof(List))] + [InlineData(typeof(Dictionary))] + [InlineData(typeof(ValueTuple))] + [InlineData(typeof(ValueTuple))] + public void GetGenericTypeFullNameReturnsSameStringAsTypeAPI(Type genericType) + { + TypeName openGenericTypeName = TypeName.Parse(genericType.GetGenericTypeDefinition().FullName.AsSpan()); + ReadOnlySpan genericArgNames = genericType.GetGenericArguments().Select(arg => TypeName.Parse(arg.AssemblyQualifiedName.AsSpan())).ToArray(); + + Assert.Equal(genericType.FullName, TypeNameParserHelpers.GetGenericTypeFullName(openGenericTypeName.FullName.AsSpan(), genericArgNames)); + } + + [Theory] + [InlineData("", false, false, "")] + [InlineData("[", false, false, "[")] // too little to be able to tell + [InlineData("[[", true, true, "")] + [InlineData("[[A],[B]]", true, true, "A],[B]]")] + [InlineData("[ [ A],[B]]", true, true, "A],[B]]")] + [InlineData("[\t[\t \r\nA],[B]]", true, true, "A],[B]]")] // whitespaces other than ' ' + [InlineData("[A,B]", true, false, "A,B]")] + [InlineData("[ A,B]", true, false, "A,B]")] + [InlineData("[]", false, false, "[]")] + [InlineData("[*]", false, false, "[*]")] + [InlineData("[,]", false, false, "[,]")] + [InlineData("[,,]", false, false, "[,,]")] + public void IsBeginningOfGenericAgsHandlesAllCasesProperly(string input, bool expectedResult, bool expectedDoubleBrackets, string expectedConsumedInput) + { + ReadOnlySpan inputSpan = input.AsSpan(); + + Assert.Equal(expectedResult, TypeNameParserHelpers.IsBeginningOfGenericArgs(ref inputSpan, out bool doubleBrackets)); + Assert.Equal(expectedDoubleBrackets, doubleBrackets); + Assert.Equal(expectedConsumedInput, inputSpan.ToString()); + } + + [Theory] + [InlineData("A.B.C", true, null, 5)] + [InlineData("A.B.C\\", false, null, 0)] // invalid type name: ends with escape character + [InlineData("A.B.C\\DoeNotNeedEscaping", false, null, 0)] // invalid type name: escapes non-special character + [InlineData("A.B+C", true, new int[] { 3 }, 5)] + [InlineData("A.B++C", false, null, 0)] // invalid type name: two following, unescaped + + [InlineData("A.B`1", true, null, 5)] + [InlineData("A+B`1+C1`2+DD2`3+E", true, new int[] { 1, 3, 4, 5 }, 18)] + [InlineData("Integer`2147483646+NoOverflow`1", true, new int[] { 18 }, 31)] + [InlineData("Integer`2147483647+Overflow`1", true, new int[] { 18 }, 29)] + public void TryGetTypeNameInfoGetsAllTheInfo(string input, bool expectedResult, int[] expectedNestedNameLengths, int expectedTotalLength) + { + List? nestedNameLengths = null; + ReadOnlySpan span = input.AsSpan(); + bool result = TypeNameParserHelpers.TryGetTypeNameInfo(ref span, ref nestedNameLengths, out int totalLength); + + Assert.Equal(expectedResult, result); + + if (expectedResult) + { + Assert.Equal(expectedNestedNameLengths, nestedNameLengths?.ToArray()); + Assert.Equal(expectedTotalLength, totalLength); + } + } + + [Theory] + [InlineData("*", true, TypeNameParserHelpers.Pointer, "")] + [InlineData(" *", false, default(int), " *")] // Whitespace cannot precede the decorator + [InlineData("* *", true, TypeNameParserHelpers.Pointer, "*")] // but it can follow the decorator. + [InlineData("&", true, TypeNameParserHelpers.ByRef, "")] + [InlineData("\t&", false, default(int), "\t&")] + [InlineData("&\t\r\n[]", true, TypeNameParserHelpers.ByRef, "[]")] + [InlineData("[]", true, TypeNameParserHelpers.SZArray, "")] + [InlineData("\r\n[]", false, default(int), "\r\n[]")] + [InlineData("[] []", true, TypeNameParserHelpers.SZArray, "[]")] + [InlineData("[,]", true, 2, "")] + [InlineData(" [,,,]", false, default(int), " [,,,]")] + [InlineData("[,,,,] *[]", true, 5, "*[]")] + public void TryParseNextDecoratorParsesTheDecoratorAndConsumesFollowingWhitespaces( + string input, bool expectedResult, int expectedModifier, string expectedConsumedInput) + { + ReadOnlySpan inputSpan = input.AsSpan(); + + Assert.Equal(expectedResult, TypeNameParserHelpers.TryParseNextDecorator(ref inputSpan, out int parsedModifier)); + Assert.Equal(expectedModifier, parsedModifier); + Assert.Equal(expectedConsumedInput, inputSpan.ToString()); + } + + [Theory] + [InlineData(" , ", ',', false, " , ")] // it can not start with a whitespace + [InlineData("AB", ',', false, "AB")] // does not start with given character + [InlineData(", ", ',', true, "")] // trimming + [InlineData(",[AB]", ',', true, "[AB]")] // nothing to trim + public void TryStripFirstCharAndTrailingSpacesWorksAsExpected( + string input, char argument, bool expectedResult, string expectedConsumedInput) + { + ReadOnlySpan inputSpan = input.AsSpan(); + + Assert.Equal(expectedResult, TypeNameParserHelpers.TryStripFirstCharAndTrailingSpaces(ref inputSpan, argument)); + Assert.Equal(expectedConsumedInput, inputSpan.ToString()); + } + } +} diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserSamples.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserSamples.cs new file mode 100644 index 00000000000000..0c48cdc2641d97 --- /dev/null +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserSamples.cs @@ -0,0 +1,255 @@ +// 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.Collections.Immutable; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using Xunit; + +namespace System.Reflection.Metadata.Tests +{ + public class TypeNameParserSamples + { + internal sealed class SampleSerializationBinder : SerializationBinder + { + private static TypeNameParseOptions _options; + + // we could use Frozen collections here ;) + private readonly static Dictionary _alwaysAllowed = new() + { + { typeof(string).FullName, typeof(string) }, + { typeof(int).FullName, typeof(int) }, + { typeof(uint).FullName, typeof(uint) }, + { typeof(long).FullName, typeof(long) }, + { typeof(ulong).FullName, typeof(ulong) }, + { typeof(double).FullName, typeof(double) }, + { typeof(float).FullName, typeof(float) }, + { typeof(bool).FullName, typeof(bool) }, + { typeof(short).FullName, typeof(short) }, + { typeof(ushort).FullName, typeof(ushort) }, + { typeof(byte).FullName, typeof(byte) }, + { typeof(char).FullName, typeof(char) }, + { typeof(DateTime).FullName, typeof(DateTime) }, + { typeof(TimeSpan).FullName, typeof(TimeSpan) }, + { typeof(Guid).FullName, typeof(Guid) }, + { typeof(Uri).FullName, typeof(Uri) }, + { typeof(DateTimeOffset).FullName, typeof(DateTimeOffset) }, + { typeof(Version).FullName, typeof(Version) }, + { typeof(Nullable).FullName, typeof(Nullable) }, // Nullable is generic! + }; + + private readonly Dictionary? _userDefined; + + public SampleSerializationBinder(Type[]? allowedTypes = null) + => _userDefined = allowedTypes?.ToDictionary(type => type.FullName); + + public override Type? BindToType(string assemblyName, string typeName) + { + // Fast path for common primitive type names and user-defined type names + // that use the same syntax and casing as System.Type.FullName API. + if (TryGetTypeFromFullName(typeName, out Type type)) + { + return type; + } + + _options ??= new TypeNameParseOptions() // there is no need for lazy initialization, I just wanted to have everything important in one method + { + // To prevent from unbounded recursion, we set the max depth for parser options. + // By ensuring that the max depth limit is enforced, we can safely use recursion in + // GetTypeFromParsedTypeName to get arrays of arrays and generics of generics. + MaxNodes = 10 + }; + + if (!TypeName.TryParse(typeName.AsSpan(), out TypeName parsed, _options)) + { + // we can throw any exception, log the information etc + throw new InvalidOperationException($"Invalid type name: '{typeName}'"); + } + + if (parsed.AssemblyName is not null) + { + // The attackers may create such a payload, + // where "typeName" passed to BindToType contains the assembly name + // and "assemblyName" passed to this method contains something else + // (some garbage or a different assembly name). Example: + // typeName: System.Int32, MyHackyDll.dll + // assemblyName: mscorlib.dll + throw new InvalidOperationException($"Type name '{typeName}' contained assembly name."); + } + + return GetTypeFromParsedTypeName(parsed); + } + + private Type? GetTypeFromParsedTypeName(TypeName parsed) + { + if (TryGetTypeFromFullName(parsed.FullName, out Type type)) + { + return type; + } + else if (parsed.IsArray) + { + TypeName arrayElementTypeName = parsed.GetElementType(); + Type arrayElementType = GetTypeFromParsedTypeName(arrayElementTypeName); // recursive call allows for creating arrays of arrays etc + + return parsed.IsSZArray + ? arrayElementType.MakeArrayType() + : arrayElementType.MakeArrayType(parsed.GetArrayRank()); + } + else if (parsed.IsConstructedGenericType) + { + TypeName genericTypeDefinitionName = parsed.GetGenericTypeDefinition(); + Type genericTypeDefinition = GetTypeFromParsedTypeName(genericTypeDefinitionName); + Debug.Assert(genericTypeDefinition.IsGenericTypeDefinition); + + ImmutableArray genericArgs = parsed.GetGenericArguments(); + Type[] typeArguments = new Type[genericArgs.Length]; + for (int i = 0; i < genericArgs.Length; i++) + { + typeArguments[i] = GetTypeFromParsedTypeName(genericArgs[i]); // recursive call allows for generics of generics like "List" + } + return genericTypeDefinition.MakeGenericType(typeArguments); + } + + throw new ArgumentException($"{parsed.FullName} is not on the allow list."); + } + + private bool TryGetTypeFromFullName(string fullName, out Type? type) + => _alwaysAllowed.TryGetValue(fullName, out type) + || (_userDefined is not null && _userDefined.TryGetValue(fullName, out type)); + } + + [Serializable] + public class CustomUserDefinedType + { + public int Integer { get; set; } + public string Text { get; set; } + public List ListOfDates { get; set; } + public CustomUserDefinedType[] ArrayOfCustomUserDefinedTypes { get; set; } + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] + public void CanDeserializeCustomUserDefinedType() + { + CustomUserDefinedType parent = new() + { + Integer = 1, + Text = "parent", + ListOfDates = new List() + { + DateTime.Parse("02/06/2024") + }, + ArrayOfCustomUserDefinedTypes = new [] + { + new CustomUserDefinedType() + { + Integer = 2, + Text = "child" + } + } + }; + SampleSerializationBinder binder = new( + allowedTypes: + [ + typeof(CustomUserDefinedType), + typeof(List<>) // using List would require using type forwarding info in dictionary + ]); + + CustomUserDefinedType deserialized = SerializeDeserialize(parent, binder); + + Assert.Equal(parent.Integer, deserialized.Integer); + Assert.Equal(parent.Text, deserialized.Text); + Assert.Equal(parent.ListOfDates.Count, deserialized.ListOfDates.Count); + for (int i = 0; i < deserialized.ListOfDates.Count; i++) + { + Assert.Equal(parent.ListOfDates[i], deserialized.ListOfDates[i]); + } + Assert.Equal(parent.ArrayOfCustomUserDefinedTypes.Length, deserialized.ArrayOfCustomUserDefinedTypes.Length); + for (int i = 0; i < deserialized.ArrayOfCustomUserDefinedTypes.Length; i++) + { + Assert.Equal(parent.ArrayOfCustomUserDefinedTypes[i].Integer, deserialized.ArrayOfCustomUserDefinedTypes[i].Integer); + Assert.Equal(parent.ArrayOfCustomUserDefinedTypes[i].Text, deserialized.ArrayOfCustomUserDefinedTypes[i].Text); + } + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] + public void CanDeserializeDictionaryUsingNonPublicComparerType() + { + Dictionary dictionary = new(StringComparer.CurrentCulture) + { + { "test", 1 } + }; + SampleSerializationBinder binder = new( + allowedTypes: + [ + typeof(Dictionary<,>), // this could be Dictionary to be more strict + StringComparer.CurrentCulture.GetType(), // this type is not public, this is all this test is about + typeof(Globalization.CompareOptions), + typeof(Globalization.CompareInfo), + typeof(KeyValuePair<,>), // this could be KeyValuePair to be more strict + ]); + + Dictionary deserialized = SerializeDeserialize(dictionary, binder); + + Assert.Equal(dictionary, deserialized); + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] + public void CanDeserializeArraysOfArrays() + { + int[][] arrayOfArrays = new int[10][]; + for (int i = 0; i < arrayOfArrays.Length; i++) + { + arrayOfArrays[i] = Enumerable.Repeat(i, 10).ToArray(); + } + + SampleSerializationBinder binder = new(); + int[][] deserialized = SerializeDeserialize(arrayOfArrays, binder); + + Assert.Equal(arrayOfArrays.Length, deserialized.Length); + for (int i = 0; i < arrayOfArrays.Length; i++) + { + Assert.Equal(arrayOfArrays[i], deserialized[i]); + } + } + + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))] + public void CanDeserializeListOfListOfInt() + { + List> listOfListOfInts = new(10); + for (int i = 0; i < listOfListOfInts.Count; i++) + { + listOfListOfInts[i] = Enumerable.Repeat(i, 10).ToList(); + } + + SampleSerializationBinder binder = new(allowedTypes: + [ + typeof(List<>) + ]); + List> deserialized = SerializeDeserialize(listOfListOfInts, binder); + + Assert.Equal(listOfListOfInts.Count, deserialized.Count); + for (int i = 0; i < listOfListOfInts.Count; i++) + { + Assert.Equal(listOfListOfInts[i], deserialized[i]); + } + } + + static T SerializeDeserialize(T instance, SerializationBinder binder) + { + using MemoryStream bfStream = new(); + BinaryFormatter bf = new() + { + Binder = binder + }; + + bf.Serialize(bfStream, instance); + bfStream.Position = 0; + + return (T)bf.Deserialize(bfStream); + } + } +} diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs new file mode 100644 index 00000000000000..a5e22b5d6c503b --- /dev/null +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs @@ -0,0 +1,748 @@ +// 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.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection.Emit; +using Xunit; + +namespace System.Reflection.Metadata.Tests +{ + public class TypeNameTests + { + [Theory] + [InlineData(" System.Int32", "System.Int32", "Int32")] + [InlineData(" MyNamespace.MyType+NestedType", "MyNamespace.MyType+NestedType", "NestedType")] + public void SpacesAtTheBeginningAreOK(string input, string expectedFullName, string expectedName) + { + TypeName parsed = TypeName.Parse(input.AsSpan()); + + Assert.Equal(expectedName, parsed.Name); + Assert.Equal(expectedFullName, parsed.FullName); + Assert.Equal(expectedFullName, parsed.AssemblyQualifiedName); + } + + [Fact] + public void LeadingDotIsNotConsumedForFullTypeNamesWithoutNamespace() + { + // This is true only for the public API. + // The internal CoreLib implementation consumes the leading dot for backward compat. + TypeName parsed = TypeName.Parse(".NoNamespace".AsSpan()); + + Assert.Equal("NoNamespace", parsed.Name); + Assert.Equal(".NoNamespace", parsed.FullName); + Assert.Equal(".NoNamespace", parsed.AssemblyQualifiedName); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData(" ")] + public void EmptyStringsAreNotAllowed(string input) + { + Assert.Throws(() => TypeName.Parse(input.AsSpan())); + + Assert.False(TypeName.TryParse(input.AsSpan(), out _)); + } + + [Theory] + [InlineData("Namespace.Containing++Nested")] // a pair of '++' + [InlineData("TypeNameFollowedBySome[] unconsumedCharacters")] + [InlineData("MissingAssemblyName, ")] + [InlineData("ExtraComma, ,")] + [InlineData("ExtraComma, , System.Runtime")] + [InlineData("UsingGenericSyntaxButNotProvidingGenericArgs[[]]")] + [InlineData("ExtraCommaAfterFirstGenericArg`1[[type1, assembly1],]")] + [InlineData("MissingClosingSquareBrackets`1[[type1, assembly1")] // missing ]] + [InlineData("MissingClosingSquareBracket`1[[type1, assembly1]")] // missing ] + [InlineData("MissingClosingSquareBracketsMixedMode`2[[type1, assembly1], type2")] // missing ] + [InlineData("MissingClosingSquareBrackets`2[[type1, assembly1], [type2, assembly2")] // missing ] + [InlineData("MissingClosingSquareBracketsMixedMode`2[type1, [type2, assembly2")] // missing ]] + [InlineData("MissingClosingSquareBracketsMixedMode`2[type1, [type2, assembly2]")] // missing ] + [InlineData("EscapeCharacterAtTheEnd\\")] + [InlineData("EscapeNonSpecialChar\\a")] + [InlineData("EscapeNonSpecialChar\\0")] + [InlineData("DoubleNestingChar++Bla")] + public void InvalidTypeNamesAreNotAllowed(string input) + { + Assert.Throws(() => TypeName.Parse(input.AsSpan())); + + Assert.False(TypeName.TryParse(input.AsSpan(), out _)); + } + + [Theory] + [InlineData("System.Int32&&")] // by-ref to by-ref is currently not supported by CLR + [InlineData("System.Int32[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]")] // more than max array rank (32) + public void ParserIsNotEnforcingRuntimeSpecificRules(string input) + { + Assert.True(TypeName.TryParse(input.AsSpan(), out _)); + + if (PlatformDetection.IsNotMonoRuntime) // https://github.com/dotnet/runtime/issues/45033 + { +#if NET + Assert.Throws(() => Type.GetType(input)); +#endif + } + } + + [Theory] + [InlineData("Namespace.Kość", "Namespace.Kość")] + public void UnicodeCharactersAreAllowedByDefault(string input, string expectedFullName) + => Assert.Equal(expectedFullName, TypeName.Parse(input.AsSpan()).FullName); + + [Theory] + [InlineData(typeof(int))] + [InlineData(typeof(Dictionary))] + [InlineData(typeof(int[][]))] + [InlineData(typeof(Assert))] // xUnit assembly + [InlineData(typeof(TypeNameTests))] // test assembly + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1.NestedGeneric_2.NestedNonGeneric_3))] + public void TypeNameCanContainAssemblyName(Type type) + { + AssemblyName expectedAssemblyName = new(type.Assembly.FullName); + + Verify(type, expectedAssemblyName, TypeName.Parse(type.AssemblyQualifiedName.AsSpan())); + + static void Verify(Type type, AssemblyName expectedAssemblyName, TypeName parsed) + { + Assert.Equal(type.AssemblyQualifiedName, parsed.AssemblyQualifiedName); + Assert.Equal(type.FullName, parsed.FullName); + Assert.Equal(type.Name, parsed.Name); + + AssemblyNameInfo parsedAssemblyName = parsed.AssemblyName; + Assert.NotNull(parsedAssemblyName); + + Assert.Equal(expectedAssemblyName.Name, parsedAssemblyName.Name); + Assert.Equal(expectedAssemblyName.Version, parsedAssemblyName.Version); + Assert.Equal(expectedAssemblyName.CultureName, parsedAssemblyName.CultureName); + Assert.Equal(expectedAssemblyName.FullName, parsedAssemblyName.FullName); + + Assert.Equal(default, parsedAssemblyName.Flags); + } + } + + [Theory] + [InlineData(10, "*")] // pointer to pointer + [InlineData(10, "[]")] // array of arrays + [InlineData(100, "*")] + [InlineData(100, "[]")] + public void MaxNodesIsRespected_TooManyDecorators(int maxDepth, string decorator) + { + TypeNameParseOptions options = new() + { + MaxNodes = maxDepth + }; + + string notTooMany = $"System.Int32{string.Join("", Enumerable.Repeat(decorator, maxDepth - 1))}"; + string tooMany = $"System.Int32{string.Join("", Enumerable.Repeat(decorator, maxDepth))}"; + + Assert.Throws(() => TypeName.Parse(tooMany.AsSpan(), options)); + Assert.False(TypeName.TryParse(tooMany.AsSpan(), out _, options)); + + TypeName parsed = TypeName.Parse(notTooMany.AsSpan(), options); + ValidateElementType(maxDepth, parsed, decorator); + + Assert.True(TypeName.TryParse(notTooMany.AsSpan(), out parsed, options)); + ValidateElementType(maxDepth, parsed, decorator); + + static void ValidateElementType(int maxDepth, TypeName parsed, string decorator) + { + for (int i = 0; i < maxDepth - 1; i++) + { + Assert.Equal(decorator == "*", parsed.IsPointer); + Assert.Equal(decorator == "[]", parsed.IsSZArray); + Assert.False(parsed.IsConstructedGenericType); + + parsed = parsed.GetElementType(); + } + } + } + + [Theory] + [InlineData(10)] + [InlineData(100)] + public void MaxNodesIsRespected_TooDeepGenerics(int maxDepth) + { + TypeNameParseOptions options = new() + { + MaxNodes = maxDepth + }; + + string tooDeep = GetName(maxDepth); + string notTooDeep = GetName(maxDepth - 1); + + Assert.Throws(() => TypeName.Parse(tooDeep.AsSpan(), options)); + Assert.False(TypeName.TryParse(tooDeep.AsSpan(), out _, options)); + + TypeName parsed = TypeName.Parse(notTooDeep.AsSpan(), options); + Validate(maxDepth, parsed); + + Assert.True(TypeName.TryParse(notTooDeep.AsSpan(), out parsed, options)); + Validate(maxDepth, parsed); + + static string GetName(int depth) + { + // MakeGenericType is not used here, as it crashes for larger depths + string coreLibName = typeof(object).Assembly.FullName; + string fullName = typeof(int).AssemblyQualifiedName!; + for (int i = 0; i < depth; i++) + { + fullName = $"System.Collections.Generic.List`1[[{fullName}]], {coreLibName}"; + } + return fullName; + } + + static void Validate(int maxDepth, TypeName parsed) + { + for (int i = 0; i < maxDepth - 1; i++) + { + Assert.True(parsed.IsConstructedGenericType); + parsed = parsed.GetGenericArguments()[0]; + } + } + } + + [Theory] + [InlineData(10)] + [InlineData(100)] + public void MaxNodesIsRespected_TooManyGenericArguments(int maxDepth) + { + TypeNameParseOptions options = new() + { + MaxNodes = maxDepth + }; + + string tooMany = GetName(maxDepth); + string notTooMany = GetName(maxDepth - 1); + + Assert.Throws(() => TypeName.Parse(tooMany.AsSpan(), options)); + Assert.False(TypeName.TryParse(tooMany.AsSpan(), out _, options)); + + TypeName parsed = TypeName.Parse(notTooMany.AsSpan(), options); + Validate(parsed, maxDepth); + + Assert.True(TypeName.TryParse(notTooMany.AsSpan(), out parsed, options)); + Validate(parsed, maxDepth); + + static string GetName(int depth) + => $"Some.GenericType`{depth}[{string.Join(",", Enumerable.Repeat("System.Int32", depth))}]"; + + static void Validate(TypeName parsed, int maxDepth) + { + Assert.True(parsed.IsConstructedGenericType); + ImmutableArray genericArgs = parsed.GetGenericArguments(); + Assert.Equal(maxDepth - 1, genericArgs.Length); + Assert.All(genericArgs, arg => Assert.False(arg.IsConstructedGenericType)); + } + } + + public static IEnumerable GenericArgumentsAreSupported_Arguments() + { + yield return new object[] + { + "Generic`1[[A]]", + "Generic`1", + "Generic`1[[A]]", + new string[] { "A" }, + null + }; + yield return new object[] + { + "Generic`1[A]", + "Generic`1", + "Generic`1[[A]]", + new string[] { "A" }, + null + }; + yield return new object[] + { + "Generic`3[[A],[B],[C]]", + "Generic`3", + "Generic`3[[A],[B],[C]]", + new string[] { "A", "B", "C" }, + null + }; + yield return new object[] + { + "Generic`3[A,B,C]", + "Generic`3", + "Generic`3[[A],[B],[C]]", + new string[] { "A", "B", "C" }, + null + }; + yield return new object[] + { + "Generic`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + "Generic`1", + "Generic`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + new string[] { "System.Int32" }, + new AssemblyName[] { new AssemblyName("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") } + }; + yield return new object[] + { + "Generic`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + "Generic`2", + "Generic`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + new string[] { "System.Int32", "System.Boolean" }, + new AssemblyName[] + { + new AssemblyName("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), + new AssemblyName("mscorlib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") + } + }; + yield return new object[] + { + "Generic`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], System.Boolean]", + "Generic`2", + "Generic`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean]]", + new string[] { "System.Int32", "System.Boolean" }, + new AssemblyName[] + { + new AssemblyName("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), + null + } + }; + yield return new object[] + { + "Generic`2[System.Boolean, [System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + "Generic`2", + "Generic`2[[System.Boolean],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + new string[] { "System.Boolean", "System.Int32" }, + new AssemblyName[] + { + null, + new AssemblyName("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") + } + }; + yield return new object[] + { + "Generic`3[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], System.Boolean, [System.Byte, other, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + "Generic`3", + "Generic`3[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean],[System.Byte, other, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", + new string[] { "System.Int32", "System.Boolean", "System.Byte" }, + new AssemblyName[] + { + new AssemblyName("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), + null, + new AssemblyName("other, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") + } + }; + yield return new object[] + { + "Generic`3[System.Boolean, [System.Byte, other, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], System.Int32]", + "Generic`3", + "Generic`3[[System.Boolean],[System.Byte, other, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32]]", + new string[] { "System.Boolean", "System.Byte", "System.Int32" }, + new AssemblyName[] + { + null, + new AssemblyName("other, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), + null + } + }; + } + + [Theory] + [MemberData(nameof(GenericArgumentsAreSupported_Arguments))] + public void GenericArgumentsAreSupported(string input, string name, string fullName, string[] genericTypesFullNames, AssemblyName[]? assemblyNames) + { + TypeName parsed = TypeName.Parse(input.AsSpan()); + + Assert.Equal(name, parsed.Name); + Assert.Equal(fullName, parsed.FullName); + Assert.True(parsed.IsConstructedGenericType); + Assert.NotNull(parsed.GetGenericTypeDefinition()); + Assert.False(parsed.IsSimple); + + ImmutableArray typeNames = parsed.GetGenericArguments(); + for (int i = 0; i < genericTypesFullNames.Length; i++) + { + TypeName genericArg = typeNames[i]; + Assert.Equal(genericTypesFullNames[i], genericArg.FullName); + Assert.True(genericArg.IsSimple); + Assert.False(genericArg.IsConstructedGenericType); + Assert.Throws(genericArg.GetGenericTypeDefinition); + + if (assemblyNames is not null) + { + if (assemblyNames[i] is null) + { + Assert.Null(genericArg.AssemblyName); + } + else + { + Assert.Equal(assemblyNames[i].FullName, genericArg.AssemblyName.FullName); + Assert.Equal(assemblyNames[i].Name, genericArg.AssemblyName.Name); + } + } + } + } + + public static IEnumerable DecoratorsAreSupported_Arguments() + { + yield return new object[] + { + "TypeName*", "TypeName", false, false, -1, false, true + }; + yield return new object[] + { + "TypeName&", "TypeName", false, false, -1, true, false + }; + yield return new object[] + { + "TypeName[]", "TypeName", true, true, 1, false, false + }; + yield return new object[] + { + "TypeName[*]", "TypeName", true, false, 1, false, false + }; + yield return new object[] + { + "TypeName[,,,]", "TypeName", true, false, 4, false, false + }; + } + + [Theory] + [MemberData(nameof(DecoratorsAreSupported_Arguments))] + public void DecoratorsAreSupported(string input, string typeNameWithoutDecorators, bool isArray, bool isSzArray, int arrayRank, bool isByRef, bool isPointer) + { + TypeName parsed = TypeName.Parse(input.AsSpan()); + + Assert.Equal(input, parsed.FullName); + Assert.Equal(isArray, parsed.IsArray); + Assert.Equal(isSzArray, parsed.IsSZArray); + if (isArray) + { + Assert.Equal(arrayRank, parsed.GetArrayRank()); + } + else + { + Assert.Throws(() => parsed.GetArrayRank()); + } + Assert.Equal(isByRef, parsed.IsByRef); + Assert.Equal(isPointer, parsed.IsPointer); + Assert.False(parsed.IsSimple); + + TypeName elementType = parsed.GetElementType(); + Assert.NotNull(elementType); + Assert.Equal(typeNameWithoutDecorators, elementType.FullName); + Assert.True(elementType.IsSimple); + Assert.False(elementType.IsArray); + Assert.False(elementType.IsSZArray); + Assert.False(elementType.IsByRef); + Assert.False(elementType.IsPointer); + Assert.Throws(elementType.GetElementType); + } + + public static IEnumerable GetAdditionalConstructedTypeData() + { + yield return new object[] { typeof(Dictionary[,], List>[]), 16 }; + + // "Dictionary[,], List>[]" breaks down to complexity 16 like so: + // + // 01: Dictionary[,], List>[] + // 02: `- Dictionary[,], List> + // 03: +- Dictionary`2 + // 04: +- List[,] + // 05: | `- List + // 06: | +- List`1 + // 07: | `- int[] + // 08: | `- int + // 09: `- List + // 10: +- List`1 + // 11: `- int?[][][,] + // 12: `- int?[][] + // 13: `- int?[] + // 14: `- int? + // 15: +- Nullable`1 + // 16: `- int + + yield return new object[] { typeof(int[]).MakePointerType().MakeByRefType(), 4 }; // int[]*& + yield return new object[] { typeof(long).MakeArrayType(31), 2 }; // long[,,,,,,,...] + yield return new object[] { typeof(long).Assembly.GetType("System.Int64[*]"), 2 }; // long[*] + } + + [Theory] + [InlineData(typeof(TypeName), 1)] + [InlineData(typeof(TypeNameTests), 1)] + [InlineData(typeof(object), 1)] + [InlineData(typeof(Assert), 1)] // xunit + [InlineData(typeof(int[]), 2)] + [InlineData(typeof(int[,][]), 3)] + [InlineData(typeof(Nullable<>), 1)] // open generic type treated as elemental + [InlineData(typeof(NestedNonGeneric_0), 2)] // declaring and nested + [InlineData(typeof(NestedGeneric_0), 3)] // declaring, nested and generic arg + [InlineData(typeof(NestedNonGeneric_0.NestedNonGeneric_1), 3)] // declaring, nested 0 and nested 1 + // TypeNameTests+NestedGeneric_0`1+NestedGeneric_1`2[[Int32],[String],[Boolean]] (simplified for brevity) + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1), 6)] // declaring, nested 0 and nested 1 and 3 generic args + [MemberData(nameof(GetAdditionalConstructedTypeData))] + public void GetNodeCountReturnsExpectedValue(Type type, int expected) + { + TypeName parsed = TypeName.Parse(type.AssemblyQualifiedName.AsSpan()); + + Assert.Equal(expected, parsed.GetNodeCount()); + + Assert.Equal(type.Name, parsed.Name); + Assert.Equal(type.FullName, parsed.FullName); + Assert.Equal(type.AssemblyQualifiedName, parsed.AssemblyQualifiedName); + } + + [Fact] + public void IsSimpleReturnsTrueForNestedNonGenericTypes() + { + Assert.True(TypeName.Parse("Containing+Nested".AsSpan()).IsSimple); + Assert.False(TypeName.Parse(typeof(NestedGeneric_0).FullName.AsSpan()).IsSimple); + } + + [Fact] + public void DeclaringTypeThrowsForNonNestedTypes() + { + TypeName nested = TypeName.Parse("Containing+Nested".AsSpan()); + Assert.True(nested.IsNested); + Assert.Equal("Containing", nested.DeclaringType.Name); + + TypeName notNested = TypeName.Parse("NotNested".AsSpan()); + Assert.False(notNested.IsNested); + Assert.Throws(() => notNested.DeclaringType); + } + + [Theory] + [InlineData("SingleDimensionNonZeroIndexed[*]", true)] + [InlineData("SingleDimensionZeroIndexed[]", false)] + [InlineData("MultiDimensional[,,,,,,]", true)] + public void IsVariableBoundArrayTypeReturnsTrueForNonSZArrays(string typeName, bool expected) + { + TypeName parsed = TypeName.Parse(typeName.AsSpan()); + + Assert.True(parsed.IsArray); + Assert.Equal(expected, parsed.IsVariableBoundArrayType); + Assert.NotEqual(expected, parsed.IsSZArray); + Assert.InRange(parsed.GetArrayRank(), 1, 32); + } + + public static IEnumerable GetTypesThatRequireEscaping() + { + if (PlatformDetection.IsReflectionEmitSupported + && !PlatformDetection.IsMonoRuntime) // Mono does not escape Type.Name + { + AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("TypesThatRequireEscaping"), AssemblyBuilderAccess.Run); + ModuleBuilder module = assembly.DefineDynamicModule("TypesThatRequireEscapingModule"); + + yield return new object[] { module.DefineType("TypeNameWith+ThatIsNotNestedType").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith\\TheEscapingCharacter").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith&Ampersand").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith*Asterisk").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith[OpeningSquareBracket").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith]ClosingSquareBracket").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith[]BothSquareBrackets").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith[[]]NestedSquareBrackets").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith,Comma").CreateType() }; + yield return new object[] { module.DefineType("TypeNameWith\\[]+*&,AllSpecialCharacters").CreateType() }; + + TypeBuilder containingType = module.DefineType("ContainingTypeWithA+Plus"); + _ = containingType.CreateType(); // containing type must exist! + yield return new object[] { containingType.DefineNestedType("NoSpecialCharacters").CreateType() }; + yield return new object[] { containingType.DefineNestedType("Contains+Plus").CreateType() }; + } + } + + [Theory] + [InlineData(typeof(List))] + [InlineData(typeof(List>))] + [InlineData(typeof(Dictionary))] + [InlineData(typeof(Dictionary>))] + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1))] + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1.NestedGeneric_2))] + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1.NestedGeneric_2.NestedNonGeneric_3))] + [MemberData(nameof(GetTypesThatRequireEscaping))] + public void ParsedNamesMatchSystemTypeNames(Type type) + { + TypeName parsed = TypeName.Parse(type.AssemblyQualifiedName.AsSpan()); + + Assert.Equal(type.Name, parsed.Name); + Assert.Equal(type.FullName, parsed.FullName); + Assert.Equal(type.AssemblyQualifiedName, parsed.AssemblyQualifiedName); + + if (type.IsGenericType) + { + Type genericType = type.GetGenericTypeDefinition(); + TypeName genericTypeName = parsed.GetGenericTypeDefinition(); + Assert.Equal(genericType.Name, genericTypeName.Name); + Assert.Equal(genericType.FullName, genericTypeName.FullName); + Assert.Equal(genericType.AssemblyQualifiedName, genericTypeName.AssemblyQualifiedName); + } + } + + [Theory] + [InlineData("Name`2[[int], [bool]]", "Name`2")] // match + [InlineData("Name`1[[int], [bool]]", "Name`1")] // less than expected + [InlineData("Name`3[[int], [bool]]", "Name`3")] // more than expected + [InlineData("Name[[int], [bool]]", "Name")] // no backtick at all! + public void TheNumberAfterBacktickDoesNotEnforceGenericArgCount(string input, string expectedName) + { + TypeName parsed = TypeName.Parse(input.AsSpan()); + + Assert.True(parsed.IsConstructedGenericType); + Assert.Equal(expectedName, parsed.Name); + Assert.Equal($"{expectedName}[[int],[bool]]", parsed.FullName); + Assert.Equal("int", parsed.GetGenericArguments()[0].Name); + Assert.Equal("bool", parsed.GetGenericArguments()[1].Name); + } + + [Theory] + [InlineData(typeof(int))] + [InlineData(typeof(int?))] + [InlineData(typeof(int[]))] + [InlineData(typeof(int[,]))] + [InlineData(typeof(int[,,,]))] + [InlineData(typeof(List))] + [InlineData(typeof(List>))] + [InlineData(typeof(Dictionary))] + [InlineData(typeof(Dictionary>))] + [InlineData(typeof(NestedNonGeneric_0))] + [InlineData(typeof(NestedNonGeneric_0.NestedNonGeneric_1))] + [InlineData(typeof(NestedGeneric_0))] + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1))] + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1.NestedGeneric_2))] + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1.NestedGeneric_2.NestedNonGeneric_3))] + public void CanImplementGetTypeUsingPublicAPIs_Roundtrip(Type type) + { + Test(type); + Test(type.MakePointerType()); + Test(type.MakePointerType().MakePointerType()); + Test(type.MakeByRefType()); + + if (!type.IsArray) + { + Test(type.MakeArrayType()); // [] + Test(type.MakeArrayType(1)); // [*] + Test(type.MakeArrayType(2)); // [,] + } + + static void Test(Type type) + { + TypeName parsed = TypeName.Parse(type.AssemblyQualifiedName.AsSpan()); + + // ensure that Name, FullName and AssemblyQualifiedName match reflection APIs!! + Assert.Equal(type.Name, parsed.Name); + Assert.Equal(type.FullName, parsed.FullName); + Assert.Equal(type.AssemblyQualifiedName, parsed.AssemblyQualifiedName); + // now load load the type from name + Verify(type, parsed, ignoreCase: false); +#if NET // something weird is going on here + // load using lowercase name + Verify(type, TypeName.Parse(type.AssemblyQualifiedName.ToLower().AsSpan()), ignoreCase: true); + // load using uppercase name + Verify(type, TypeName.Parse(type.AssemblyQualifiedName.ToUpper().AsSpan()), ignoreCase: true); +#endif + + static void Verify(Type type, TypeName typeName, bool ignoreCase) + { + Type afterRoundtrip = GetType(typeName, throwOnError: true, ignoreCase: ignoreCase); + + Assert.NotNull(afterRoundtrip); + Assert.Equal(type, afterRoundtrip); + } + } + +#if NET8_0_OR_GREATER + [RequiresUnreferencedCode("The type might be removed")] + [RequiresDynamicCode("Required by MakeArrayType")] +#else +#pragma warning disable IL2055, IL2057, IL2075, IL2096 +#endif + static Type? GetType(TypeName typeName, bool throwOnError = true, bool ignoreCase = false) + { + if (typeName.IsNested) + { + BindingFlags flagsCopiedFromClr = BindingFlags.NonPublic | BindingFlags.Public; + if (ignoreCase) + { + flagsCopiedFromClr |= BindingFlags.IgnoreCase; + } + return Make(GetType(typeName.DeclaringType, throwOnError, ignoreCase)?.GetNestedType(typeName.Name, flagsCopiedFromClr)); + } + else if (typeName.IsConstructedGenericType) + { + return Make(GetType(typeName.GetGenericTypeDefinition(), throwOnError, ignoreCase)); + } + else if(typeName.IsArray || typeName.IsPointer || typeName.IsByRef) + { + return Make(GetType(typeName.GetElementType(), throwOnError, ignoreCase)); + } + else + { + Assert.True(typeName.IsSimple); + + AssemblyName? assemblyName = typeName.AssemblyName.ToAssemblyName(); + Type? type = assemblyName is null + ? Type.GetType(typeName.FullName, throwOnError, ignoreCase) + : Assembly.Load(assemblyName).GetType(typeName.FullName, throwOnError, ignoreCase); + + return Make(type); + } + + Type? Make(Type? type) + { + if (type is null || typeName.IsSimple) + { + return type; + } + else if (typeName.IsConstructedGenericType) + { + ImmutableArray genericArgs = typeName.GetGenericArguments(); + Type[] genericTypes = new Type[genericArgs.Length]; + for (int i = 0; i < genericArgs.Length; i++) + { + Type? genericArg = GetType(genericArgs[i], throwOnError, ignoreCase); + if (genericArg is null) + { + return null; + } + genericTypes[i] = genericArg; + } + + return type.MakeGenericType(genericTypes); + } + else if (typeName.IsByRef) + { + return type.MakeByRefType(); + } + else if (typeName.IsPointer) + { + return type.MakePointerType(); + } + else if (typeName.IsSZArray) + { + return type.MakeArrayType(); + } + else + { + Assert.True(typeName.IsVariableBoundArrayType); + + return type.MakeArrayType(rank: typeName.GetArrayRank()); + } + } + } +#pragma warning restore IL2055, IL2057, IL2075, IL2096 + } + + public class NestedNonGeneric_0 + { + public class NestedNonGeneric_1 { } + } + + public class NestedGeneric_0 + { + public class NestedGeneric_1 + { + public class NestedGeneric_2 + { + public class NestedNonGeneric_3 { } + } + } + } + } +} diff --git a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj index fa48b37d26ab82..f739ac0789ff81 100644 --- a/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj +++ b/src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj @@ -25,6 +25,9 @@ Link="Common\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" /> + + @@ -36,6 +39,9 @@ + + + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.Modules.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.Modules.cs index b6ad1c372e0f78..e5caf0e3a79f89 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.Modules.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.Modules.cs @@ -17,7 +17,7 @@ internal abstract partial class RoAssembly public sealed override Module? GetModule(string name) => GetRoModule(name); public sealed override Module[] GetModules(bool getResourceModules) => ComputeRoModules(getResourceModules).CloneArray(); -#if NETCOREAPP +#if NET [RequiresAssemblyFiles(ThrowingMessageInRAF)] #endif public sealed override FileStream? GetFile(string name) @@ -28,7 +28,7 @@ internal abstract partial class RoAssembly return new FileStream(m.FullyQualifiedName, FileMode.Open, FileAccess.Read, FileShare.Read); } -#if NETCOREAPP +#if NET [RequiresAssemblyFiles(ThrowingMessageInRAF)] #endif public sealed override FileStream[] GetFiles(bool getResourceModules) diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs index 9e0e4320a021c9..8ba5c16560087e 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/RoAssembly.cs @@ -45,12 +45,12 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount) // Location and codebase public abstract override string Location { get; } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [RequiresAssemblyFiles(ThrowingMessageInRAF)] #endif public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase); -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [RequiresAssemblyFiles(ThrowingMessageInRAF)] #endif @@ -159,7 +159,7 @@ public sealed override AssemblyName[] GetReferencedAssemblies() // Miscellaneous properties public sealed override bool ReflectionOnly => true; -#if NETCOREAPP +#if NET [Obsolete("The Global Assembly Cache is not supported.", DiagnosticId = "SYSLIB0005", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed override bool GlobalAssemblyCache => false; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs index d172f20f1cb066..c303886f9e7063 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/General/Helpers.cs @@ -134,7 +134,7 @@ public static bool NeedsEscapingInTypeName(this char c) public static string UnescapeTypeNameIdentifier(this string identifier) { -#if NET5_0_OR_GREATER +#if NET if (identifier.Contains('\\')) #else if (identifier.IndexOf('\\') != -1) @@ -367,7 +367,7 @@ public static RoAssemblyName ToRoAssemblyName(this AssemblyName assemblyName) public static byte[] ToUtf8(this string s) => Encoding.UTF8.GetBytes(s); -#if NETCOREAPP +#if NET public static string ToUtf16(this ReadOnlySpan utf8) => Encoding.UTF8.GetString(utf8); #else public static unsafe string ToUtf16(this ReadOnlySpan utf8) diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs index bd19faaac6256d..f236b209b3d25f 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Modules/RoModule.cs @@ -34,7 +34,7 @@ internal RoModule(string fullyQualifiedName) internal const string UnknownStringMessageInRAF = "Returns for modules with no file path"; -#if NETCOREAPP +#if NET [RequiresAssemblyFiles(UnknownStringMessageInRAF)] #endif public sealed override string FullyQualifiedName => _fullyQualifiedName; @@ -42,7 +42,7 @@ internal RoModule(string fullyQualifiedName) public abstract override int MetadataToken { get; } public abstract override Guid ModuleVersionId { get; } -#if NETCOREAPP +#if NET [RequiresAssemblyFiles(UnknownStringMessageInRAF)] #endif public sealed override string Name diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoModifiedType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoModifiedType.cs index afb9c79952ccfe..0e5928d26bbc6c 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoModifiedType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoModifiedType.cs @@ -152,7 +152,7 @@ public override Type[] GetOptionalCustomModifiers() public override IEnumerable DeclaredNestedTypes { -#if NETCOREAPP +#if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicNestedTypes)] #endif get { throw new NotSupportedException(SR.NotSupported_ModifiedType); } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs index 50ab6b7f307a08..1a5369f2f638d1 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs @@ -331,7 +331,7 @@ public sealed override Type MakeArrayType(int rank) private volatile RoType? _lazyUnderlyingEnumType; public sealed override Array GetEnumValues() => throw new InvalidOperationException(SR.Arg_InvalidOperation_Reflection); -#if NET7_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2085:UnrecognizedReflectionPattern", Justification = "Enum Types are not trimmed.")] public override Array GetEnumValuesAsUnderlyingType() diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj b/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj index 32518ce3efa431..4feacf3ede60ec 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/System.Reflection.MetadataLoadContext.Tests.csproj @@ -92,7 +92,7 @@ - + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/NetStandardBridge.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/NetStandardBridge.cs index 95ae7cea3e3e1c..e4fb5fbc1f5ac8 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/NetStandardBridge.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/TestUtils/NetStandardBridge.cs @@ -8,7 +8,7 @@ namespace System.Reflection.Tests { internal static class NetCoreApiEmulators { -#if NETCOREAPP +#if NET public static bool IsSZArray(this Type t) => t.IsSZArray; public static bool IsVariableBoundArray(this Type t) => t.IsVariableBoundArray; public static bool IsTypeDefinition(this Type t) => t.IsTypeDefinition; diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs index 03611db20825a4..c476213963544a 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs @@ -365,7 +365,7 @@ public static IEnumerable GetEnumUnderlyingTypeData } } -#if NET7_0_OR_GREATER +#if NET [Fact] public static void GetEnumValuesAsUnderlyingType() { diff --git a/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj b/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj index a0533c343614c6..8a197d09368674 100644 --- a/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj +++ b/src/libraries/System.Resources.Extensions/tests/System.Resources.Extensions.Tests.csproj @@ -27,7 +27,8 @@ - + + CP0001 diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/StringMarshalingTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/StringMarshalingTests.cs index 413809f30f6007..6181069f6bf48d 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/StringMarshalingTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/StringMarshalingTests.cs @@ -147,7 +147,7 @@ public void StringToHGlobalUniToString() } -#if NETCOREAPP +#if NET [Fact] public void TestUTF8String() { diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj index 3daf1f99fe8b06..ad5bd11ee41cc2 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/NativeExports.csproj @@ -91,12 +91,12 @@ - arm64-apple-ios14.2-macabi - x86_64-apple-ios13.5-macabi + arm64-apple-ios$(MacCatalystVersionMin)-macabi + x86_64-apple-ios$(MacCatalystVersionMin)-macabi - arm64-apple-macos11 - x86_64-apple-macos10.15 + arm64-apple-macos$(macOSVersionMin) + x86_64-apple-macos$(macOSVersionMin) macosx diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index c34725ba0bae50..e4f5e1d215802d 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -49,14 +49,20 @@ public static partial class Vector128 [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector128 ConvertToDouble(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 ConvertToInt32(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToInt32Native(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 ConvertToInt64(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ConvertToInt64Native(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static System.Runtime.Intrinsics.Vector128 ConvertToSingle(System.Runtime.Intrinsics.Vector128 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector128 ConvertToSingle(System.Runtime.Intrinsics.Vector128 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector128 ConvertToUInt32(System.Runtime.Intrinsics.Vector128 vector) { throw null; } [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector128 ConvertToUInt32Native(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector128 ConvertToUInt64(System.Runtime.Intrinsics.Vector128 vector) { throw null; } + [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector128 ConvertToUInt64Native(System.Runtime.Intrinsics.Vector128 vector) { throw null; } public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, System.Span destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, T[] destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, T[] destination, int startIndex) { } @@ -384,14 +390,20 @@ public static partial class Vector256 [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector256 ConvertToDouble(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 ConvertToInt32(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToInt32Native(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 ConvertToInt64(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector256 ConvertToInt64Native(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static System.Runtime.Intrinsics.Vector256 ConvertToSingle(System.Runtime.Intrinsics.Vector256 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector256 ConvertToSingle(System.Runtime.Intrinsics.Vector256 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector256 ConvertToUInt32(System.Runtime.Intrinsics.Vector256 vector) { throw null; } [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector256 ConvertToUInt32Native(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector256 ConvertToUInt64(System.Runtime.Intrinsics.Vector256 vector) { throw null; } + [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector256 ConvertToUInt64Native(System.Runtime.Intrinsics.Vector256 vector) { throw null; } public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, System.Span destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, T[] destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, T[] destination, int startIndex) { } @@ -719,14 +731,20 @@ public static partial class Vector512 [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector512 ConvertToDouble(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToInt32(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToInt32Native(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToInt64(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector512 ConvertToInt64Native(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static System.Runtime.Intrinsics.Vector512 ConvertToSingle(System.Runtime.Intrinsics.Vector512 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector512 ConvertToSingle(System.Runtime.Intrinsics.Vector512 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector512 ConvertToUInt32(System.Runtime.Intrinsics.Vector512 vector) { throw null; } [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector512 ConvertToUInt32Native(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector512 ConvertToUInt64(System.Runtime.Intrinsics.Vector512 vector) { throw null; } + [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector512 ConvertToUInt64Native(System.Runtime.Intrinsics.Vector512 vector) { throw null; } public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, System.Span destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, T[] destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, T[] destination, int startIndex) { } @@ -1050,14 +1068,20 @@ public static partial class Vector64 [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 ConvertToDouble(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 ConvertToInt32(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ConvertToInt32Native(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 ConvertToInt64(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ConvertToInt64Native(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static System.Runtime.Intrinsics.Vector64 ConvertToSingle(System.Runtime.Intrinsics.Vector64 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 ConvertToSingle(System.Runtime.Intrinsics.Vector64 vector) { throw null; } [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 ConvertToUInt32(System.Runtime.Intrinsics.Vector64 vector) { throw null; } [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector64 ConvertToUInt32Native(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + [System.CLSCompliantAttribute(false)] public static System.Runtime.Intrinsics.Vector64 ConvertToUInt64(System.Runtime.Intrinsics.Vector64 vector) { throw null; } + [System.CLSCompliantAttribute(false)] + public static System.Runtime.Intrinsics.Vector64 ConvertToUInt64Native(System.Runtime.Intrinsics.Vector64 vector) { throw null; } public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, System.Span destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, T[] destination) { } public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, T[] destination, int startIndex) { } @@ -4147,7 +4171,64 @@ internal Sve() { } internal Arm64() { } public static new bool IsSupported { get { throw null; } } } + public static System.Numerics.Vector Abs(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Abs(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Abs(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Abs(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Abs(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Abs(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Add(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector And(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AndAcross(System.Numerics.Vector value) { throw null; } + public static ulong Count16BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } + public static ulong Count32BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } + public static ulong Count64BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } + public static ulong Count8BitElements([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ConditionalSelect(System.Numerics.Vector mask, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector CreateTrueMaskByte([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskDouble([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskInt16([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } @@ -4158,7 +4239,40 @@ internal Arm64() { } public static System.Numerics.Vector CreateTrueMaskUInt16([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskUInt32([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } public static System.Numerics.Vector CreateTrueMaskUInt64([ConstantExpected] SveMaskPattern pattern = SveMaskPattern.All) { throw null; } - + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask16Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask32Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask64Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanMask8Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask16Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask32Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask64Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(int left, int right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(long left, long right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(uint left, uint right) { throw null; } + public static System.Numerics.Vector CreateWhileLessThanOrEqualMask8Bit(ulong left, ulong right) { throw null; } + public static System.Numerics.Vector Divide(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Divide(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, sbyte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, int* address) { throw null; } @@ -4169,7 +4283,209 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, ulong* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, float* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, double* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToInt16(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToInt32(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToInt64(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt16(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt32(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorByteZeroExtendToUInt64(System.Numerics.Vector mask, byte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToInt32(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToInt64(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToUInt32(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt16SignExtendToUInt64(System.Numerics.Vector mask, short* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt32SignExtendToInt64(System.Numerics.Vector mask, int* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorInt32SignExtendToUInt64(System.Numerics.Vector mask, int* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToInt16(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToInt32(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToInt64(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToUInt16(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToUInt32(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorSByteSignExtendToUInt64(System.Numerics.Vector mask, sbyte* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToInt32(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToInt64(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToUInt32(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToUInt64(System.Numerics.Vector mask, ushort* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt32ZeroExtendToInt64(System.Numerics.Vector mask, uint* address) { throw null; } + public static unsafe System.Numerics.Vector LoadVectorUInt32ZeroExtendToUInt64(System.Numerics.Vector mask, uint* address) { throw null; } + + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxNumber(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxNumber(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MaxNumberAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MaxNumberAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinNumber(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinNumber(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MinNumberAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector MinNumberAcross(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector OrAcross(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector SignExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend32(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend8(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector SignExtendWideningLower(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtendWideningLower(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtendWideningLower(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtendWideningUpper(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtendWideningUpper(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtendWideningUpper(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Xor(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector XorAcross(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector ZeroExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend32(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend8(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector ZeroExtendWideningLower(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtendWideningLower(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtendWideningLower(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtendWideningUpper(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtendWideningUpper(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtendWideningUpper(System.Numerics.Vector value) { throw null; } + + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZipLow(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } } public enum SveMaskPattern : byte diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs index 0ebed660f33689..95cf6d16b66171 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector128Tests.cs @@ -5,6 +5,7 @@ using System.Numerics; using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; using Xunit; namespace System.Runtime.Intrinsics.Tests.Vectors @@ -4872,5 +4873,108 @@ public void Log2SingleTest(float value, float expectedResult, float variance) Vector128 actualResult = Vector128.Log2(Vector128.Create(value)); AssertEqual(Vector128.Create(expectedResult), actualResult, Vector128.Create(variance)); } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32Test() + { + Assert.Equal(Vector128.Create(int.MinValue), Vector128.ConvertToInt32(Vector128.Create(float.MinValue))); + Assert.Equal(Vector128.Create(2), Vector128.ConvertToInt32(Vector128.Create(2.6f))); + Assert.Equal(Vector128.Create(int.MaxValue), Vector128.ConvertToInt32(Vector128.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32NativeTest() + { + if (Vector128.IsHardwareAccelerated && Sse2.IsSupported) + { + Assert.Equal(Vector128.Create(int.MinValue), Vector128.ConvertToInt32Native(Vector128.Create(float.MaxValue))); + } + else + { + Assert.Equal(Vector128.Create(int.MaxValue), Vector128.ConvertToInt32Native(Vector128.Create(float.MaxValue))); + } + Assert.Equal(Vector128.Create(int.MinValue), Vector128.ConvertToInt32Native(Vector128.Create(float.MinValue))); + Assert.Equal(Vector128.Create(2), Vector128.ConvertToInt32Native(Vector128.Create(2.6f))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64Test() + { + Assert.Equal(Vector128.Create(long.MinValue), Vector128.ConvertToInt64(Vector128.Create(double.MinValue))); + Assert.Equal(Vector128.Create(2L), Vector128.ConvertToInt64(Vector128.Create(2.6))); + Assert.Equal(Vector128.Create(long.MaxValue), Vector128.ConvertToInt64(Vector128.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512DQ.VL.IsSupported) + { + Assert.Equal(Vector128.Create(long.MinValue), Vector128.ConvertToInt64Native(Vector128.Create(double.MaxValue))); + } + else + { + Assert.Equal(Vector128.Create(long.MaxValue), Vector128.ConvertToInt64Native(Vector128.Create(double.MaxValue))); + } + + Assert.Equal(Vector128.Create(long.MinValue), Vector128.ConvertToInt64Native(Vector128.Create(double.MinValue))); + Assert.Equal(Vector128.Create(2L), Vector128.ConvertToInt64Native(Vector128.Create(2.6))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32Test() + { + Assert.Equal(Vector128.Create(uint.MinValue), Vector128.ConvertToUInt32(Vector128.Create(float.MinValue))); + Assert.Equal(Vector128.Create(2u), Vector128.ConvertToUInt32(Vector128.Create(2.6f))); + Assert.Equal(Vector128.Create(uint.MaxValue), Vector128.ConvertToUInt32(Vector128.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512F.VL.IsSupported) + { + Assert.Equal(Vector128.Create(uint.MaxValue), Vector128.ConvertToUInt32Native(Vector128.Create(float.MinValue))); + } + else + { + Assert.Equal(Vector128.Create(uint.MinValue), Vector128.ConvertToUInt32Native(Vector128.Create(float.MinValue))); + } + + Assert.Equal(Vector128.Create(2u), Vector128.ConvertToUInt32Native(Vector128.Create(2.6f))); + Assert.Equal(Vector128.Create(uint.MaxValue), Vector128.ConvertToUInt32Native(Vector128.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64Test() + { + Assert.Equal(Vector128.Create(ulong.MinValue), Vector128.ConvertToUInt64(Vector128.Create(double.MinValue))); + Assert.Equal(Vector128.Create(2UL), Vector128.ConvertToUInt64(Vector128.Create(2.6))); + Assert.Equal(Vector128.Create(ulong.MaxValue), Vector128.ConvertToUInt64(Vector128.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512DQ.VL.IsSupported) + { + Assert.Equal(Vector128.Create(ulong.MaxValue), Vector128.ConvertToUInt64Native(Vector128.Create(double.MinValue))); + } + else + { + Assert.Equal(Vector128.Create(ulong.MinValue), Vector128.ConvertToUInt64Native(Vector128.Create(double.MinValue))); + } + + Assert.Equal(Vector128.Create(2UL), Vector128.ConvertToUInt64Native(Vector128.Create(2.6))); + Assert.Equal(Vector128.Create(ulong.MaxValue), Vector128.ConvertToUInt64Native(Vector128.Create(double.MaxValue))); + } } } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs index d658ca08b17b32..a5559d43c81505 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector256Tests.cs @@ -4,6 +4,7 @@ using System.Numerics; using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; using Xunit; namespace System.Runtime.Intrinsics.Tests.Vectors @@ -5887,5 +5888,108 @@ public void Log2SingleTest(float value, float expectedResult, float variance) Vector256 actualResult = Vector256.Log2(Vector256.Create(value)); AssertEqual(Vector256.Create(expectedResult), actualResult, Vector256.Create(variance)); } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32Test() + { + Assert.Equal(Vector256.Create(int.MinValue), Vector256.ConvertToInt32(Vector256.Create(float.MinValue))); + Assert.Equal(Vector256.Create(2), Vector256.ConvertToInt32(Vector256.Create(2.6f))); + Assert.Equal(Vector256.Create(int.MaxValue), Vector256.ConvertToInt32(Vector256.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32NativeTest() + { + if (Vector128.IsHardwareAccelerated && Sse2.IsSupported) + { + Assert.Equal(Vector256.Create(int.MinValue), Vector256.ConvertToInt32Native(Vector256.Create(float.MaxValue))); + } + else + { + Assert.Equal(Vector256.Create(int.MaxValue), Vector256.ConvertToInt32Native(Vector256.Create(float.MaxValue))); + } + Assert.Equal(Vector256.Create(int.MinValue), Vector256.ConvertToInt32Native(Vector256.Create(float.MinValue))); + Assert.Equal(Vector256.Create(2), Vector256.ConvertToInt32Native(Vector256.Create(2.6f))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64Test() + { + Assert.Equal(Vector256.Create(long.MinValue), Vector256.ConvertToInt64(Vector256.Create(double.MinValue))); + Assert.Equal(Vector256.Create(2L), Vector256.ConvertToInt64(Vector256.Create(2.6))); + Assert.Equal(Vector256.Create(long.MaxValue), Vector256.ConvertToInt64(Vector256.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512DQ.VL.IsSupported) + { + Assert.Equal(Vector256.Create(long.MinValue), Vector256.ConvertToInt64Native(Vector256.Create(double.MaxValue))); + } + else + { + Assert.Equal(Vector256.Create(long.MaxValue), Vector256.ConvertToInt64Native(Vector256.Create(double.MaxValue))); + } + + Assert.Equal(Vector256.Create(long.MinValue), Vector256.ConvertToInt64Native(Vector256.Create(double.MinValue))); + Assert.Equal(Vector256.Create(2L), Vector256.ConvertToInt64Native(Vector256.Create(2.6))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32Test() + { + Assert.Equal(Vector256.Create(uint.MinValue), Vector256.ConvertToUInt32(Vector256.Create(float.MinValue))); + Assert.Equal(Vector256.Create(2u), Vector256.ConvertToUInt32(Vector256.Create(2.6f))); + Assert.Equal(Vector256.Create(uint.MaxValue), Vector256.ConvertToUInt32(Vector256.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512F.VL.IsSupported) + { + Assert.Equal(Vector256.Create(uint.MaxValue), Vector256.ConvertToUInt32Native(Vector256.Create(float.MinValue))); + } + else + { + Assert.Equal(Vector256.Create(uint.MinValue), Vector256.ConvertToUInt32Native(Vector256.Create(float.MinValue))); + } + + Assert.Equal(Vector256.Create(2u), Vector256.ConvertToUInt32Native(Vector256.Create(2.6f))); + Assert.Equal(Vector256.Create(uint.MaxValue), Vector256.ConvertToUInt32Native(Vector256.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64Test() + { + Assert.Equal(Vector256.Create(ulong.MinValue), Vector256.ConvertToUInt64(Vector256.Create(double.MinValue))); + Assert.Equal(Vector256.Create(2UL), Vector256.ConvertToUInt64(Vector256.Create(2.6))); + Assert.Equal(Vector256.Create(ulong.MaxValue), Vector256.ConvertToUInt64(Vector256.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512DQ.VL.IsSupported) + { + Assert.Equal(Vector256.Create(ulong.MaxValue), Vector256.ConvertToUInt64Native(Vector256.Create(double.MinValue))); + } + else + { + Assert.Equal(Vector256.Create(ulong.MinValue), Vector256.ConvertToUInt64Native(Vector256.Create(double.MinValue))); + } + + Assert.Equal(Vector256.Create(2UL), Vector256.ConvertToUInt64Native(Vector256.Create(2.6))); + Assert.Equal(Vector256.Create(ulong.MaxValue), Vector256.ConvertToUInt64Native(Vector256.Create(double.MaxValue))); + } } } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs index 4b4f9e2d4692aa..c01f88facbf574 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector512Tests.cs @@ -4,6 +4,7 @@ using System.Numerics; using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; using Xunit; namespace System.Runtime.Intrinsics.Tests.Vectors @@ -5320,5 +5321,108 @@ public void Log2SingleTest(float value, float expectedResult, float variance) Vector512 actualResult = Vector512.Log2(Vector512.Create(value)); AssertEqual(Vector512.Create(expectedResult), actualResult, Vector512.Create(variance)); } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32Test() + { + Assert.Equal(Vector512.Create(int.MinValue), Vector512.ConvertToInt32(Vector512.Create(float.MinValue))); + Assert.Equal(Vector512.Create(2), Vector512.ConvertToInt32(Vector512.Create(2.6f))); + Assert.Equal(Vector512.Create(int.MaxValue), Vector512.ConvertToInt32(Vector512.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32NativeTest() + { + if (Vector128.IsHardwareAccelerated && Sse2.IsSupported) + { + Assert.Equal(Vector512.Create(int.MinValue), Vector512.ConvertToInt32Native(Vector512.Create(float.MaxValue))); + } + else + { + Assert.Equal(Vector512.Create(int.MaxValue), Vector512.ConvertToInt32Native(Vector512.Create(float.MaxValue))); + } + Assert.Equal(Vector512.Create(int.MinValue), Vector512.ConvertToInt32Native(Vector512.Create(float.MinValue))); + Assert.Equal(Vector512.Create(2), Vector512.ConvertToInt32Native(Vector512.Create(2.6f))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64Test() + { + Assert.Equal(Vector512.Create(long.MinValue), Vector512.ConvertToInt64(Vector512.Create(double.MinValue))); + Assert.Equal(Vector512.Create(2L), Vector512.ConvertToInt64(Vector512.Create(2.6))); + Assert.Equal(Vector512.Create(long.MaxValue), Vector512.ConvertToInt64(Vector512.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512DQ.VL.IsSupported) + { + Assert.Equal(Vector512.Create(long.MinValue), Vector512.ConvertToInt64Native(Vector512.Create(double.MaxValue))); + } + else + { + Assert.Equal(Vector512.Create(long.MaxValue), Vector512.ConvertToInt64Native(Vector512.Create(double.MaxValue))); + } + + Assert.Equal(Vector512.Create(long.MinValue), Vector512.ConvertToInt64Native(Vector512.Create(double.MinValue))); + Assert.Equal(Vector512.Create(2L), Vector512.ConvertToInt64Native(Vector512.Create(2.6))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32Test() + { + Assert.Equal(Vector512.Create(uint.MinValue), Vector512.ConvertToUInt32(Vector512.Create(float.MinValue))); + Assert.Equal(Vector512.Create(2u), Vector512.ConvertToUInt32(Vector512.Create(2.6f))); + Assert.Equal(Vector512.Create(uint.MaxValue), Vector512.ConvertToUInt32(Vector512.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512F.VL.IsSupported) + { + Assert.Equal(Vector512.Create(uint.MaxValue), Vector512.ConvertToUInt32Native(Vector512.Create(float.MinValue))); + } + else + { + Assert.Equal(Vector512.Create(uint.MinValue), Vector512.ConvertToUInt32Native(Vector512.Create(float.MinValue))); + } + + Assert.Equal(Vector512.Create(2u), Vector512.ConvertToUInt32Native(Vector512.Create(2.6f))); + Assert.Equal(Vector512.Create(uint.MaxValue), Vector512.ConvertToUInt32Native(Vector512.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64Test() + { + Assert.Equal(Vector512.Create(ulong.MinValue), Vector512.ConvertToUInt64(Vector512.Create(double.MinValue))); + Assert.Equal(Vector512.Create(2UL), Vector512.ConvertToUInt64(Vector512.Create(2.6))); + Assert.Equal(Vector512.Create(ulong.MaxValue), Vector512.ConvertToUInt64(Vector512.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64NativeTest() + { + if (Vector128.IsHardwareAccelerated && Avx512DQ.VL.IsSupported) + { + Assert.Equal(Vector512.Create(ulong.MaxValue), Vector512.ConvertToUInt64Native(Vector512.Create(double.MinValue))); + } + else + { + Assert.Equal(Vector512.Create(ulong.MinValue), Vector512.ConvertToUInt64Native(Vector512.Create(double.MinValue))); + } + + Assert.Equal(Vector512.Create(2UL), Vector512.ConvertToUInt64Native(Vector512.Create(2.6))); + Assert.Equal(Vector512.Create(ulong.MaxValue), Vector512.ConvertToUInt64Native(Vector512.Create(double.MaxValue))); + } } } diff --git a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs index 69f37520ad735a..3c2d8064681fe1 100644 --- a/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs +++ b/src/libraries/System.Runtime.Intrinsics/tests/Vectors/Vector64Tests.cs @@ -4,6 +4,7 @@ using System.Numerics; using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; using Xunit; namespace System.Runtime.Intrinsics.Tests.Vectors @@ -4287,5 +4288,77 @@ public void Log2SingleTest(float value, float expectedResult, float variance) Vector64 actualResult = Vector64.Log2(Vector64.Create(value)); AssertEqual(Vector64.Create(expectedResult), actualResult, Vector64.Create(variance)); } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32Test() + { + Assert.Equal(Vector64.Create(int.MinValue), Vector64.ConvertToInt32(Vector64.Create(float.MinValue))); + Assert.Equal(Vector64.Create(2), Vector64.ConvertToInt32(Vector64.Create(2.6f))); + Assert.Equal(Vector64.Create(int.MaxValue), Vector64.ConvertToInt32(Vector64.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt32NativeTest() + { + Assert.Equal(Vector64.Create(int.MinValue), Vector64.ConvertToInt32Native(Vector64.Create(float.MinValue))); + Assert.Equal(Vector64.Create(2), Vector64.ConvertToInt32Native(Vector64.Create(2.6f))); + Assert.Equal(Vector64.Create(int.MaxValue), Vector64.ConvertToInt32Native(Vector64.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64Test() + { + Assert.Equal(Vector64.Create(long.MinValue), Vector64.ConvertToInt64(Vector64.Create(double.MinValue))); + Assert.Equal(Vector64.Create(2L), Vector64.ConvertToInt64(Vector64.Create(2.6))); + Assert.Equal(Vector64.Create(long.MaxValue), Vector64.ConvertToInt64(Vector64.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToInt64NativeTest() + { + Assert.Equal(Vector64.Create(long.MinValue), Vector64.ConvertToInt64Native(Vector64.Create(double.MinValue))); + Assert.Equal(Vector64.Create(2L), Vector64.ConvertToInt64Native(Vector64.Create(2.6))); + Assert.Equal(Vector64.Create(long.MaxValue), Vector64.ConvertToInt64Native(Vector64.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32Test() + { + Assert.Equal(Vector64.Create(uint.MinValue), Vector64.ConvertToUInt32(Vector64.Create(float.MinValue))); + Assert.Equal(Vector64.Create(2u), Vector64.ConvertToUInt32(Vector64.Create(2.6f))); + Assert.Equal(Vector64.Create(uint.MaxValue), Vector64.ConvertToUInt32(Vector64.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt32NativeTest() + { + Assert.Equal(Vector64.Create(uint.MinValue), Vector64.ConvertToUInt32Native(Vector64.Create(float.MinValue))); + Assert.Equal(Vector64.Create(2u), Vector64.ConvertToUInt32Native(Vector64.Create(2.6f))); + Assert.Equal(Vector64.Create(uint.MaxValue), Vector64.ConvertToUInt32Native(Vector64.Create(float.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64Test() + { + Assert.Equal(Vector64.Create(ulong.MinValue), Vector64.ConvertToUInt64(Vector64.Create(double.MinValue))); + Assert.Equal(Vector64.Create(2UL), Vector64.ConvertToUInt64(Vector64.Create(2.6))); + Assert.Equal(Vector64.Create(ulong.MaxValue), Vector64.ConvertToUInt64(Vector64.Create(double.MaxValue))); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public void ConvertToUInt64NativeTest() + { + Assert.Equal(Vector64.Create(ulong.MinValue), Vector64.ConvertToUInt64Native(Vector64.Create(double.MinValue))); + Assert.Equal(Vector64.Create(2UL), Vector64.ConvertToUInt64Native(Vector64.Create(2.6))); + Assert.Equal(Vector64.Create(ulong.MaxValue), Vector64.ConvertToUInt64Native(Vector64.Create(double.MaxValue))); + } } } diff --git a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj index 8bb2962a4e59ec..504be89a6d4af2 100644 --- a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj @@ -71,7 +71,7 @@ - + diff --git a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj index d2003757c60f3d..6526656921c343 100644 --- a/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj +++ b/src/libraries/System.Runtime.Numerics/src/System.Runtime.Numerics.csproj @@ -25,6 +25,8 @@ + fo return spanSuccess; } + private const uint kuBase = 1_000_000_000; // 10^9 + private const int kcchBase = 9; + private static unsafe string? FormatBigInteger( bool targetSpan, BigInteger value, string? formatString, ReadOnlySpan formatSpan, @@ -882,6 +886,7 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan fo } else { + Debug.Assert(formatString != null); charsWritten = 0; spanSuccess = false; return value._sign.ToString(formatString, info); @@ -889,17 +894,17 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan fo } // First convert to base 10^9. - const uint kuBase = 1000000000; // 10^9 - const int kcchBase = 9; - int cuSrc = value._bits.Length; - int cuMax; - try - { - cuMax = checked(cuSrc * 10 / 9 + 2); - } - catch (OverflowException e) { throw new FormatException(SR.Format_TooLarge, e); } - uint[] rguDst = new uint[cuMax]; + // A quick conservative max length of base 10^9 representation + // A uint contributes to no more than 10/9 of 10^9 block, +1 for ceiling of division + int cuMax = cuSrc * (kcchBase + 1) / kcchBase + 1; + Debug.Assert((long)BigInteger.MaxLength * (kcchBase + 1) / kcchBase + 1 < (long)int.MaxValue); // won't overflow + + uint[]? bufferToReturn = null; + Span base1E9Buffer = cuMax < BigIntegerCalculator.StackAllocThreshold ? + stackalloc uint[cuMax] : + (bufferToReturn = ArrayPool.Shared.Rent(cuMax)); + int cuDst = 0; for (int iuSrc = cuSrc; --iuSrc >= 0;) @@ -907,93 +912,86 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan fo uint uCarry = value._bits[iuSrc]; for (int iuDst = 0; iuDst < cuDst; iuDst++) { - Debug.Assert(rguDst[iuDst] < kuBase); - ulong uuRes = NumericsHelpers.MakeUInt64(rguDst[iuDst], uCarry); - rguDst[iuDst] = (uint)(uuRes % kuBase); - uCarry = (uint)(uuRes / kuBase); + Debug.Assert(base1E9Buffer[iuDst] < kuBase); + + // Use X86Base.DivRem when stable + ulong uuRes = NumericsHelpers.MakeUInt64(base1E9Buffer[iuDst], uCarry); + (ulong quo, ulong rem) = Math.DivRem(uuRes, kuBase); + uCarry = (uint)quo; + base1E9Buffer[iuDst] = (uint)rem; } if (uCarry != 0) { - rguDst[cuDst++] = uCarry % kuBase; - uCarry /= kuBase; + (uCarry, base1E9Buffer[cuDst++]) = Math.DivRem(uCarry, kuBase); if (uCarry != 0) - rguDst[cuDst++] = uCarry; + base1E9Buffer[cuDst++] = uCarry; } } - int cchMax; - try - { - // Each uint contributes at most 9 digits to the decimal representation. - cchMax = checked(cuDst * kcchBase); - } - catch (OverflowException e) { throw new FormatException(SR.Format_TooLarge, e); } + ReadOnlySpan base1E9Value = base1E9Buffer[..cuDst]; + + int valueDigits = (base1E9Value.Length - 1) * kcchBase + FormattingHelpers.CountDigits(base1E9Value[^1]); + + string? strResult; - bool decimalFmt = (fmt == 'g' || fmt == 'G' || fmt == 'd' || fmt == 'D' || fmt == 'r' || fmt == 'R'); - if (decimalFmt) + if (fmt == 'g' || fmt == 'G' || fmt == 'd' || fmt == 'D' || fmt == 'r' || fmt == 'R') { - if (digits > 0 && digits > cchMax) - cchMax = digits; - if (value._sign < 0) + int strDigits = Math.Max(digits, valueDigits); + string? sNegative = value.Sign < 0 ? info.NegativeSign : null; + int strLength = strDigits + (sNegative?.Length ?? 0); + + if (targetSpan) { - try + if (destination.Length < strLength) + { + spanSuccess = false; + charsWritten = 0; + } + else { - // Leave an extra slot for a minus sign. - cchMax = checked(cchMax + info.NegativeSign.Length); + sNegative?.CopyTo(destination); + fixed (char* ptr = &MemoryMarshal.GetReference(destination)) + { + BigIntegerToDecChars((Utf16Char*)ptr + strLength, base1E9Value, digits); + } + charsWritten = strLength; + spanSuccess = true; } - catch (OverflowException e) { throw new FormatException(SR.Format_TooLarge, e); } + strResult = null; } - } - - int rgchBufSize; - - try - { - // We'll pass the rgch buffer to native code, which is going to treat it like a string of digits, so it needs - // to be null terminated. Let's ensure that we can allocate a buffer of that size. - rgchBufSize = checked(cchMax + 1); - } - catch (OverflowException e) { throw new FormatException(SR.Format_TooLarge, e); } - - char[] rgch = new char[rgchBufSize]; - - int ichDst = cchMax; - - for (int iuDst = 0; iuDst < cuDst - 1; iuDst++) - { - uint uDig = rguDst[iuDst]; - Debug.Assert(uDig < kuBase); - for (int cch = kcchBase; --cch >= 0;) + else { - rgch[--ichDst] = (char)('0' + uDig % 10); - uDig /= 10; + spanSuccess = false; + charsWritten = 0; + fixed (uint* ptr = base1E9Value) + { + strResult = string.Create(strLength, (digits, ptr: (IntPtr)ptr, base1E9Value.Length, sNegative), static (span, state) => + { + state.sNegative?.CopyTo(span); + fixed (char* ptr = &MemoryMarshal.GetReference(span)) + { + BigIntegerToDecChars((Utf16Char*)ptr + span.Length, new ReadOnlySpan((void*)state.ptr, state.Length), state.digits); + } + }); + } } } - for (uint uDig = rguDst[cuDst - 1]; uDig != 0;) - { - rgch[--ichDst] = (char)('0' + uDig % 10); - uDig /= 10; - } - - if (!decimalFmt) + else { - // sign = true for negative and false for 0 and positive values - bool sign = (value._sign < 0); - int scale = cchMax - ichDst; - - byte[]? buffer = ArrayPool.Shared.Rent(rgchBufSize + 1); - fixed (byte* ptr = buffer) // NumberBuffer expects pinned Digits + byte[]? numberBufferToReturn = null; + Span numberBuffer = valueDigits + 1 <= CharStackBufferSize ? + stackalloc byte[valueDigits + 1] : + (numberBufferToReturn = ArrayPool.Shared.Rent(valueDigits + 1)); + fixed (byte* ptr = numberBuffer) // NumberBuffer expects pinned Digits { - scoped NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, buffer); + scoped NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, ptr, valueDigits + 1); + BigIntegerToDecChars((Utf8Char*)ptr + valueDigits, base1E9Value, valueDigits); + number.Digits[^1] = 0; + number.DigitsCount = valueDigits; + number.Scale = valueDigits; + number.IsNegative = value.Sign < 0; - for (int i = 0; i < rgch.Length - ichDst; i++) - number.Digits[i] = (byte)rgch[ichDst + i]; - number.Digits[rgch.Length - ichDst] = 0; - number.DigitsCount = rgch.Length - ichDst - 1; // The cut-off point to switch (G)eneral from (F)ixed-point to (E)xponential form - number.Scale = scale; - number.IsNegative = sign; - - scoped var vlb = new ValueListBuilder(stackalloc Utf16Char[128]); // arbitrary stack cut-off + scoped var vlb = new ValueListBuilder(stackalloc Utf16Char[CharStackBufferSize]); // arbitrary stack cut-off if (fmt != 0) { @@ -1007,59 +1005,44 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan fo if (targetSpan) { spanSuccess = vlb.TryCopyTo(MemoryMarshal.Cast(destination), out charsWritten); - vlb.Dispose(); - return null; + strResult = null; } else { charsWritten = 0; spanSuccess = false; - string result = MemoryMarshal.Cast(vlb.AsSpan()).ToString(); - vlb.Dispose(); - return result; + strResult = MemoryMarshal.Cast(vlb.AsSpan()).ToString(); + } + + vlb.Dispose(); + if (numberBufferToReturn != null) + { + ArrayPool.Shared.Return(numberBufferToReturn); } } } - // Format Round-trip decimal - // This format is supported for integral types only. The number is converted to a string of - // decimal digits (0-9), prefixed by a minus sign if the number is negative. The precision - // specifier indicates the minimum number of digits desired in the resulting string. If required, - // the number is padded with zeros to its left to produce the number of digits given by the - // precision specifier. - int numDigitsPrinted = cchMax - ichDst; - while (digits > 0 && digits > numDigitsPrinted) - { - // pad leading zeros - rgch[--ichDst] = '0'; - digits--; - } - if (value._sign < 0) + if (bufferToReturn != null) { - string negativeSign = info.NegativeSign; - for (int i = negativeSign.Length - 1; i > -1; i--) - rgch[--ichDst] = negativeSign[i]; + ArrayPool.Shared.Return(bufferToReturn); } - int resultLength = cchMax - ichDst; - if (!targetSpan) - { - charsWritten = 0; - spanSuccess = false; - return new string(rgch, ichDst, cchMax - ichDst); - } - else if (new ReadOnlySpan(rgch, ichDst, cchMax - ichDst).TryCopyTo(destination)) - { - charsWritten = resultLength; - spanSuccess = true; - return null; - } - else + return strResult; + } + + private static unsafe TChar* BigIntegerToDecChars(TChar* bufferEnd, ReadOnlySpan base1E9Value, int digits) + where TChar : unmanaged, IUtfChar + { + Debug.Assert(base1E9Value[^1] != 0, "Leading zeros should be trimmed by caller."); + + // The base 10^9 value is in reverse order + for (int i = 0; i < base1E9Value.Length - 1; i++) { - charsWritten = 0; - spanSuccess = false; - return null; + bufferEnd = UInt32ToDecChars(bufferEnd, base1E9Value[i], kcchBase); + digits -= kcchBase; } + + return UInt32ToDecChars(bufferEnd, base1E9Value[^1], digits); } } diff --git a/src/libraries/System.Runtime.Numerics/src/System/Number.Polyfill.cs b/src/libraries/System.Runtime.Numerics/src/System/Number.Polyfill.cs index d5de46b5842eb5..9c1c2a89daf5ef 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Number.Polyfill.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Number.Polyfill.cs @@ -43,6 +43,21 @@ internal readonly struct Utf16Char(char ch) : IUtfChar public bool Equals(Utf16Char other) => value == other.value; } +#pragma warning disable CA1067 // Polyfill only type + internal readonly struct Utf8Char(byte ch) : IUtfChar +#pragma warning restore CA1067 + { + private readonly byte value = ch; + + public static Utf8Char CastFrom(byte value) => new(value); + public static Utf8Char CastFrom(char value) => new((byte)value); + public static Utf8Char CastFrom(int value) => new((byte)value); + public static Utf8Char CastFrom(uint value) => new((byte)value); + public static Utf8Char CastFrom(ulong value) => new((byte)value); + public static uint CastToUInt32(Utf8Char value) => value.value; + public bool Equals(Utf8Char other) => value == other.value; + } + internal static partial class Number { internal static bool AllowHyphenDuringParsing(this NumberFormatInfo info) diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index f599a02df8df0f..d3e06e69b43926 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -60,7 +60,7 @@ using System.Diagnostics.Eventing.Reader; // System.Text.Json is a .NET Core 3.0 specific library -#if NETCOREAPP +#if NET using System.Text.Json; #endif @@ -494,7 +494,7 @@ public static IEnumerable SerializableObjects() yield return new object[] { PopulateException(isolatedStorageException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAADJTeXN0ZW0uSU8uSXNvbGF0ZWRTdG9yYWdlLklzb2xhdGVkU3RvcmFnZUV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGAgAAADJTeXN0ZW0uSU8uSXNvbGF0ZWRTdG9yYWdlLklzb2xhdGVkU3RvcmFnZUV4Y2VwdGlvbgYDAAAAB21lc3NhZ2UJBAAAAAkFAAAABgYAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYHAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBggAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgkAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAQAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQoAAAACAAAAAgAAAAQFAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgsAAAAQU3lzdGVtLkV4Y2VwdGlvbgkDAAAACQ0AAAAJDgAAAAkGAAAACQcAAAAJCAAAAAAAAAAK6AMAAAkJAAAACgQKAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYTAAAABnNlY3JldAgBAQkUAAAAAQ0AAAAEAAAACRUAAAACAAAAAgAAAAEOAAAABQAAAAkLAAAABhcAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARQAAAAKAAAACAgBAAAABhgAAAADb25lCgEVAAAACgAAAAkTAAAACAEBCRoAAAABGgAAAAoAAAAICAEAAAAJGAAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAEAQAAADJTeXN0ZW0uSU8uSXNvbGF0ZWRTdG9yYWdlLklzb2xhdGVkU3RvcmFnZUV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGAgAAADJTeXN0ZW0uSU8uSXNvbGF0ZWRTdG9yYWdlLklzb2xhdGVkU3RvcmFnZUV4Y2VwdGlvbgYDAAAAB21lc3NhZ2UJBAAAAAkFAAAABgYAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYHAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBggAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgkAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAQAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQoAAAACAAAAAgAAAAQFAAAAEFN5c3RlbS5FeGNlcHRpb24MAAAACUNsYXNzTmFtZQdNZXNzYWdlBERhdGEOSW5uZXJFeGNlcHRpb24HSGVscFVSTBBTdGFja1RyYWNlU3RyaW5nFlJlbW90ZVN0YWNrVHJhY2VTdHJpbmcQUmVtb3RlU3RhY2tJbmRleA9FeGNlcHRpb25NZXRob2QHSFJlc3VsdAZTb3VyY2UNV2F0c29uQnVja2V0cwEBAwMBAQEAAQABBylTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCBgsAAAAQU3lzdGVtLkV4Y2VwdGlvbgkDAAAACQ0AAAAJDgAAAAkGAAAACQcAAAAJCAAAAAAAAAAK6AMAAAkJAAAACgQKAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYTAAAABnNlY3JldAgBAQkUAAAAAQ0AAAAEAAAACRUAAAACAAAAAgAAAAEOAAAABQAAAAkLAAAABhcAAAAXSW5uZXIgZXhjZXB0aW9uIG1lc3NhZ2UKCgoKCgAAAAAKABUTgAoKARQAAAAKAAAACAgBAAAABhgAAAADb25lCgEVAAAACgAAAAkTAAAACAEBCRoAAAABGgAAAAoAAAAICAEAAAAJGAAAAAoL", TargetFrameworkMoniker.netfx461) } }; } -#if NETCOREAPP +#if NET var jsonException = new JsonException("message", path: "path", lineNumber: 1, bytePositionInLine: 2, innerException: exception); yield return new object[] { PopulateException(jsonException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbhAAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCkxpbmVOdW1iZXISQnl0ZVBvc2l0aW9uSW5MaW5lBFBhdGgNQWN0dWFsTWVzc2FnZQEBAwMBAQEAAQABBwMDAQEpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgxTeXN0ZW0uSW50NjQMU3lzdGVtLkludDY0AgAAAAYDAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKCAkBAAAAAAAAAAgJAgAAAAAAAAAGCwAAAARwYXRoCQQAAAAEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJDQAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDgAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJEAAAAAkRAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBA0AAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhYAAAAGc2VjcmV0CAEBCRcAAAABEAAAAAUAAAAJGAAAAAIAAAACAAAAAREAAAAGAAAACQ4AAAAGGgAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFwAAAA0AAAAICAEAAAAGGwAAAANvbmUKARgAAAANAAAACRYAAAAIAQEJHQAAAAEdAAAADQAAAAgIAQAAAAkbAAAACgs=", TargetFrameworkMoniker.netcoreapp30) } }; @@ -677,7 +677,7 @@ public static IEnumerable SerializableObjects() yield return new object[] { PopulateException(smtpFailedRecipientsException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAtU3lzdGVtLk5ldC5NYWlsLlNtdHBGYWlsZWRSZWNpcGllbnRzRXhjZXB0aW9uDwAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMGU3RhdHVzD2ZhaWxlZFJlY2lwaWVudA9pbm5lckV4Y2VwdGlvbnMBAQMEAQEBAAEAAQcAAQQpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwsU3lzdGVtLk5ldC5NYWlsLlNtdHBGYWlsZWRSZWNpcGllbnRFeGNlcHRpb24CAAAACAgCCC5TeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudEV4Y2VwdGlvbltdAgAAAAIAAAAGAwAAAC1TeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudHNFeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCv////8GCwAAAA9mYWlsZWRSZWNpcGllbnQJDAAAAAQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkNAAAAAgAAAAIAAAAFBgAAACxTeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudEV4Y2VwdGlvbg4AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzBlN0YXR1cw9mYWlsZWRSZWNpcGllbnQBAQMDAQEBAAEAAQcAASlTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCCAIAAAAGDgAAACxTeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudEV4Y2VwdGlvbgYPAAAAMkNvbXBsZXRlZC4gVGhlIHNlcnZlciByZXNwb25zZSB3YXM6IHNlcnZlclJlc3BvbnNlCRAAAAAKCQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAK+gAAAAkLAAAABwwAAAAAAQAAAAEAAAAELFN5c3RlbS5OZXQuTWFpbC5TbXRwRmFpbGVkUmVjaXBpZW50RXhjZXB0aW9uAgAAAAkGAAAABA0AAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhcAAAAGc2VjcmV0CAEBCRgAAAABEAAAAAUAAAAJGQAAAAIAAAACAAAAARgAAAANAAAACAgBAAAABhoAAAADb25lCgEZAAAADQAAAAkXAAAACAEBCRwAAAABHAAAAA0AAAAICAEAAAAJGgAAAAoL", TargetFrameworkMoniker.netcoreapp20), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAtU3lzdGVtLk5ldC5NYWlsLlNtdHBGYWlsZWRSZWNpcGllbnRzRXhjZXB0aW9uDwAAAAlDbGFzc05hbWUHTWVzc2FnZQREYXRhDklubmVyRXhjZXB0aW9uB0hlbHBVUkwQU3RhY2tUcmFjZVN0cmluZxZSZW1vdGVTdGFja1RyYWNlU3RyaW5nEFJlbW90ZVN0YWNrSW5kZXgPRXhjZXB0aW9uTWV0aG9kB0hSZXN1bHQGU291cmNlDVdhdHNvbkJ1Y2tldHMGU3RhdHVzD2ZhaWxlZFJlY2lwaWVudA9pbm5lckV4Y2VwdGlvbnMBAQMEAQEBAAEAAQcAAQQpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwsU3lzdGVtLk5ldC5NYWlsLlNtdHBGYWlsZWRSZWNpcGllbnRFeGNlcHRpb24CAAAACAgCCC5TeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudEV4Y2VwdGlvbltdAgAAAAIAAAAGAwAAAC1TeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudHNFeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAJBgAAAAYHAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GCAAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYJAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYKAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCv////8GCwAAAA9mYWlsZWRSZWNpcGllbnQJDAAAAAQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkNAAAAAgAAAAIAAAAFBgAAACxTeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudEV4Y2VwdGlvbg4AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzBlN0YXR1cw9mYWlsZWRSZWNpcGllbnQBAQMDAQEBAAEAAQcAASlTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbBBTeXN0ZW0uRXhjZXB0aW9uCAgCCAIAAAAGDgAAACxTeXN0ZW0uTmV0Lk1haWwuU210cEZhaWxlZFJlY2lwaWVudEV4Y2VwdGlvbgYPAAAAMkNvbXBsZXRlZC4gVGhlIHNlcnZlciByZXNwb25zZSB3YXM6IHNlcnZlclJlc3BvbnNlCRAAAAAKCQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAK+gAAAAkLAAAABwwAAAAAAQAAAAEAAAAELFN5c3RlbS5OZXQuTWFpbC5TbXRwRmFpbGVkUmVjaXBpZW50RXhjZXB0aW9uAgAAAAkGAAAABA0AAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhcAAAAGc2VjcmV0CAEBCRgAAAABEAAAAAUAAAAJGQAAAAIAAAACAAAAARgAAAANAAAACAgBAAAABhoAAAADb25lCgEZAAAADQAAAAkXAAAACAEBCRwAAAABHAAAAA0AAAAICAEAAAAJGgAAAAoL", TargetFrameworkMoniker.netfx461) } }; } -#if NETCOREAPP +#if NET var ambiguousImplementationException = new AmbiguousImplementationException(); yield return new object[] { PopulateException(ambiguousImplementationException, false), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uUnVudGltZSwgVmVyc2lvbj00LjIuMS4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAC9TeXN0ZW0uUnVudGltZS5BbWJpZ3VvdXNJbXBsZW1lbnRhdGlvbkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAAAvU3lzdGVtLlJ1bnRpbWUuQW1iaWd1b3VzSW1wbGVtZW50YXRpb25FeGNlcHRpb24GBAAAAB9BbWJpZ3VvdXMgaW1wbGVtZW50YXRpb24gZm91bmQuCQUAAAAKBgYAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYHAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBggAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAApqEBOABgkAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKBAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQoAAAACAAAAAgAAAAQKAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYLAAAABnNlY3JldAgBAQkMAAAAAQwAAAAKAAAACAgBAAAABg0AAAADb25lCgs=", TargetFrameworkMoniker.netcoreapp30) } }; var switchExpressionException = new SwitchExpressionException(34); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs index e6d9652007e396..cbb1b2bba6b2ad 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs @@ -23,7 +23,7 @@ using Xunit; // System.Text.Json is a .NET Core 3.0 specific library -#if NETCOREAPP +#if NET using System.Text.Json; #endif @@ -1195,7 +1195,7 @@ public static void IsEqual(this AggregateException @this, AggregateException oth @this.InnerExceptions.CheckSequenceEquals(other.InnerExceptions, isSamePlatform); } -#if NETCOREAPP +#if NET public static void IsEqual(this JsonException @this, JsonException other, bool isSamePlatform) { if (@this == null && other == null) diff --git a/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj b/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj index 08ff96e95af3e1..ca2ed33befc50b 100644 --- a/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj +++ b/src/libraries/System.Runtime.Serialization.Primitives/src/System.Runtime.Serialization.Primitives.csproj @@ -22,6 +22,7 @@ + diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 1080983cb9bb2c..a3f2a4b07e2f48 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -4,6 +4,8 @@ // Changes to this file must follow the https://aka.ms/api-review process. // ------------------------------------------------------------------------------ +using System.Numerics; + namespace Microsoft.Win32.SafeHandles { public abstract partial class CriticalHandleMinusOneIsInvalid : System.Runtime.InteropServices.CriticalHandle @@ -1985,6 +1987,8 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S public static int Compare(decimal d1, decimal d2) { throw null; } public int CompareTo(decimal value) { throw null; } public int CompareTo(object? value) { throw null; } + public static TInteger ConvertToInteger(decimal value) where TInteger : System.Numerics.IBinaryInteger { throw null; } + public static TInteger ConvertToIntegerNative(decimal value) where TInteger : System.Numerics.IBinaryInteger { throw null; } public static decimal CopySign(decimal value, decimal sign) { throw null; } public static decimal CreateChecked(TOther value) where TOther : System.Numerics.INumberBase { throw null; } public static decimal CreateSaturating(TOther value) where TOther : System.Numerics.INumberBase { throw null; } @@ -2163,6 +2167,7 @@ protected Delegate([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAt [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("b")] public static System.Delegate? Combine(System.Delegate? a, System.Delegate? b) { throw null; } public static System.Delegate? Combine(params System.Delegate?[]? delegates) { throw null; } + public static System.Delegate? Combine(System.ReadOnlySpan delegates) { throw null; } protected virtual System.Delegate CombineImpl(System.Delegate? d) { throw null; } public static System.Delegate CreateDelegate(System.Type type, object? firstArgument, System.Reflection.MethodInfo method) { throw null; } public static System.Delegate? CreateDelegate(System.Type type, object? firstArgument, System.Reflection.MethodInfo method, bool throwOnBindFailure) { throw null; } @@ -2258,6 +2263,8 @@ public DivideByZeroException(string? message, System.Exception? innerException) public static double Clamp(double value, double min, double max) { throw null; } public int CompareTo(double value) { throw null; } public int CompareTo(object? value) { throw null; } + public static TInteger ConvertToInteger(double value) where TInteger : System.Numerics.IBinaryInteger { throw null; } + public static TInteger ConvertToIntegerNative(double value) where TInteger : System.Numerics.IBinaryInteger { throw null; } public static double CopySign(double value, double sign) { throw null; } public static double Cos(double x) { throw null; } public static double Cosh(double x) { throw null; } @@ -2880,6 +2887,8 @@ public enum GCNotificationStatus public static System.Half Clamp(System.Half value, System.Half min, System.Half max) { throw null; } public int CompareTo(System.Half other) { throw null; } public int CompareTo(object? obj) { throw null; } + public static TInteger ConvertToInteger(System.Half value) where TInteger : System.Numerics.IBinaryInteger { throw null; } + public static TInteger ConvertToIntegerNative(System.Half value) where TInteger : System.Numerics.IBinaryInteger { throw null; } public static System.Half CopySign(System.Half value, System.Half sign) { throw null; } public static System.Half Cos(System.Half x) { throw null; } public static System.Half Cosh(System.Half x) { throw null; } @@ -4997,6 +5006,8 @@ public SerializableAttribute() { } public static float Clamp(float value, float min, float max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(float value) { throw null; } + public static TInteger ConvertToInteger(float value) where TInteger : System.Numerics.IBinaryInteger { throw null; } + public static TInteger ConvertToIntegerNative(float value) where TInteger : System.Numerics.IBinaryInteger { throw null; } public static float CopySign(float value, float sign) { throw null; } public static float Cos(float x) { throw null; } public static float Cosh(float x) { throw null; } @@ -5242,6 +5253,7 @@ public unsafe String(sbyte* value, int startIndex, int length, System.Text.Encod public static string Concat(object? arg0, object? arg1) { throw null; } public static string Concat(object? arg0, object? arg1, object? arg2) { throw null; } public static string Concat(params object?[] args) { throw null; } + public static string Concat(System.ReadOnlySpan args) { throw null; } public static string Concat(System.ReadOnlySpan str0, System.ReadOnlySpan str1) { throw null; } public static string Concat(System.ReadOnlySpan str0, System.ReadOnlySpan str1, System.ReadOnlySpan str2) { throw null; } public static string Concat(System.ReadOnlySpan str0, System.ReadOnlySpan str1, System.ReadOnlySpan str2, System.ReadOnlySpan str3) { throw null; } @@ -5249,6 +5261,7 @@ public unsafe String(sbyte* value, int startIndex, int length, System.Text.Encod public static string Concat(string? str0, string? str1, string? str2) { throw null; } public static string Concat(string? str0, string? str1, string? str2, string? str3) { throw null; } public static string Concat(params string?[] values) { throw null; } + public static string Concat(System.ReadOnlySpan values) { throw null; } public static string Concat(System.Collections.Generic.IEnumerable values) { throw null; } public bool Contains(char value) { throw null; } public bool Contains(char value, System.StringComparison comparisonType) { throw null; } @@ -5276,12 +5289,14 @@ public void CopyTo(System.Span destination) { } public static string Format(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { throw null; } public static string Format(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { throw null; } public static string Format(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] args) { throw null; } + public static string Format(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan args) { throw null; } public static string Format(System.IFormatProvider? provider, System.Text.CompositeFormat format, params object?[] args) { throw null; } public static string Format(System.IFormatProvider? provider, System.Text.CompositeFormat format, System.ReadOnlySpan args) { throw null; } public static string Format([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0) { throw null; } public static string Format([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { throw null; } public static string Format([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { throw null; } public static string Format([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] args) { throw null; } + public static string Format([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan args) { throw null; } public static string Format(System.IFormatProvider? provider, System.Text.CompositeFormat format, TArg0 arg0) { throw null; } public static string Format(System.IFormatProvider? provider, System.Text.CompositeFormat format, TArg0 arg0, TArg1 arg1) { throw null; } public static string Format(System.IFormatProvider? provider, System.Text.CompositeFormat format, TArg0 arg0, TArg1 arg1, TArg2 arg2) { throw null; } @@ -5314,11 +5329,15 @@ public void CopyTo(System.Span destination) { } public static bool IsNullOrEmpty([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] string? value) { throw null; } public static bool IsNullOrWhiteSpace([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(false)] string? value) { throw null; } public static string Join(char separator, params object?[] values) { throw null; } + public static string Join(char separator, System.ReadOnlySpan values) { throw null; } public static string Join(char separator, params string?[] value) { throw null; } + public static string Join(char separator, System.ReadOnlySpan value) { throw null; } public static string Join(char separator, string?[] value, int startIndex, int count) { throw null; } public static string Join(string? separator, System.Collections.Generic.IEnumerable values) { throw null; } public static string Join(string? separator, params object?[] values) { throw null; } + public static string Join(string? separator, System.ReadOnlySpan values) { throw null; } public static string Join(string? separator, params string?[] value) { throw null; } + public static string Join(string? separator, System.ReadOnlySpan value) { throw null; } public static string Join(string? separator, string?[] value, int startIndex, int count) { throw null; } public static string Join(char separator, System.Collections.Generic.IEnumerable values) { throw null; } public static string Join(string? separator, System.Collections.Generic.IEnumerable values) { throw null; } @@ -5354,6 +5373,7 @@ public void CopyTo(System.Span destination) { } public string[] Split(char separator, int count, System.StringSplitOptions options = System.StringSplitOptions.None) { throw null; } public string[] Split(char separator, System.StringSplitOptions options = System.StringSplitOptions.None) { throw null; } public string[] Split(params char[]? separator) { throw null; } + public string[] Split(System.ReadOnlySpan separator) { throw null; } public string[] Split(char[]? separator, int count) { throw null; } public string[] Split(char[]? separator, int count, System.StringSplitOptions options) { throw null; } public string[] Split(char[]? separator, System.StringSplitOptions options) { throw null; } @@ -5401,12 +5421,15 @@ public void CopyTo(System.Span destination) { } public string Trim() { throw null; } public string Trim(char trimChar) { throw null; } public string Trim(params char[]? trimChars) { throw null; } + public string Trim(System.ReadOnlySpan trimChars) { throw null; } public string TrimEnd() { throw null; } public string TrimEnd(char trimChar) { throw null; } public string TrimEnd(params char[]? trimChars) { throw null; } + public string TrimEnd(System.ReadOnlySpan trimChars) { throw null; } public string TrimStart() { throw null; } public string TrimStart(char trimChar) { throw null; } public string TrimStart(params char[]? trimChars) { throw null; } + public string TrimStart(System.ReadOnlySpan trimChars) { throw null; } public bool TryCopyTo(System.Span destination) { throw null; } } public abstract partial class StringComparer : System.Collections.Generic.IComparer, System.Collections.Generic.IEqualityComparer, System.Collections.IComparer, System.Collections.IEqualityComparer @@ -7527,6 +7550,7 @@ public override void Write(string? s) { } public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0) { } public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] arg) { } + public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } public override System.Threading.Tasks.Task WriteAsync(char value) { throw null; } public override System.Threading.Tasks.Task WriteAsync(char[] buffer, int index, int count) { throw null; } public override System.Threading.Tasks.Task WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -7546,6 +7570,7 @@ public override void WriteLine(string? s) { } public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0) { } public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] arg) { } + public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } [System.CLSCompliantAttribute(false)] public override void WriteLine(uint value) { } public override System.Threading.Tasks.Task WriteLineAsync() { throw null; } @@ -10112,6 +10137,7 @@ public static partial class Path public static string Combine(string path1, string path2, string path3) { throw null; } public static string Combine(string path1, string path2, string path3, string path4) { throw null; } public static string Combine(params string[] paths) { throw null; } + public static string Combine(System.ReadOnlySpan paths) { throw null; } public static bool EndsInDirectorySeparator(System.ReadOnlySpan path) { throw null; } public static bool EndsInDirectorySeparator([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? path) { throw null; } public static bool Exists([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? path) { throw null; } @@ -10149,6 +10175,7 @@ public static partial class Path public static string Join(string? path1, string? path2, string? path3) { throw null; } public static string Join(string? path1, string? path2, string? path3, string? path4) { throw null; } public static string Join(params string?[] paths) { throw null; } + public static string Join(System.ReadOnlySpan paths) { throw null; } public static System.ReadOnlySpan TrimEndingDirectorySeparator(System.ReadOnlySpan path) { throw null; } public static string TrimEndingDirectorySeparator(string path) { throw null; } public static bool TryJoin(System.ReadOnlySpan path1, System.ReadOnlySpan path2, System.ReadOnlySpan path3, System.Span destination, out int charsWritten) { throw null; } @@ -10315,6 +10342,7 @@ public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribut public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { } public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] arg) { } + public override void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } public override System.Threading.Tasks.Task WriteAsync(char value) { throw null; } public override System.Threading.Tasks.Task WriteAsync(char[] buffer, int index, int count) { throw null; } public override System.Threading.Tasks.Task WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -10325,6 +10353,7 @@ public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttr public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { } public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] arg) { } + public override void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } public override System.Threading.Tasks.Task WriteLineAsync() { throw null; } public override System.Threading.Tasks.Task WriteLineAsync(char value) { throw null; } public override System.Threading.Tasks.Task WriteLineAsync(char[] buffer, int index, int count) { throw null; } @@ -10442,6 +10471,7 @@ public virtual void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute public virtual void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public virtual void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { } public virtual void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] arg) { } + public virtual void Write([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } public virtual void Write(System.Text.StringBuilder? value) { } [System.CLSCompliantAttribute(false)] public virtual void Write(uint value) { } @@ -10470,6 +10500,7 @@ public virtual void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttri public virtual void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { } public virtual void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { } public virtual void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] arg) { } + public virtual void WriteLine([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan arg) { } public virtual void WriteLine(System.Text.StringBuilder? value) { } [System.CLSCompliantAttribute(false)] public virtual void WriteLine(uint value) { } @@ -10788,6 +10819,8 @@ public partial interface IFloatingPointIeee754 : System.IComparable, Syst public partial interface IFloatingPoint : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IFloatingPointConstants, System.Numerics.IIncrementOperators, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.ISignedNumber, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.IFloatingPoint? { static virtual TSelf Ceiling(TSelf x) { throw null; } + static virtual TInteger ConvertToInteger(TSelf value) where TInteger : System.Numerics.IBinaryInteger { throw null; } + static virtual TInteger ConvertToIntegerNative(TSelf value) where TInteger : System.Numerics.IBinaryInteger { throw null; } static virtual TSelf Floor(TSelf x) { throw null; } int GetExponentByteCount(); int GetExponentShortestBitLength(); @@ -14915,19 +14948,25 @@ public StringBuilder(string? value, int startIndex, int length, int capacity) { public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { throw null; } public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { throw null; } public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] args) { throw null; } + public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan args) { throw null; } public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, System.Text.CompositeFormat format, params object?[] args) { throw null; } public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, System.Text.CompositeFormat format, System.ReadOnlySpan args) { throw null; } public System.Text.StringBuilder AppendFormat([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0) { throw null; } public System.Text.StringBuilder AppendFormat([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1) { throw null; } public System.Text.StringBuilder AppendFormat([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, object? arg0, object? arg1, object? arg2) { throw null; } public System.Text.StringBuilder AppendFormat([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, params object?[] args) { throw null; } + public System.Text.StringBuilder AppendFormat([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, System.ReadOnlySpan args) { throw null; } public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, System.Text.CompositeFormat format, TArg0 arg0) { throw null; } public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, System.Text.CompositeFormat format, TArg0 arg0, TArg1 arg1) { throw null; } public System.Text.StringBuilder AppendFormat(System.IFormatProvider? provider, System.Text.CompositeFormat format, TArg0 arg0, TArg1 arg1, TArg2 arg2) { throw null; } public System.Text.StringBuilder AppendJoin(char separator, params object?[] values) { throw null; } public System.Text.StringBuilder AppendJoin(char separator, params string?[] values) { throw null; } + public System.Text.StringBuilder AppendJoin(char separator, System.ReadOnlySpan values) { throw null; } + public System.Text.StringBuilder AppendJoin(char separator, System.ReadOnlySpan values) { throw null; } public System.Text.StringBuilder AppendJoin(string? separator, params object?[] values) { throw null; } public System.Text.StringBuilder AppendJoin(string? separator, params string?[] values) { throw null; } + public System.Text.StringBuilder AppendJoin(string? separator, System.ReadOnlySpan values) { throw null; } + public System.Text.StringBuilder AppendJoin(string? separator, System.ReadOnlySpan values) { throw null; } public System.Text.StringBuilder AppendJoin(char separator, System.Collections.Generic.IEnumerable values) { throw null; } public System.Text.StringBuilder AppendJoin(string? separator, System.Collections.Generic.IEnumerable values) { throw null; } public System.Text.StringBuilder AppendLine() { throw null; } @@ -15103,6 +15142,7 @@ public void CancelAfter(System.TimeSpan delay) { } public System.Threading.Tasks.Task CancelAsync() { throw null; } public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(System.Threading.CancellationToken token) { throw null; } public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(System.Threading.CancellationToken token1, System.Threading.CancellationToken token2) { throw null; } + public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(System.ReadOnlySpan tokens) { throw null; } public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(params System.Threading.CancellationToken[] tokens) { throw null; } public void Dispose() { } protected virtual void Dispose(bool disposing) { } @@ -15309,6 +15349,8 @@ public void Wait(System.Threading.CancellationToken cancellationToken) { } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static void WaitAll(System.Collections.Generic.IEnumerable tasks, System.Threading.CancellationToken cancellationToken = default) { } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public static void WaitAll(System.ReadOnlySpan tasks) { } + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static void WaitAll(params System.Threading.Tasks.Task[] tasks) { } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static bool WaitAll(System.Threading.Tasks.Task[] tasks, int millisecondsTimeout) { throw null; } @@ -15329,14 +15371,18 @@ public static void WaitAll(System.Threading.Tasks.Task[] tasks, System.Threading public System.Threading.Tasks.Task WaitAsync(System.TimeSpan timeout, System.TimeProvider timeProvider) { throw null; } public System.Threading.Tasks.Task WaitAsync(System.TimeSpan timeout, System.TimeProvider timeProvider, System.Threading.CancellationToken cancellationToken) { throw null; } public static System.Threading.Tasks.Task WhenAll(System.Collections.Generic.IEnumerable tasks) { throw null; } + public static System.Threading.Tasks.Task WhenAll(System.ReadOnlySpan tasks) { throw null; } public static System.Threading.Tasks.Task WhenAll(params System.Threading.Tasks.Task[] tasks) { throw null; } public static System.Threading.Tasks.Task WhenAll(System.Collections.Generic.IEnumerable> tasks) { throw null; } + public static System.Threading.Tasks.Task WhenAll(System.ReadOnlySpan> tasks) { throw null; } public static System.Threading.Tasks.Task WhenAll(params System.Threading.Tasks.Task[] tasks) { throw null; } public static System.Threading.Tasks.Task WhenAny(System.Collections.Generic.IEnumerable tasks) { throw null; } public static System.Threading.Tasks.Task WhenAny(System.Threading.Tasks.Task task1, System.Threading.Tasks.Task task2) { throw null; } + public static System.Threading.Tasks.Task WhenAny(System.ReadOnlySpan tasks) { throw null; } public static System.Threading.Tasks.Task WhenAny(params System.Threading.Tasks.Task[] tasks) { throw null; } public static System.Threading.Tasks.Task> WhenAny(System.Collections.Generic.IEnumerable> tasks) { throw null; } public static System.Threading.Tasks.Task> WhenAny(System.Threading.Tasks.Task task1, System.Threading.Tasks.Task task2) { throw null; } + public static System.Threading.Tasks.Task> WhenAny(System.ReadOnlySpan> tasks) { throw null; } public static System.Threading.Tasks.Task> WhenAny(params System.Threading.Tasks.Task[] tasks) { throw null; } public static System.Collections.Generic.IAsyncEnumerable WhenEach(System.Collections.Generic.IEnumerable tasks) { throw null; } public static System.Collections.Generic.IAsyncEnumerable WhenEach(params System.Threading.Tasks.Task[] tasks) { throw null; } diff --git a/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.Context/Conformance.dynamic.context.method.regmethod.regclass.cs b/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.Context/Conformance.dynamic.context.method.regmethod.regclass.cs index 4ab40934105281..6cf3503569751f 100644 --- a/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.Context/Conformance.dynamic.context.method.regmethod.regclass.cs +++ b/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.Context/Conformance.dynamic.context.method.regmethod.regclass.cs @@ -714,7 +714,9 @@ public static void CalledFrom_UsingExpression() { using (StreamWriter sw = new StreamWriter(sm)) { +#pragma warning disable CS9220 // One or more overloads of method having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. sw.WriteLine(mc.Method_ReturnString('a')); +#pragma warning restore CS9220 sw.Flush(); sm.Position = 0; using (StreamReader sr = new StreamReader(sm, (bool)mc.Method_ReturnBool())) diff --git a/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.OverloadResolution/Conformance.dynamic.overloadResolution.Operators.basic.cs b/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.OverloadResolution/Conformance.dynamic.overloadResolution.Operators.basic.cs index 1230648a1f443b..5d5933aaf4eea2 100644 --- a/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.OverloadResolution/Conformance.dynamic.overloadResolution.Operators.basic.cs +++ b/src/libraries/System.Runtime/tests/System.Dynamic.Runtime.Tests/Dynamic.OverloadResolution/Conformance.dynamic.overloadResolution.Operators.basic.cs @@ -1169,7 +1169,9 @@ public static void ExecPositiveTest(dynamic dobj, Type exp_type, T exp_underv } else { +#pragma warning disable CS9220 // One or more overloads of method having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. System.Console.WriteLine("Got invalid result when testing {0}: {1}[{2}]", tip, dr, dr.GetType()); +#pragma warning restore CS9220 } } catch (Exception ex) @@ -1186,7 +1188,9 @@ public static void ExecNegativeTestWithBadOps(dynamic dobj, string[] exp_msg, st try { dynamic dr = test(dobj); +#pragma warning disable CS9220 // One or more overloads of method having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. System.Console.WriteLine("Got invalid result when testing {0}: {1}[{2}]", tip, dr, dr.GetType()); +#pragma warning restore CS9220 } catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex) { diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj b/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj index 5b898363764087..7e10ef4ac1dd59 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj @@ -4,6 +4,14 @@ true true true + + + + WasmTestOnChrome + $(TestArchiveRoot)browserornodejs/ + $(TestArchiveTestsRoot)$(OSPlatformConfig)/ + $(DefineConstants);TARGET_BROWSER + true diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoNativeCalendarName.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoNativeCalendarName.cs index 86507dc1308f11..377e6d30d597bc 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoNativeCalendarName.cs +++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoNativeCalendarName.cs @@ -11,10 +11,10 @@ public class DateTimeFormatInfoNativeCalendarName public static IEnumerable NativeCalendarName_Get_TestData_HybridGlobalization() { // see the comments on the right to check the non-Hybrid result, in this collection it always differs - string islamicName = "islamic-umalqura"; - string gregorianName = "gregory"; - string persianName = "persian"; - string bhuddistName = "buddhist"; + string islamicName = PlatformDetection.IsFirefox ? "UMALQURA" : "islamic-umalqura"; + string gregorianName = PlatformDetection.IsFirefox ? "GREGORIAN" : "gregory"; + string persianName = PlatformDetection.IsFirefox ? "PERSIAN" : "persian"; + string bhuddistName = PlatformDetection.IsFirefox ? "THAI" : "buddhist"; yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, islamicName }; // التقويم الإسلامي (أم القرى) yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, gregorianName }; // የግሪጎሪያን የቀን አቆጣጠር yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, gregorianName }; // григориански календар diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj b/src/libraries/System.Runtime/tests/System.Globalization.Tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj index a39604c1cfaccd..fdc037e655558d 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj @@ -6,6 +6,14 @@ true true + + + WasmTestOnChrome + $(TestArchiveRoot)browserornodejs/ + $(TestArchiveTestsRoot)$(OSPlatformConfig)/ + $(DefineConstants);TARGET_BROWSER + true + diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/System.Globalization.Tests.csproj b/src/libraries/System.Runtime/tests/System.Globalization.Tests/System.Globalization.Tests.csproj index 12da4639cb3611..6c0b2eab95b424 100644 --- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/System.Globalization.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/System.Globalization.Tests.csproj @@ -11,7 +11,8 @@ - + + diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj index b029dd3341a710..614de3d1ce979f 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/DisabledFileLockingTests/System.IO.FileSystem.DisabledFileLocking.Tests.csproj @@ -34,7 +34,8 @@ - + + diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj index 0e4d3e3770cd61..b4f627b831f2e5 100644 --- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj @@ -245,6 +245,7 @@ - + + diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs index 0de5d90f77bbdb..84ebd066786a22 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/IndentedTextWriter.cs @@ -104,6 +104,12 @@ public override void Write(string format, params object[] arg) LastCalledMethod = nameof(Write); } + public override void Write(string format, /*params*/ ReadOnlySpan arg) + { + base.Write(format, arg); + LastCalledMethod = nameof(Write); + } + public override void Write(string value) { base.Write(value); @@ -212,6 +218,12 @@ public override void WriteLine(string format, params object[] arg) LastCalledMethod = nameof(WriteLine); } + public override void WriteLine(string format, /*params*/ ReadOnlySpan arg) + { + base.WriteLine(format, arg); + LastCalledMethod = nameof(WriteLine); + } + public override void WriteLine(string value) { base.WriteLine(value); @@ -416,7 +428,8 @@ public static async Task Writes_ProducesExpectedOutput(string newline) itw.Write("{0}", 14); itw.Write("{0} {1}", 15, 16); itw.Write("{0} {1} {2}", 15, 16, 17); - itw.Write("{0} {1} {2} {3}", 15, 16, 17, 18); + itw.Write("{0} {1} {2} {3}", new object[] { 15, 16, 17, 18 }); + itw.Write("{0} {1} {2} {3}", (ReadOnlySpan)new object[] { 15, 16, 17, 18 }); itw.WriteLine(true); itw.WriteLine('a'); @@ -434,7 +447,8 @@ public static async Task Writes_ProducesExpectedOutput(string newline) itw.WriteLine("{0}", 14); itw.WriteLine("{0} {1}", 15, 16); itw.WriteLine("{0} {1} {2}", 15, 16, 17); - itw.WriteLine("{0} {1} {2} {3}", 15, 16, 17, 18); + itw.WriteLine("{0} {1} {2} {3}", new object[] { 15, 16, 17, 18 }); + itw.WriteLine("{0} {1} {2} {3}", (ReadOnlySpan)new object[] { 15, 16, 17, 18 }); await itw.WriteAsync('a'); await itw.WriteAsync(new char[] { 'b', 'c' }); @@ -450,7 +464,7 @@ public static async Task Writes_ProducesExpectedOutput(string newline) Assert.Equal( "t" + newline + - "tTrueabcde45.66.789101112131415 1615 16 1715 16 17 18True" + newline + + "tTrueabcde45.66.789101112131415 1615 16 1715 16 17 1815 16 17 18True" + newline + "ta" + newline + "tbc" + newline + "tde" + newline + @@ -467,6 +481,7 @@ public static async Task Writes_ProducesExpectedOutput(string newline) "t15 16" + newline + "t15 16 17" + newline + "t15 16 17 18" + newline + + "t15 16 17 18" + newline + "tabcde1a" + newline + "tbc" + newline + "tde" + newline + @@ -499,7 +514,8 @@ object[] CreateParameters(Action callWrite, string expected) yield return CreateParameters(x => x.Write("Hello {0} World", "Digital"), "Hello Digital World"); yield return CreateParameters(x => x.Write("Hello {0} World{1}", "Digital", "!!"), "Hello Digital World!!"); yield return CreateParameters(x => x.Write("Hello {0} {1} World{2}", "Dot", "NET", "!!"), "Hello Dot NET World!!"); - yield return CreateParameters(x => x.Write("Hello {0} {1} {2} World{3}", "Digital", "Dot", "NET", "!!"), "Hello Digital Dot NET World!!"); + yield return CreateParameters(x => x.Write("Hello {0} {1} {2} World{3}", new object[] { "Digital", "Dot", "NET", "!!" }), "Hello Digital Dot NET World!!"); + yield return CreateParameters(x => x.Write("Hello {0} {1} {2} World{3}", (ReadOnlySpan)new object[] { "Digital", "Dot", "NET", "!!" }), "Hello Digital Dot NET World!!"); yield return CreateParameters(x => x.Write("Hello World".ToCharArray(), 6, 5), "World"); } } @@ -530,7 +546,8 @@ object[] CreateParameters(Action callWriteLine, string expec yield return CreateParameters(x => x.WriteLine("Hello {0} {1} World", "Dot", "NET"), $"Hello Dot NET World{NewLine}"); yield return CreateParameters(x => x.WriteLine("Hello {0} {1} World{2}", "Dot", "NET", "!!"), $"Hello Dot NET World!!{NewLine}"); yield return CreateParameters(x => x.WriteLine("Hello World".ToCharArray(), 6, 5), $"World{NewLine}"); - yield return CreateParameters(x => x.WriteLine("Hello {0} {1} {2} World{3}", "Digital", "Dot", "NET", "!!"), $"Hello Digital Dot NET World!!{NewLine}"); + yield return CreateParameters(x => x.WriteLine("Hello {0} {1} {2} World{3}", new object[] { "Digital", "Dot", "NET", "!!" }), $"Hello Digital Dot NET World!!{NewLine}"); + yield return CreateParameters(x => x.WriteLine("Hello {0} {1} {2} World{3}", (ReadOnlySpan)new object[] { "Digital", "Dot", "NET", "!!" }), $"Hello Digital Dot NET World!!{NewLine}"); } } diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/Stream/Stream.NullTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/Stream/Stream.NullTests.cs index 86ebfba5efbefb..3714ff3b2020dc 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/Stream/Stream.NullTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/Stream/Stream.NullTests.cs @@ -234,7 +234,8 @@ public static void TextNullTextWriter(TextWriter output) output.Write(" {0} ", "Friday"); output.Write(" {0}{1} ", "Saturday", "Sunday"); output.Write(" {0} {1} {2}", TimeSpan.FromSeconds(1), TimeSpan.FromMinutes(2), TimeSpan.FromDays(3)); - output.Write(" {0} {1} {2} {3}", (Int128)4, (UInt128)5, (nint)6, (nuint)7); + output.Write(" {0} {1} {2} {3}", new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7 }); + output.Write(" {0} {1} {2} {3} {4}", (ReadOnlySpan)new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7, "8" }); output.WriteLine(); output.WriteLine(true); output.WriteLine('a'); @@ -256,7 +257,8 @@ public static void TextNullTextWriter(TextWriter output) output.WriteLine(" {0} ", "Friday"); output.WriteLine(" {0}{1} ", "Saturday", "Sunday"); output.WriteLine(" {0} {1} {2}", TimeSpan.FromSeconds(1), TimeSpan.FromMinutes(2), TimeSpan.FromDays(3)); - output.WriteLine(" {0} {1} {2} {3}", (Int128)4, (UInt128)5, (nint)6, (nuint)7); + output.WriteLine(" {0} {1} {2} {3}", new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7 }); + output.WriteLine(" {0} {1} {2} {3} {4}", (ReadOnlySpan)new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7, "8" }); Assert.True(output.WriteAsync('a').IsCompletedSuccessfully); Assert.True(output.WriteAsync((char[])null).IsCompletedSuccessfully); Assert.True(output.WriteAsync(new char[] { 'b', 'c' }).IsCompletedSuccessfully); diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs index 0d34fe6730f0ac..69edb13a8a1fce 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/StreamWriter/StreamWriter.cs @@ -58,20 +58,28 @@ public void FormatOverloadsCallWrite() Assert.Equal(2, writer.WriteCalls); writer.Write("{0}{1}{2}", "Zero", "One", "Two"); Assert.Equal(3, writer.WriteCalls); - writer.Write("{0}{1}{2}{3}", "Zero", "One", "Two", "Three"); + writer.Write("{0}{1}{2}{3}", new object[] { "Zero", "One", "Two", "Three" }); Assert.Equal(4, writer.WriteCalls); - writer.Write("{0}{1}{2}{3}{4}", "Zero", "One", "Two", "Three", "Four"); + writer.Write("{0}{1}{2}{3}", (ReadOnlySpan)new object[] { "Zero", "One", "Two", "Three" }); Assert.Equal(5, writer.WriteCalls); + writer.Write("{0}{1}{2}{3}{4}", new object[] { "Zero", "One", "Two", "Three", "Four" }); + Assert.Equal(6, writer.WriteCalls); + writer.Write("{0}{1}{2}{3}{4}", (ReadOnlySpan)new object[] { "Zero", "One", "Two", "Three", "Four" }); + Assert.Equal(7, writer.WriteCalls); writer.WriteLine("{0}", "Zero"); Assert.Equal(1, writer.WriteLineCalls); writer.WriteLine("{0}{1}", "Zero", "One"); Assert.Equal(2, writer.WriteLineCalls); writer.WriteLine("{0}{1}{2}", "Zero", "One", "Two"); Assert.Equal(3, writer.WriteLineCalls); - writer.WriteLine("{0}{1}{2}{3}", "Zero", "One", "Two", "Three"); + writer.WriteLine("{0}{1}{2}{3}", new object[] { "Zero", "One", "Two", "Three" }); Assert.Equal(4, writer.WriteLineCalls); - writer.WriteLine("{0}{1}{2}{3}{4}", "Zero", "One", "Two", "Three", "Four"); + writer.WriteLine("{0}{1}{2}{3}", (ReadOnlySpan)new object[] { "Zero", "One", "Two", "Three" }); Assert.Equal(5, writer.WriteLineCalls); + writer.WriteLine("{0}{1}{2}{3}{4}", new object[] { "Zero", "One", "Two", "Three", "Four" }); + Assert.Equal(6, writer.WriteLineCalls); + writer.WriteLine("{0}{1}{2}{3}{4}", (ReadOnlySpan)new object[] { "Zero", "One", "Two", "Three", "Four" }); + Assert.Equal(7, writer.WriteLineCalls); } } } diff --git a/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs b/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs index de3ed9530a1ee2..2299dc86f567db 100644 --- a/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs +++ b/src/libraries/System.Runtime/tests/System.IO.Tests/TextWriter/TextWriterTests.cs @@ -226,15 +226,24 @@ public void WriteStringThreeObjectsTest() } [Fact] - public void WriteStringMultipleObjectsTest() + public void WriteStringMultipleObjectsArrayTest() { using (CharArrayTextWriter tw = NewTextWriter) { - tw.Write(TestDataProvider.FormatStringMultipleObjects, TestDataProvider.MultipleObjects); + tw.Write(TestDataProvider.FormatStringMultipleObjects, (object[])TestDataProvider.MultipleObjects); Assert.Equal(string.Format(TestDataProvider.FormatStringMultipleObjects, TestDataProvider.MultipleObjects), tw.Text); } } + [Fact] + public void WriteStringMultipleObjectsSpanTest() + { + using (CharArrayTextWriter tw = NewTextWriter) + { + tw.Write(TestDataProvider.FormatStringMultipleObjects, (ReadOnlySpan)TestDataProvider.MultipleObjects); + Assert.Equal(string.Format(TestDataProvider.FormatStringMultipleObjects, TestDataProvider.MultipleObjects), tw.Text); + } + } #endregion #region WriteLine Overloads @@ -454,11 +463,21 @@ public void WriteLineStringThreeObjectsTest() } [Fact] - public void WriteLineStringMultipleObjectsTest() + public void WriteLineStringMultipleObjectsArrayTest() { using (CharArrayTextWriter tw = NewTextWriter) { - tw.WriteLine(TestDataProvider.FormatStringMultipleObjects, TestDataProvider.MultipleObjects); + tw.WriteLine(TestDataProvider.FormatStringMultipleObjects, (object[])TestDataProvider.MultipleObjects); + Assert.Equal(string.Format(TestDataProvider.FormatStringMultipleObjects + tw.NewLine, TestDataProvider.MultipleObjects), tw.Text); + } + } + + [Fact] + public void WriteLineStringMultipleObjectsSpanTest() + { + using (CharArrayTextWriter tw = NewTextWriter) + { + tw.WriteLine(TestDataProvider.FormatStringMultipleObjects, (ReadOnlySpan)TestDataProvider.MultipleObjects); Assert.Equal(string.Format(TestDataProvider.FormatStringMultipleObjects + tw.NewLine, TestDataProvider.MultipleObjects), tw.Text); } } @@ -772,8 +791,11 @@ public async Task CreateBroadcasting_DelegatesToAllWriters() oracle.Write(" {0} {1} {2}", TimeSpan.FromSeconds(1), TimeSpan.FromMinutes(2), TimeSpan.FromDays(3)); broadcasting.Write(" {0} {1} {2}", TimeSpan.FromSeconds(1), TimeSpan.FromMinutes(2), TimeSpan.FromDays(3)); - oracle.Write(" {0} {1} {2} {3}", (Int128)4, (UInt128)5, (nint)6, (nuint)7); - broadcasting.Write(" {0} {1} {2} {3}", (Int128)4, (UInt128)5, (nint)6, (nuint)7); + oracle.Write(" {0} {1} {2} {3}", new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7 }); + broadcasting.Write(" {0} {1} {2} {3}", new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7 }); + + oracle.Write(" {0} {1} {2} {3} {4}", (ReadOnlySpan)new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7, "8" }); + broadcasting.Write(" {0} {1} {2} {3} {4}", (ReadOnlySpan)new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7, "8" }); oracle.WriteLine(); broadcasting.WriteLine(); @@ -835,8 +857,11 @@ public async Task CreateBroadcasting_DelegatesToAllWriters() oracle.WriteLine(" {0} {1} {2}", TimeSpan.FromSeconds(1), TimeSpan.FromMinutes(2), TimeSpan.FromDays(3)); broadcasting.WriteLine(" {0} {1} {2}", TimeSpan.FromSeconds(1), TimeSpan.FromMinutes(2), TimeSpan.FromDays(3)); - oracle.WriteLine(" {0} {1} {2} {3}", (Int128)4, (UInt128)5, (nint)6, (nuint)7); - broadcasting.WriteLine(" {0} {1} {2} {3}", (Int128)4, (UInt128)5, (nint)6, (nuint)7); + oracle.WriteLine(" {0} {1} {2} {3}", new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7 }); + broadcasting.WriteLine(" {0} {1} {2} {3}", new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7 }); + + oracle.WriteLine(" {0} {1} {2} {3} {4}", (ReadOnlySpan)new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7, "8" }); + broadcasting.WriteLine(" {0} {1} {2} {3} {4}", (ReadOnlySpan)new object[] { (Int128)4, (UInt128)5, (nint)6, (nuint)7, "8" }); await oracle.WriteAsync('a'); await broadcasting.WriteAsync('a'); diff --git a/src/libraries/System.Runtime/tests/System.Resources.ResourceManager.Tests/ResourceManagerTests.cs b/src/libraries/System.Runtime/tests/System.Resources.ResourceManager.Tests/ResourceManagerTests.cs index 6bb68cb65b1455..b80b709fd171fe 100644 --- a/src/libraries/System.Runtime/tests/System.Resources.ResourceManager.Tests/ResourceManagerTests.cs +++ b/src/libraries/System.Runtime/tests/System.Resources.ResourceManager.Tests/ResourceManagerTests.cs @@ -112,7 +112,7 @@ public static void GetString_FromTestClassWithoutNeutralResources() static int ResourcesAfAZEvents = 0; -#if NETCOREAPP +#if NET static System.Reflection.Assembly AssemblyResolvingEventHandler(System.Runtime.Loader.AssemblyLoadContext alc, System.Reflection.AssemblyName name) { if (name.FullName.StartsWith("System.Resources.ResourceManager.Tests.resources")) @@ -138,7 +138,7 @@ static System.Reflection.Assembly AssemblyResolveEventHandler(object sender, Res { if (name.Contains("Culture=af-ZA")) { -#if NETCOREAPP +#if NET Assert.Equal(1, ResourcesAfAZEvents); #else Assert.Equal(0, ResourcesAfAZEvents); @@ -162,7 +162,7 @@ public static void GetString_ExpectEvents() private static void Remote_ExpectEvents() { -#if NETCOREAPP +#if NET System.Runtime.Loader.AssemblyLoadContext.Default.Resolving += AssemblyResolvingEventHandler; #endif AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolveEventHandler); @@ -176,7 +176,7 @@ private static void Remote_ExpectEvents() string actual = resourceManager.GetString("One", culture); Assert.Equal("Value-One", actual); -#if NETCOREAPP +#if NET Assert.Equal(2, ResourcesAfAZEvents); #else Assert.Equal(1, ResourcesAfAZEvents); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Combine.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Combine.cs index 033168ce649a17..9493d5aed543ab 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Combine.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Combine.cs @@ -98,6 +98,7 @@ public static void Combine(string[] paths) // Combine(string[]) Assert.Equal(expected, Path.Combine(paths)); + Assert.Equal(expected, Path.Combine((ReadOnlySpan)paths)); // Verify special cases switch (paths.Length) @@ -166,6 +167,10 @@ public static void ContainsInvalidCharWithRooted_Windows_core() private static void VerifyException(string[] paths) where T : Exception { Assert.Throws(() => Path.Combine(paths)); + if (paths != null) + { + Assert.Throws(() => Path.Combine((ReadOnlySpan)paths)); + } //verify passed as elements case if (paths != null) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Join.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Join.cs index 0984a9145385ac..f8b61049251fee 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Join.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/IO/PathTests_Join.cs @@ -200,36 +200,42 @@ public void JoinStringArray_ThrowsArgumentNullException() public void JoinStringArray_ZeroLengthArray() { Assert.Equal(string.Empty, Path.Join(new string[0])); + Assert.Equal(string.Empty, Path.Join((ReadOnlySpan)new string[0])); } [Theory, MemberData(nameof(TestData_JoinOnePath))] public void JoinStringArray_1(string path1, string expected) { Assert.Equal(expected, Path.Join(new string[] { path1 })); + Assert.Equal(expected, Path.Join((ReadOnlySpan)new string[] { path1 })); } [Theory, MemberData(nameof(TestData_JoinTwoPaths))] public void JoinStringArray_2(string path1, string path2, string expected) { Assert.Equal(expected, Path.Join(new string[] { path1, path2 })); + Assert.Equal(expected, Path.Join((ReadOnlySpan)new string[] { path1, path2 })); } [Theory, MemberData(nameof(TestData_JoinThreePaths))] public void JoinStringArray_3(string path1, string path2, string path3, string expected) { Assert.Equal(expected, Path.Join(new string[] { path1, path2, path3 })); + Assert.Equal(expected, Path.Join((ReadOnlySpan)new string[] { path1, path2, path3 })); } [Theory, MemberData(nameof(TestData_JoinFourPaths))] public void JoinStringArray_4(string path1, string path2, string path3, string path4, string expected) { Assert.Equal(expected, Path.Join(new string[] { path1, path2, path3, path4 })); + Assert.Equal(expected, Path.Join((ReadOnlySpan)new string[] { path1, path2, path3, path4 })); } [Theory, MemberData(nameof(TestData_JoinFourPaths))] public void JoinStringArray_8(string path1, string path2, string path3, string path4, string fourJoined) { Assert.Equal(Path.Join(fourJoined, fourJoined), Path.Join(new string[] { path1, path2, path3, path4, path1, path2, path3, path4 })); + Assert.Equal(Path.Join(fourJoined, fourJoined), Path.Join((ReadOnlySpan)new string[] { path1, path2, path3, path4, path1, path2, path3, path4 })); } } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj index 4bf5a231b12ed2..1e6b01ecf75b30 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System.Runtime.Tests.csproj @@ -12,9 +12,7 @@ true - - true - + true false diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs index 05e71be7b325c2..d829eb1199d4d7 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; using Xunit; namespace System.Tests @@ -356,6 +357,172 @@ public static void op_InequalityTest() // IFloatingPoint // + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public static void ConvertToIntegerTest() + { + // Signed Values + + Assert.Equal(0, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(Int128.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(0, FloatingPointHelper.ConvertToInteger(double.MinValue)); + + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); + + Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(int.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(Int128.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(nint.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + + // Unsigned Values + + Assert.Equal(byte.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(ushort.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(uint.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(ulong.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(UInt128.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(nuint.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); + + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6)); + + Assert.Equal(byte.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(ushort.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(uint.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(ulong.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(UInt128.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(nuint.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public static void ConvertToIntegerNativeTest() + { + // Signed Values + + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(Int128.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6)); + + if (Sse2.IsSupported) + { + // On Xarch: + // * Conversion to int is natively supported and returns 0x8000_0000 + // * Conversion to long is natively supported on 64-bit and returns 0x8000_0000_0000_0000 + + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + } + else + { + Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + } + } + else + { + Assert.Equal(-1, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(int.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(nint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(-1, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + } + Assert.Equal(Int128.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + + // Unsigned Values + + if (Sse2.IsSupported) + { + // On Xarch: + // * Conversion to uint is natively supported w/ Avx512 and returns 0xFFFF_FFFF + // * Conversion to ulong is natively supported on 64-bit w/ Avx512 and returns 0xFFFF_FFFF_FFFF_FFFF + + if (Avx512F.IsSupported) + { + Assert.Equal(uint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(nuint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + } + else + { + Assert.Equal(uint.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(nuint.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + } + + if (Environment.Is64BitProcess && Avx512F.IsSupported) + { + Assert.Equal(ulong.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + } + else + { + Assert.Equal(ulong.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + } + } + else + { + Assert.Equal(uint.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(ulong.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(nuint.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + } + Assert.Equal(byte.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(ushort.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + Assert.Equal(UInt128.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MinValue)); + + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6)); + + if (Sse2.IsSupported) + { + // On Xarch: + // * Conversion to uint is natively supported w/ Avx512 and returns 0xFFFF_FFFF + // * Conversion to ulong is natively supported on 64-bit w/ Avx512 and returns 0xFFFF_FFFF_FFFF_FFFF + + Assert.Equal(byte.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(ushort.MinValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + } + else + { + Assert.Equal(byte.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(ushort.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + } + Assert.Equal(uint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(ulong.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(UInt128.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + Assert.Equal(nuint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(double.MaxValue)); + } + [Fact] public static void GetExponentByteCountTest() { @@ -1055,7 +1222,7 @@ public static void CreateCheckedFromDecimalTest() AssertBitwiseEqual(-0.0, NumberBaseHelper.CreateChecked(-0.0m)); AssertBitwiseEqual(+0.0, NumberBaseHelper.CreateChecked(+0.0m)); AssertBitwiseEqual(+1.0, NumberBaseHelper.CreateChecked(+1.0m)); - AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateChecked(decimal.MaxValue)); + AssertBitwiseEqual(+79228162514264337593543950335.0, NumberBaseHelper.CreateChecked(decimal.MaxValue)); } [Fact] diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/MulticastDelegateTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/MulticastDelegateTests.cs index 9994fa02f10fac..ab798d6442beb0 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/MulticastDelegateTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/MulticastDelegateTests.cs @@ -105,7 +105,19 @@ public static void Combine() D nothing = (D)(Delegate.Combine()); Assert.Null(nothing); - D one = (D)(Delegate.Combine(a)); + nothing = (D)(Delegate.Combine(null)); + Assert.Null(nothing); + + nothing = (D)(Delegate.Combine(ReadOnlySpan.Empty)); + Assert.Null(nothing); + + D one = (D)(Delegate.Combine(new[] { a })); + t1.Clear(); + one(5); + Assert.Equal("A5", t1.S); + CheckInvokeList(new D[] { a }, one, t1); + + one = (D)(Delegate.Combine((ReadOnlySpan)new[] { a })); t1.Clear(); one(5); Assert.Equal("A5", t1.S); @@ -117,13 +129,25 @@ public static void Combine() Assert.Equal("A5B5", t1.S); CheckInvokeList(new D[] { a, b }, ab, t1); - D abc = (D)(Delegate.Combine(a, b, c)); + D abc = (D)(Delegate.Combine(new[] { a, b, c })); t1.Clear(); abc(5); Assert.Equal("A5B5C5", t1.S); CheckInvokeList(new D[] { a, b, c }, abc, t1); - D abcdabc = (D)(Delegate.Combine(abc, d, abc)); + abc = (D)(Delegate.Combine((ReadOnlySpan)new[] { a, b, c })); + t1.Clear(); + abc(5); + Assert.Equal("A5B5C5", t1.S); + CheckInvokeList(new D[] { a, b, c }, abc, t1); + + D abcdabc = (D)(Delegate.Combine(new[] { abc, d, abc })); + t1.Clear(); + abcdabc(9); + Assert.Equal("A9B9C9D9A9B9C9", t1.S); + CheckInvokeList(new D[] { a, b, c, d, a, b, c }, abcdabc, t1); + + abcdabc = (D)(Delegate.Combine((ReadOnlySpan)new[] { abc, d, abc })); t1.Clear(); abcdabc(9); Assert.Equal("A9B9C9D9A9B9C9", t1.S); diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs index a6637de7f7e2a3..21a4ba2cd77a11 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; using Xunit; namespace System.Tests @@ -356,6 +357,172 @@ public static void op_InequalityTest() // IFloatingPoint // + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public static void ConvertToIntegerTest() + { + // Signed Values + + Assert.Equal(0, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(Int128.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(0, FloatingPointHelper.ConvertToInteger(float.MinValue)); + + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); + + Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(int.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(Int128.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(nint.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + + // Unsigned Values + + Assert.Equal(byte.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(ushort.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(uint.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(ulong.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(UInt128.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(nuint.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); + + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToInteger(2.6f)); + + Assert.Equal(byte.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(ushort.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(uint.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(ulong.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(nuint.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] + public static void ConvertToIntegerNativeTest() + { + // Signed Values + + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(Int128.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + + if (Sse2.IsSupported) + { + // On Xarch: + // * Conversion to int is natively supported and returns 0x8000_0000 + // * Conversion to long is natively supported on 64-bit and returns 0x8000_0000_0000_0000 + + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(0, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + + if (Environment.Is64BitProcess) + { + Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + } + else + { + Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + } + } + else + { + Assert.Equal(-1, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(int.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(nint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(-1, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + } + Assert.Equal(Int128.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + + // Unsigned Values + + if (Sse2.IsSupported) + { + // On Xarch: + // * Conversion to uint is natively supported w/ Avx512 and returns 0xFFFF_FFFF + // * Conversion to ulong is natively supported on 64-bit w/ Avx512 and returns 0xFFFF_FFFF_FFFF_FFFF + + if (Avx512F.IsSupported) + { + Assert.Equal(uint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(nuint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + } + else + { + Assert.Equal(uint.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(nuint.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + } + + if (Environment.Is64BitProcess && Avx512F.IsSupported) + { + Assert.Equal(ulong.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + } + else + { + Assert.Equal(ulong.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + } + } + else + { + Assert.Equal(uint.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(ulong.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(nuint.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + } + Assert.Equal(byte.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(ushort.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + Assert.Equal(UInt128.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MinValue)); + + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + Assert.Equal(2u, FloatingPointHelper.ConvertToIntegerNative(2.6f)); + + if (Sse2.IsSupported) + { + // On Xarch: + // * Conversion to uint is natively supported w/ Avx512 and returns 0xFFFF_FFFF + // * Conversion to ulong is natively supported on 64-bit w/ Avx512 and returns 0xFFFF_FFFF_FFFF_FFFF + + Assert.Equal(byte.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(ushort.MinValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + } + else + { + Assert.Equal(byte.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(ushort.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + } + Assert.Equal(uint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(ulong.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(new UInt128(0xFFFF_FF00_0000_0000, 0x0000_0000_0000_0000), FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + Assert.Equal(nuint.MaxValue, FloatingPointHelper.ConvertToIntegerNative(float.MaxValue)); + } + [Fact] public static void GetExponentByteCountTest() { diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs index b12bd2cb74fc48..037e7a98a95878 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/String.SplitTests.cs @@ -141,6 +141,7 @@ public static void SplitNoMatchSingleResult() Assert.Equal(expected, Value.Split(',', Options)); Assert.Equal(expected, Value.Split(',', Count, Options)); Assert.Equal(expected, Value.Split(new[] { ',' })); + Assert.Equal(expected, Value.Split((ReadOnlySpan)new[] { ',' })); Assert.Equal(expected, Value.Split(new[] { ',' }, Options)); Assert.Equal(expected, Value.Split(new[] { ',' }, Count)); Assert.Equal(expected, Value.Split(new[] { ',' }, Count, Options)); @@ -516,6 +517,7 @@ public static void SplitCharSeparator(string value, char separator, int count, S { Assert.Equal(expected, value.Split(separator)); Assert.Equal(expected, value.Split(new[] { separator })); + Assert.Equal(expected, value.Split((ReadOnlySpan)new[] { separator })); Assert.Equal(expected, value.Split(separator.ToString())); } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/CompositeFormatTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/CompositeFormatTests.cs index bdfde206c850f4..64c0caf8f8c396 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/CompositeFormatTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/CompositeFormatTests.cs @@ -68,12 +68,15 @@ public static void MinimumArgumentCount_MatchesExpectedValue(string format, int Assert.Equal(expected, cf.MinimumArgumentCount); - string s = string.Format(null, cf, Enumerable.Repeat((object)"arg", expected).ToArray()); - Assert.NotNull(s); + object[] args = Enumerable.Repeat((object)"arg", expected).ToArray(); + Assert.NotNull(string.Format(null, cf, args)); + Assert.NotNull(string.Format(null, cf, (ReadOnlySpan)args)); if (expected != 0) { - Assert.Throws(() => string.Format(null, cf, Enumerable.Repeat((object)"arg", expected - 1).ToArray())); + args = Enumerable.Repeat((object)"arg", expected - 1).ToArray(); + Assert.Throws(() => string.Format(null, cf, args)); + Assert.Throws(() => string.Format(null, cf, (ReadOnlySpan)args)); } } @@ -86,21 +89,20 @@ public static void StringFormat_Valid(IFormatProvider provider, string format, o Assert.Same(format, cf.Format); Assert.Equal(expected, string.Format(provider, cf, values)); - - Assert.Equal(expected, string.Format(provider, cf, (ReadOnlySpan)values)); + Assert.Equal(expected, string.Format(provider, cf, (ReadOnlySpan)values)); switch (values.Length) { case 1: - Assert.Equal(expected, string.Format(provider, cf, values[0])); + Assert.Equal(expected, string.Format(provider, cf, arg0: values[0])); break; case 2: - Assert.Equal(expected, string.Format(provider, cf, values[0], values[1])); + Assert.Equal(expected, string.Format(provider, cf, arg0: values[0], arg1: values[1])); break; case 3: - Assert.Equal(expected, string.Format(provider, cf, values[0], values[1], values[2])); + Assert.Equal(expected, string.Format(provider, cf, arg0: values[0], arg1: values[1], arg2: values[2])); break; } } @@ -188,6 +190,8 @@ public static void MemoryExtensionsTryWrite_Valid(IFormatProvider provider, stri dest = new char[expected.Length - 1]; Assert.False(dest.AsSpan().TryWrite(provider, cf, out charsWritten, values)); Assert.Equal(0, charsWritten); + Assert.False(dest.AsSpan().TryWrite(provider, cf, out charsWritten, (ReadOnlySpan)values)); + Assert.Equal(0, charsWritten); } } @@ -209,16 +213,17 @@ public static void StringFormat_Invalid_FormatExceptionFromArgs(IFormatProvider Assert.NotNull(cf); Assert.Throws(() => string.Format(provider, cf, args)); + Assert.Throws(() => string.Format(provider, cf, (ReadOnlySpan)args)); switch (args.Length) { case 1: - Assert.Throws(() => string.Format(provider, cf, args[0])); + Assert.Throws(() => string.Format(provider, cf, arg0: args[0])); break; case 2: - Assert.Throws(() => string.Format(provider, cf, args[0], args[1])); + Assert.Throws(() => string.Format(provider, cf, arg0: args[0], arg1: args[1])); break; case 3: - Assert.Throws(() => string.Format(provider, cf, args[0], args[1], args[2])); + Assert.Throws(() => string.Format(provider, cf, arg0: args[0], arg1: args[1], arg2: args[2])); break; } } @@ -233,16 +238,17 @@ public static void StringBuilderAppendFormat_Invalid_FormatExceptionFromArgs(IFo var sb = new StringBuilder(); Assert.Throws(() => sb.AppendFormat(provider, cf, args)); + Assert.Throws(() => sb.AppendFormat(provider, cf, (ReadOnlySpan)args)); switch (args.Length) { case 1: - Assert.Throws(() => sb.AppendFormat(provider, cf, args[0])); + Assert.Throws(() => sb.AppendFormat(provider, cf, arg0: args[0])); break; case 2: - Assert.Throws(() => sb.AppendFormat(provider, cf, args[0], args[1])); + Assert.Throws(() => sb.AppendFormat(provider, cf, arg0: args[0], arg1: args[1])); break; case 3: - Assert.Throws(() => sb.AppendFormat(provider, cf, args[0], args[1], args[2])); + Assert.Throws(() => sb.AppendFormat(provider, cf, arg0: args[0], arg1: args[1], arg2: args[2])); break; } } @@ -257,16 +263,17 @@ public static void MemoryExtensionsTryWrite_Invalid_FormatExceptionFromArgs(IFor char[] dest = new char[1024]; Assert.Throws(() => new Span(dest).TryWrite(provider, cf, out _, args)); + Assert.Throws(() => new Span(dest).TryWrite(provider, cf, out _, (ReadOnlySpan)args)); switch (args.Length) { case 1: Assert.Throws(() => new Span(dest).TryWrite(provider, cf, out _, args[0])); break; case 2: - Assert.Throws(() => new Span(dest).TryWrite(provider, cf, out _, args[0], args[1])); + Assert.Throws(() => new Span(dest).TryWrite(provider, cf, out _, arg0: args[0], arg1: args[1])); break; case 3: - Assert.Throws(() => new Span(dest).TryWrite(provider, cf, out _, args[0], args[1], args[2])); + Assert.Throws(() => new Span(dest).TryWrite(provider, cf, out _, arg0: args[0], arg1: args[1], arg2: args[2])); break; } } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs index 2d1f569dd103be..5671c6d3614e57 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Text/StringBuilderTests.cs @@ -842,6 +842,19 @@ public static void AppendFormat(string original, IFormatProvider provider, strin builder = new StringBuilder(original); builder.AppendFormat(provider, format, values); Assert.Equal(expected, builder.ToString()); + + // Use AppendFormat(string, ReadOnlySpan) or AppendFormat(IFormatProvider, string, ReadOnlySpan) + if (provider == null) + { + // Use AppendFormat(string, ReadOnlySpan) + builder = new StringBuilder(original); + builder.AppendFormat(format, (ReadOnlySpan)values); + Assert.Equal(expected, builder.ToString()); + } + // Use AppendFormat(IFormatProvider, string, ReadOnlySpan) + builder = new StringBuilder(original); + builder.AppendFormat(provider, format, (ReadOnlySpan)values); + Assert.Equal(expected, builder.ToString()); } [Fact] @@ -855,17 +868,21 @@ public static void AppendFormat_Invalid() var obj2 = new object(); var obj3 = new object(); var obj4 = new object(); + var objArray = new object[] { obj1, obj2, obj3, obj4 }; AssertExtensions.Throws("format", () => builder.AppendFormat(null, obj1)); // Format is null AssertExtensions.Throws("format", () => builder.AppendFormat(null, obj1, obj2, obj3)); // Format is null - AssertExtensions.Throws("format", () => builder.AppendFormat(null, obj1, obj2, obj3)); // Format is null AssertExtensions.Throws("format", () => builder.AppendFormat(null, obj1, obj2, obj3, obj4)); // Format is null + AssertExtensions.Throws("format", () => builder.AppendFormat(null, objArray)); // Format is null + AssertExtensions.Throws("format", () => builder.AppendFormat(null, (ReadOnlySpan)objArray)); // Format is null AssertExtensions.Throws("args", () => builder.AppendFormat("", null)); // Args is null AssertExtensions.Throws("format", () => builder.AppendFormat(null, (object[])null)); // Both format and args are null AssertExtensions.Throws("format", () => builder.AppendFormat(formatter, (string)null, obj1)); // Format is null AssertExtensions.Throws("format", () => builder.AppendFormat(formatter, (string)null, obj1, obj2)); // Format is null AssertExtensions.Throws("format", () => builder.AppendFormat(formatter, (string)null, obj1, obj2, obj3)); // Format is null AssertExtensions.Throws("format", () => builder.AppendFormat(formatter, (string)null, obj1, obj2, obj3, obj4)); // Format is null + AssertExtensions.Throws("format", () => builder.AppendFormat(formatter, (string)null, objArray)); // Format is null + AssertExtensions.Throws("format", () => builder.AppendFormat(formatter, (string)null, (ReadOnlySpan)objArray)); // Format is null AssertExtensions.Throws("args", () => builder.AppendFormat(formatter, "", null)); // Args is null AssertExtensions.Throws("format", () => builder.AppendFormat(formatter, (string)null, null)); // Both format and args are null @@ -873,19 +890,27 @@ public static void AppendFormat_Invalid() Assert.Throws(() => builder.AppendFormat("{-1}", obj1, obj2)); // Format has value < 0 Assert.Throws(() => builder.AppendFormat("{-1}", obj1, obj2, obj3)); // Format has value < 0 Assert.Throws(() => builder.AppendFormat("{-1}", obj1, obj2, obj3, obj4)); // Format has value < 0 + Assert.Throws(() => builder.AppendFormat("{-1}", objArray)); // Format has value < 0 + Assert.Throws(() => builder.AppendFormat("{-1}", (ReadOnlySpan)objArray)); // Format has value < 0 Assert.Throws(() => builder.AppendFormat(formatter, "{-1}", obj1)); // Format has value < 0 Assert.Throws(() => builder.AppendFormat(formatter, "{-1}", obj1, obj2)); // Format has value < 0 Assert.Throws(() => builder.AppendFormat(formatter, "{-1}", obj1, obj2, obj3)); // Format has value < 0 Assert.Throws(() => builder.AppendFormat(formatter, "{-1}", obj1, obj2, obj3, obj4)); // Format has value < 0 + Assert.Throws(() => builder.AppendFormat(formatter, "{-1}", objArray)); // Format has value < 0 + Assert.Throws(() => builder.AppendFormat(formatter, "{-1}", (ReadOnlySpan)objArray)); // Format has value < 0 Assert.Throws(() => builder.AppendFormat("{1}", obj1)); // Format has value >= 1 Assert.Throws(() => builder.AppendFormat("{2}", obj1, obj2)); // Format has value >= 2 Assert.Throws(() => builder.AppendFormat("{3}", obj1, obj2, obj3)); // Format has value >= 3 Assert.Throws(() => builder.AppendFormat("{4}", obj1, obj2, obj3, obj4)); // Format has value >= 4 + Assert.Throws(() => builder.AppendFormat("{4}", objArray)); // Format has value >= 4 + Assert.Throws(() => builder.AppendFormat("{4}", (ReadOnlySpan)objArray)); // Format has value >= 4 Assert.Throws(() => builder.AppendFormat(formatter, "{1}", obj1)); // Format has value >= 1 Assert.Throws(() => builder.AppendFormat(formatter, "{2}", obj1, obj2)); // Format has value >= 2 Assert.Throws(() => builder.AppendFormat(formatter, "{3}", obj1, obj2, obj3)); // Format has value >= 3 Assert.Throws(() => builder.AppendFormat(formatter, "{4}", obj1, obj2, obj3, obj4)); // Format has value >= 4 + Assert.Throws(() => builder.AppendFormat(formatter, "{4}", objArray)); // Format has value >= 4 + Assert.Throws(() => builder.AppendFormat(formatter, "{4}", (ReadOnlySpan)objArray)); // Format has value >= 4 Assert.Throws(() => builder.AppendFormat("{", "")); // Format has unescaped { Assert.Throws(() => builder.AppendFormat("{a", "")); // Format has unescaped { @@ -900,7 +925,9 @@ public static void AppendFormat_Invalid() Assert.Throws(() => builder.AppendFormat("{0 ", "")); // Format with index and spaces is not closed Assert.Throws(() => builder.AppendFormat("{1000000", new string[10])); // Format index is too long + Assert.Throws(() => builder.AppendFormat("{1000000", (ReadOnlySpan)new string[10])); // Format index is too long Assert.Throws(() => builder.AppendFormat("{10000000}", new string[10])); // Format index is too long + Assert.Throws(() => builder.AppendFormat("{10000000}", (ReadOnlySpan)new string[10])); // Format index is too long Assert.Throws(() => builder.AppendFormat("{0,", "")); // Format with comma is not closed Assert.Throws(() => builder.AppendFormat("{0, ", "")); // Format with comma and spaces is not closed @@ -910,13 +937,19 @@ public static void AppendFormat_Invalid() Assert.Throws(() => builder.AppendFormat("{0,-a", "")); // Format has invalid character after minus sign Assert.Throws(() => builder.AppendFormat("{0,1000000", new string[10])); // Format length is too long + Assert.Throws(() => builder.AppendFormat("{0,1000000", (ReadOnlySpan)new string[10])); // Format length is too long Assert.Throws(() => builder.AppendFormat("{0,10000000}", new string[10])); // Format length is too long + Assert.Throws(() => builder.AppendFormat("{0,10000000}", (ReadOnlySpan)new string[10])); // Format length is too long Assert.Throws(() => builder.AppendFormat("{0:", new string[10])); // Format with colon is not closed + Assert.Throws(() => builder.AppendFormat("{0:", (ReadOnlySpan)new string[10])); // Format with colon is not closed Assert.Throws(() => builder.AppendFormat("{0: ", new string[10])); // Format with colon and spaces is not closed + Assert.Throws(() => builder.AppendFormat("{0: ", (ReadOnlySpan)new string[10])); // Format with colon and spaces is not closed Assert.Throws(() => builder.AppendFormat("{0:{", new string[10])); // Format with custom format contains unescaped { + Assert.Throws(() => builder.AppendFormat("{0:{", (ReadOnlySpan)new string[10])); // Format with custom format contains unescaped { Assert.Throws(() => builder.AppendFormat("{0:{}", new string[10])); // Format with custom format contains unescaped { + Assert.Throws(() => builder.AppendFormat("{0:{}", (ReadOnlySpan)new string[10])); // Format with custom format contains unescaped { Assert.Throws(() => builder.AppendFormat("{0}", new TooManyCharsWrittenSpanFormattable())); // ISpanFormattable that returns more characters than it actually wrote } @@ -1775,11 +1808,15 @@ public static void AppendJoin_TestValues(object[] values, string expected) var enumerable = values.Select(_ => _); Assert.Equal(expected, new StringBuilder().AppendJoin('|', values).ToString()); + Assert.Equal(expected, new StringBuilder().AppendJoin('|', (ReadOnlySpan)values).ToString()); Assert.Equal(expected, new StringBuilder().AppendJoin('|', enumerable).ToString()); Assert.Equal(expected, new StringBuilder().AppendJoin('|', stringValues).ToString()); + Assert.Equal(expected, new StringBuilder().AppendJoin('|', (ReadOnlySpan)stringValues).ToString()); Assert.Equal(expected, new StringBuilder().AppendJoin("|", values).ToString()); + Assert.Equal(expected, new StringBuilder().AppendJoin("|", (ReadOnlySpan)values).ToString()); Assert.Equal(expected, new StringBuilder().AppendJoin("|", enumerable).ToString()); Assert.Equal(expected, new StringBuilder().AppendJoin("|", stringValues).ToString()); + Assert.Equal(expected, new StringBuilder().AppendJoin("|", (ReadOnlySpan)stringValues).ToString()); } [Fact] @@ -1801,9 +1838,14 @@ private sealed class NullToStringObject [InlineData(", ", "1, 2, 3")] public static void AppendJoin_TestStringSeparators(string separator, string expected) { - Assert.Equal(expected, new StringBuilder().AppendJoin(separator, new object[] { 1, 2, 3 }).ToString()); + var values = new object[] { 1, 2, 3 }; + var stringValues = new string[] { "1", "2", "3" }; + + Assert.Equal(expected, new StringBuilder().AppendJoin(separator, values).ToString()); + Assert.Equal(expected, new StringBuilder().AppendJoin(separator, (ReadOnlySpan)values).ToString()); Assert.Equal(expected, new StringBuilder().AppendJoin(separator, Enumerable.Range(1, 3)).ToString()); - Assert.Equal(expected, new StringBuilder().AppendJoin(separator, new string[] { "1", "2", "3" }).ToString()); + Assert.Equal(expected, new StringBuilder().AppendJoin(separator, stringValues).ToString()); + Assert.Equal(expected, new StringBuilder().AppendJoin(separator, (ReadOnlySpan)stringValues).ToString()); } @@ -1825,12 +1867,16 @@ public static void AppendJoin_NoValues_NoSpareCapacity_DoesNotThrow(string separ if (separator?.Length == 1) { CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], values); + CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], (ReadOnlySpan)values); CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], enumerable); CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], stringValues); + CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], (ReadOnlySpan)stringValues); } CreateBuilderWithNoSpareCapacity().AppendJoin(separator, values); + CreateBuilderWithNoSpareCapacity().AppendJoin(separator, (ReadOnlySpan)values); CreateBuilderWithNoSpareCapacity().AppendJoin(separator, enumerable); CreateBuilderWithNoSpareCapacity().AppendJoin(separator, stringValues); + CreateBuilderWithNoSpareCapacity().AppendJoin(separator, (ReadOnlySpan)stringValues); } [Theory] @@ -1849,12 +1895,16 @@ public static void AppendJoin_NoSpareCapacity_ThrowsArgumentOutOfRangeException( if (separator?.Length == 1) { AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], values)); + AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], (ReadOnlySpan)values)); AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], enumerable)); AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], stringValues)); + AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator[0], (ReadOnlySpan)stringValues)); } AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, values)); + AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, (ReadOnlySpan)values)); AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, enumerable)); AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, stringValues)); + AssertExtensions.Throws(s_noCapacityParamName, () => CreateBuilderWithNoSpareCapacity().AppendJoin(separator, (ReadOnlySpan)stringValues)); } [Theory] diff --git a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/CancellationTokenTests.cs b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/CancellationTokenTests.cs index ba75f617bf0b5d..bc66b33cd9b68a 100644 --- a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/CancellationTokenTests.cs +++ b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/CancellationTokenTests.cs @@ -207,6 +207,7 @@ public static void TokenSourceDispose_Negative() //shouldn't throw CancellationTokenSource.CreateLinkedTokenSource(new[] { token, token }); + CancellationTokenSource.CreateLinkedTokenSource((ReadOnlySpan)new[] { token, token }); } /// @@ -431,15 +432,20 @@ public static void CreateLinkedTokenSource_Simple_TwoToken() "CreateLinkedToken_Simple_TwoToken: The combined token should now be signalled"); } - [Fact] - public static void CreateLinkedTokenSource_Simple_MultiToken() + [Theory] + [InlineData(false)] + [InlineData(true)] + public static void CreateLinkedTokenSource_Simple_MultiToken(bool useSpan) { CancellationTokenSource signal1 = new CancellationTokenSource(); CancellationTokenSource signal2 = new CancellationTokenSource(); CancellationTokenSource signal3 = new CancellationTokenSource(); //Neither token is signalled. - CancellationTokenSource combined = CancellationTokenSource.CreateLinkedTokenSource(new[] { signal1.Token, signal2.Token, signal3.Token }); + CancellationTokenSource combined = useSpan ? + CancellationTokenSource.CreateLinkedTokenSource((ReadOnlySpan)new[] { signal1.Token, signal2.Token, signal3.Token }) : + CancellationTokenSource.CreateLinkedTokenSource(new[] { signal1.Token, signal2.Token, signal3.Token }); + Assert.False(combined.IsCancellationRequested, "CreateLinkedToken_Simple_MultiToken: The combined token should start unsignalled"); diff --git a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/MethodCoverage.cs b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/MethodCoverage.cs index 2634e8340ef9ec..01af9fb525c035 100644 --- a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/MethodCoverage.cs +++ b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/MethodCoverage.cs @@ -188,14 +188,30 @@ public static void Task_WhenAny_TwoTasks_InvalidArgs_Throws() AssertExtensions.Throws("task2", () => Task.WhenAny(Task.FromResult(2), null)); } + [Fact] + public static void Task_WhenAny_NullTaskElement_Throws() + { + AssertExtensions.Throws("tasks", () => { Task.WhenAny(new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAny((ReadOnlySpan)new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAny(NullElementIterator()); }); + + AssertExtensions.Throws("tasks", () => { Task.WhenAny(new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAny((ReadOnlySpan>)new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAny(NullElementIterator>()); }); + + static IEnumerable NullElementIterator() where T : Task { yield return null; } + } + [Fact] public static void Task_WhenAny_NoTasks_Throws() { AssertExtensions.Throws("tasks", () => { Task.WhenAny(new Task[0]); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAny(ReadOnlySpan.Empty); }); AssertExtensions.Throws("tasks", () => { Task.WhenAny(new List()); }); AssertExtensions.Throws("tasks", () => { Task.WhenAny(EmptyIterator()); }); AssertExtensions.Throws("tasks", () => { Task.WhenAny(new Task[0]); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAny(ReadOnlySpan>.Empty); }); AssertExtensions.Throws("tasks", () => { Task.WhenAny(new List>()); }); AssertExtensions.Throws("tasks", () => { Task.WhenAny(EmptyIterator>()); }); @@ -353,6 +369,36 @@ public static void FromAsync() mre2.WaitOne(); } + [Fact] + public static void Task_WaitAll_NullArgument_Throws() + { + AssertExtensions.Throws("tasks", () => { Task.WaitAll((Task[])null); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll((Task[])null, CancellationToken.None); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll((Task[])null, 30_000); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll((Task[])null, TimeSpan.FromSeconds(30)); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll((Task[])null, 30_000, CancellationToken.None); }); + } + + [Fact] + public static void Task_WaitAll_NullTaskElement_Throws() + { + Task[] nullElement = [null]; + AssertExtensions.Throws("tasks", () => { Task.WaitAll(nullElement); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll((ReadOnlySpan)nullElement); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll(nullElement, CancellationToken.None); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll(nullElement, 30_000); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll(nullElement, TimeSpan.FromSeconds(30)); }); + AssertExtensions.Throws("tasks", () => { Task.WaitAll(nullElement, 30_000, CancellationToken.None); }); + } + + [Fact] + public static void Task_WaitAll_InvalidArgument_Throws() + { + Assert.Throws(() => Task.WaitAll([Task.Factory.StartNew(() => { })], -2)); + Assert.Throws(() => Task.WaitAll([Task.Factory.StartNew(() => { })], -2, CancellationToken.None)); + Assert.Throws(() => Task.WaitAll([Task.Factory.StartNew(() => { })], TimeSpan.FromMilliseconds(-2))); + } + [Fact] public static void Task_WhenAll_NullArgument_Throws() { @@ -363,14 +409,30 @@ public static void Task_WhenAll_NullArgument_Throws() AssertExtensions.Throws("tasks", () => { Task.WhenAll((IEnumerable>)null); }); } + [Fact] + public static void Task_WhenAll_NullTaskElement_Throws() + { + AssertExtensions.Throws("tasks", () => { Task.WhenAll(new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAll((ReadOnlySpan)new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAll(NullElementIterator()); }); + + AssertExtensions.Throws("tasks", () => { Task.WhenAll(new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAll((ReadOnlySpan>)new Task[] { null }); }); + AssertExtensions.Throws("tasks", () => { Task.WhenAll(NullElementIterator>()); }); + + static IEnumerable NullElementIterator() where T : Task { yield return null; } + } + [Fact] public static void Task_WhenAll_NoTasks_IsCompletedSuccessfully() { Assert.True(Task.WhenAll(new Task[0]).IsCompletedSuccessfully); + Assert.True(Task.WhenAll(ReadOnlySpan.Empty).IsCompletedSuccessfully); Assert.True(Task.WhenAll(new List()).IsCompletedSuccessfully); Assert.True(Task.WhenAll(EmptyIterator()).IsCompletedSuccessfully); AssertIsCompletedWithEmptyResult(Task.WhenAll(new Task[0])); + AssertIsCompletedWithEmptyResult(Task.WhenAll(ReadOnlySpan>.Empty)); AssertIsCompletedWithEmptyResult(Task.WhenAll(new List>())); AssertIsCompletedWithEmptyResult(Task.WhenAll(EmptyIterator>())); diff --git a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/Task/TaskRtTests_Core.cs b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/Task/TaskRtTests_Core.cs index 088c45ddc116fc..1225ca6433a291 100644 --- a/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/Task/TaskRtTests_Core.cs +++ b/src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/Task/TaskRtTests_Core.cs @@ -1338,11 +1338,6 @@ public static void RunTaskWaitAnyTests_WithCancellationTokenTests() [OuterLoop] public static void RunTaskWaitAllTests() { - Assert.Throws(() => Task.WaitAll((Task[])null)); - AssertExtensions.Throws("tasks", () => Task.WaitAll(new Task[] { null })); - Assert.Throws(() => Task.WaitAll(new Task[] { Task.Factory.StartNew(() => { }) }, -2)); - Assert.Throws(() => Task.WaitAll(new Task[] { Task.Factory.StartNew(() => { }) }, TimeSpan.FromMilliseconds(-2))); - ThreadPoolHelpers.EnsureMinThreadsAtLeast(10); RunTaskWaitAllTest(false, 1); RunTaskWaitAllTest(false, 10); diff --git a/src/libraries/System.Runtime/tests/System.ValueTuple.Tests/ValueTupleTests.cs b/src/libraries/System.Runtime/tests/System.ValueTuple.Tests/ValueTupleTests.cs index 147b4ea9647cbf..0e85e1565149db 100644 --- a/src/libraries/System.Runtime/tests/System.ValueTuple.Tests/ValueTupleTests.cs +++ b/src/libraries/System.Runtime/tests/System.ValueTuple.Tests/ValueTupleTests.cs @@ -3,7 +3,7 @@ using System.Collections; using Xunit; -#if NETCOREAPP +#if NET using System.Runtime.CompilerServices; #endif @@ -775,7 +775,7 @@ public static void ZeroTuples() AssertExtensions.Throws("other", () => ((IStructuralComparable)a).CompareTo("string", DummyTestComparer.Instance)); Assert.Equal("(1, 2, 3, 4, 5, 6, 7, )", CreateLong(1, 2, 3, 4, 5, 6, 7, new ValueTuple()).ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(); Assert.Throws(() => it[-1].ToString()); Assert.Throws(() => it[0].ToString()); @@ -812,7 +812,7 @@ public static void OneTuples() Assert.Equal("()", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(1); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -852,7 +852,7 @@ public static void TwoTuples() Assert.Equal("(, )", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(1, 2); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -897,7 +897,7 @@ public static void ThreeTuples() Assert.Equal("(, , )", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(1, 2, 3); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -948,7 +948,7 @@ public static void FourTuples() Assert.Equal("(, , , )", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(1, 2, 3, 4); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -1004,7 +1004,7 @@ public static void FiveTuples() Assert.Equal("(, , , , )", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(1, 2, 3, 4, 5); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -1065,7 +1065,7 @@ public static void SixTuples() Assert.Equal("(, , , , , )", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(1, 2, 3, 4, 5, 6); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -1131,7 +1131,7 @@ public static void SevenTuples() Assert.Equal("(, , , , , , )", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = ValueTuple.Create(1, 2, 3, 4, 5, 6, 7); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -1223,7 +1223,7 @@ public static void EightTuples() Assert.Equal("(, , , , , , , )", vtWithNull.ToString()); Assert.Equal(tupleWithNull.ToString(), vtWithNull.ToString()); -#if NETCOREAPP +#if NET ITuple it = CreateLong(1, 2, 3, 4, 5, 6, 7, ValueTuple.Create(8)); Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); @@ -1312,7 +1312,7 @@ public static void EightTuplesWithBadRest() Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 0, 0, 0, 0, 0, 0, 42)", CreateLong(1, 2, 3, 4, 5, 6, 7, d).ToString()); -#if NETCOREAPP +#if NET ITuple it = d; Assert.Throws(() => it[-1].ToString()); Assert.Equal(1, it[0]); diff --git a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj index e1e3b9838c4c25..4376906dbbc4bf 100644 --- a/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj +++ b/src/libraries/System.Security.Claims/src/System.Security.Claims.csproj @@ -18,6 +18,7 @@ + diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseSignature.cs b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseSignature.cs index 831c5c8f676bd2..da0962a48b3bdf 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseSignature.cs +++ b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseSignature.cs @@ -450,7 +450,7 @@ private bool VerifyCore(AsymmetricAlgorithm key, ReadOnlySpan contentBytes private bool VerifyHash(AsymmetricAlgorithm key, IncrementalHash hasher, HashAlgorithmName hashAlgorithm, KeyType keyType, RSASignaturePadding? padding) { -#if NETCOREAPP +#if NET Debug.Assert(hasher.HashLengthInBytes <= 512 / 8); // largest hash we can get (SHA512). Span hash = stackalloc byte[hasher.HashLengthInBytes]; hasher.GetHashAndReset(hash); diff --git a/src/libraries/System.Security.Cryptography.Cose/tests/CoseTestHelpers.cs b/src/libraries/System.Security.Cryptography.Cose/tests/CoseTestHelpers.cs index 4eb5d7dba72dd5..2e73ce54ffefbd 100644 --- a/src/libraries/System.Security.Cryptography.Cose/tests/CoseTestHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Cose/tests/CoseTestHelpers.cs @@ -588,7 +588,7 @@ public static IEnumerable AllCborTypes() w.WriteDouble(default); yield return ReturnDataAndReset(w); -#if NETCOREAPP +#if NET w.WriteHalf(default); yield return ReturnDataAndReset(w); #endif diff --git a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.cs b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.cs index 6c17e4ac084049..f687149f802229 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.cs @@ -83,7 +83,7 @@ public void Reset() { } public sealed partial class CmsSigner { public CmsSigner() { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("CmsSigner(CspParameters) is obsolete and is not supported. Use an alternative constructor instead.", DiagnosticId = "SYSLIB0034", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -270,7 +270,7 @@ internal SignerInfo() { } public void CheckHash() { } public void CheckSignature(bool verifySignatureOnly) { } public void CheckSignature(System.Security.Cryptography.X509Certificates.X509Certificate2Collection extraStore, bool verifySignatureOnly) { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("ComputeCounterSignature without specifying a CmsSigner is obsolete and is not supported. Use the overload that accepts a CmsSigner.", DiagnosticId = "SYSLIB0035", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.KeyTrans.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.KeyTrans.cs index e95be29e999099..fd9cc62ac0ec22 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.KeyTrans.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.KeyTrans.cs @@ -189,7 +189,7 @@ private KeyTransRecipientInfoAsn MakeKtri( return null; } -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 byte[]? cek = null; int cekLength = 0; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs index c0831046595a23..69525a16b001e9 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.cs @@ -80,7 +80,7 @@ public override byte[] GetSubjectKeyIdentifier(X509Certificate2 certificate) return (T?)(object?)certificate.GetRSAPrivateKey(); if (typeof(T) == typeof(ECDsa)) return (T?)(object?)certificate.GetECDsaPrivateKey(); -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 if (typeof(T) == typeof(DSA) && Internal.Cryptography.Helpers.IsDSASupported) return (T?)(object?)certificate.GetDSAPrivateKey(); #endif diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs index ab05ccc6f9f6ef..db93dff50c67ec 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.cs @@ -127,7 +127,7 @@ public sealed override byte[] GetSubjectKeyIdentifier(X509Certificate2 certifica if (keySpec == CryptKeySpec.CERT_NCRYPT_KEY_SPEC) { -#if NETSTANDARD || NETCOREAPP +#if NETSTANDARD || NET Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); #endif diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs index 6351a376c0bc72..1cf3bc1f4a5a20 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs @@ -36,7 +36,7 @@ private static bool DetectInitOnlyOid() } } -#if !NETCOREAPP && !NETSTANDARD2_1 +#if !NET && !NETSTANDARD2_1 // Compatibility API. internal static void AppendData(this IncrementalHash hasher, ReadOnlySpan data) { @@ -364,12 +364,12 @@ public static string ToSerialString(this byte[] serialBytes) return ToUpperHexString(serialBytes); } -#if NET5_0_OR_GREATER +#if NET private static string ToUpperHexString(ReadOnlySpan ba) { return Convert.ToHexString(ba); } -#elif NETCOREAPP || NETSTANDARD2_1 +#elif NETSTANDARD2_1 private static string ToUpperHexString(ReadOnlySpan ba) { return HexConverter.ToString(ba, HexConverter.Casing.Upper); @@ -433,7 +433,7 @@ public static Pkcs9AttributeObject CreateBestPkcs9AttributeObjectAvailable(Oid o Oids.SigningTime => new Pkcs9SigningTime(encodedAttribute), Oids.ContentType => new Pkcs9ContentType(encodedAttribute), Oids.MessageDigest => new Pkcs9MessageDigest(encodedAttribute), -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 Oids.LocalKeyId => new Pkcs9LocalKeyId() { RawData = encodedAttribute.ToArray() }, #endif _ => new Pkcs9AttributeObject(oid, encodedAttribute), diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.DSA.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.DSA.cs index 97192c83b91652..183520aa9c3f0a 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.DSA.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.DSA.cs @@ -43,7 +43,7 @@ protected override bool VerifyKeyType(AsymmetricAlgorithm key) } internal override bool VerifySignature( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan valueHash, ReadOnlyMemory signature, #else @@ -76,7 +76,7 @@ internal override bool VerifySignature( DSAParameters dsaParameters = dsa.ExportParameters(false); int bufSize = 2 * dsaParameters.Q!.Length; -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 byte[] rented = CryptoPool.Rent(bufSize); Span ieee = new Span(rented, 0, bufSize); @@ -91,7 +91,7 @@ internal override bool VerifySignature( } return dsa.VerifySignature(valueHash, ieee); -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 } finally { @@ -101,7 +101,7 @@ internal override bool VerifySignature( } protected override bool Sign( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan dataHash, #else byte[] dataHash, @@ -145,7 +145,7 @@ protected override bool Sign( signatureAlgorithm = oidValue; -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 // The Q size cannot be bigger than the KeySize. byte[] rented = CryptoPool.Rent(dsa.KeySize / 8); int bytesWritten = 0; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs index dd098e46362ea6..e89e6e5232d514 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.ECDsa.cs @@ -44,7 +44,7 @@ protected override bool VerifyKeyType(AsymmetricAlgorithm key) } internal override bool VerifySignature( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan valueHash, ReadOnlyMemory signature, #else @@ -80,7 +80,7 @@ internal override bool VerifySignature( bufSize = 2 * fieldSize; } -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 byte[] rented = CryptoPool.Rent(bufSize); Span ieee = new Span(rented, 0, bufSize); @@ -95,7 +95,7 @@ internal override bool VerifySignature( } return key.VerifyHash(valueHash, ieee); -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 } finally { @@ -105,7 +105,7 @@ internal override bool VerifySignature( } protected override bool Sign( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan dataHash, #else byte[] dataHash, @@ -152,7 +152,7 @@ protected override bool Sign( signatureAlgorithm = oidValue; -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 int bufSize; checked { @@ -188,7 +188,7 @@ protected override bool Sign( #endif signatureValue = DsaIeeeToDer(key.SignHash( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 dataHash.ToArray() #else dataHash diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs index 51677662dd5219..80aa6abb9085a3 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs @@ -45,7 +45,7 @@ protected override bool VerifyKeyType(AsymmetricAlgorithm key) } internal override bool VerifySignature( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan valueHash, ReadOnlyMemory signature, #else @@ -81,7 +81,7 @@ internal override bool VerifySignature( return publicKey.VerifyHash( valueHash, -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 signature.Span, #else signature, @@ -97,7 +97,7 @@ protected abstract RSASignaturePadding GetSignaturePadding( int digestValueLength); private protected static bool SignCore( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan dataHash, #else byte[] dataHash, @@ -122,7 +122,7 @@ private protected static bool SignCore( return false; } -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 byte[] signature = new byte[privateKey.KeySize / 8]; bool signed = privateKey.TrySignHash( @@ -147,7 +147,7 @@ private protected static bool SignCore( } #endif signatureValue = privateKey.SignHash( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 dataHash.ToArray(), #else dataHash, @@ -199,7 +199,7 @@ protected override RSASignaturePadding GetSignaturePadding( } protected override bool Sign( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan dataHash, #else byte[] dataHash, @@ -319,7 +319,7 @@ protected override RSASignaturePadding GetSignaturePadding( } protected override bool Sign( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan dataHash, #else byte[] dataHash, diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs index 7cf3436b54aa63..a0595c61dc3c00 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.cs @@ -30,7 +30,7 @@ static CmsSignature() protected abstract bool VerifyKeyType(AsymmetricAlgorithm key); internal abstract bool VerifySignature( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan valueHash, ReadOnlyMemory signature, #else @@ -43,7 +43,7 @@ internal abstract bool VerifySignature( X509Certificate2 certificate); protected abstract bool Sign( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan dataHash, #else byte[] dataHash, @@ -112,7 +112,7 @@ protected abstract bool Sign( } internal static bool Sign( -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 ReadOnlySpan dataHash, #else byte[] dataHash, @@ -224,7 +224,7 @@ private static byte[] DsaIeeeToDer(ReadOnlySpan ieeeSignature) { writer.PushSequence(); -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 // r BigInteger val = new BigInteger( ieeeSignature.Slice(0, fieldSize), diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs index d9d592c7d578ec..04c2fd59e78aa7 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSigner.cs @@ -73,7 +73,7 @@ public CmsSigner(X509Certificate2? certificate) { } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CmsSignerCspParamsCtorMessage, DiagnosticId = Obsoletions.CmsSignerCspParamsCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs index 0b0700d2658410..51dccc6458d6d2 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs @@ -96,7 +96,7 @@ public X509Certificate2Collection Certificates if (choice.Certificate.HasValue) { coll.Add(new X509Certificate2(choice.Certificate.Value -#if NETCOREAPP +#if NET .Span #else .ToArray() diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs index 021e1f8e9be2d4..46b6fc056e4c1b 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs @@ -262,7 +262,7 @@ private SignerInfoCollection GetCounterSigners(AttributeAsn[] unsignedAttrs) return new SignerInfoCollection(signerInfos.ToArray()); } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.SignerInfoCounterSigMessage, DiagnosticId = Obsoletions.SignerInfoCounterSigDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [EditorBrowsable(EditorBrowsableState.Never)] @@ -746,7 +746,7 @@ private bool VerifySignature( return false; } -#if NETCOREAPP || NETSTANDARD2_1 +#if NET || NETSTANDARD2_1 // SHA-2-512 is the biggest digest type we know about. Span digestValue = stackalloc byte[512 / 8]; ReadOnlySpan digest = digestValue; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs index be71f91529a105..e310abc86cd463 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/CertLoader.cs @@ -14,7 +14,7 @@ internal abstract partial class CertLoader // Prefer ephemeral when available private static X509KeyStorageFlags GetBestKeyStorageFlags() { -#if NETCOREAPP +#if NET if (OperatingSystem.IsWindows()) { // On Windows 7 ephemeral keys with a key usage embedded in the PFX @@ -176,7 +176,7 @@ public CertLoaderFromRawData(byte[] cerData, byte[] pfxData = null, string passw internal override CertLoader CloneAsEphemeralLoader() { -#if NETCOREAPP +#if NET return new CertLoaderFromRawData(CerData, PfxData, Password) { KeyStorageFlags = X509KeyStorageFlags.EphemeralKeySet, diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/DecryptTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/DecryptTests.cs index bca63841dfde72..58ff32fd632859 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/DecryptTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/DecryptTests.cs @@ -835,7 +835,7 @@ internal void VerifySimpleDecrypt(byte[] encodedMessage, CertLoader certLoader, if (cert == null) return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can. -#if NETCOREAPP // API not present on netfx +#if NET // API not present on netfx if (_useExplicitPrivateKey) { using (X509Certificate2 pubCert = certLoader.GetCertificate()) diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/StateTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/StateTests.cs index 02b83db21688f0..288aa11e4ad94f 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/StateTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/StateTests.cs @@ -274,7 +274,7 @@ public static void PostDecode_ContentInfo_netcore() [Theory] [OuterLoop(/* Leaks key on disk if interrupted */)] [InlineData(false)] -#if NETCOREAPP // API not supported on netfx +#if NET // API not supported on netfx [InlineData(true)] #endif public static void PostDecrypt_Encode(bool useExplicitPrivateKey) @@ -300,7 +300,7 @@ public static void PostDecrypt_Encode(bool useExplicitPrivateKey) if (useExplicitPrivateKey) { -#if NETCOREAPP +#if NET ecms.Decrypt(r[0], cer.GetRSAPrivateKey()); #else Assert.Fail("Should not run on this platform"); @@ -362,7 +362,7 @@ public static void PostDecrypt_RecipientInfos() [Theory] [OuterLoop(/* Leaks key on disk if interrupted */)] [InlineData(false)] -#if NETCOREAPP // API not supported on netfx +#if NET // API not supported on netfx [InlineData(true)] #endif public static void PostDecrypt_Decrypt(bool useExplicitPrivateKey) @@ -404,7 +404,7 @@ public static void PostDecrypt_Decrypt(bool useExplicitPrivateKey) { if (useExplicitPrivateKey) { -#if NETCOREAPP +#if NET ecms.Decrypt(r[0], cert1.GetRSAPrivateKey()); #else Assert.Fail("Should not run on this platform"); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/CertBagTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/CertBagTests.cs index 68f364b9d858ab..45ffae839acdac 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/CertBagTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/CertBagTests.cs @@ -47,7 +47,7 @@ public static void OidCtorPreservesFriendlyName() Oid firstCall = certBag.GetCertificateType(); Oid secondCall = certBag.GetCertificateType(); -#if !NETCOREAPP +#if !NET Assert.NotSame(oid, firstCall); Assert.NotSame(oid, secondCall); Assert.NotSame(firstCall, secondCall); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12SafeBagTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12SafeBagTests.cs index d5ace8984490ac..9c7f5e360df666 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12SafeBagTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12SafeBagTests.cs @@ -66,7 +66,7 @@ public static void GetBagIdIsFactory() Assert.Equal(Oids.Aes192, firstCall.Value); Assert.Equal(firstCall.Value, secondCall.Value); -#if !NETCOREAPP +#if !NET Assert.NotSame(firstCall, secondCall); #endif } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/CmsSignerTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/CmsSignerTests.cs index a99d2f8d4dde94..27be5cf21152f1 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/CmsSignerTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/CmsSignerTests.cs @@ -21,7 +21,7 @@ public static void SignerIdentifierType_InvalidValues(SubjectIdentifierType inva () => signer.SignerIdentifierType = invalidType); } -#if NETCOREAPP +#if NET [Fact] public static void SignaturePadding_InvalidValue() { diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs index 7eee42aa5db719..c0c1421daac423 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs @@ -562,7 +562,7 @@ public static void AddFirstSigner_DSA(SubjectIdentifierType identifierType, bool Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); Assert.Equal(cms.Certificates[0], firstSigner.Certificate); -#if NETCOREAPP +#if NET byte[] signature = firstSigner.GetSignature(); Assert.NotEmpty(signature); // DSA PKIX signature format is a DER SEQUENCE. @@ -581,7 +581,7 @@ public static void AddFirstSigner_DSA(SubjectIdentifierType identifierType, bool Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); -#if NETCOREAPP +#if NET byte[] sig2 = cms.SignerInfos[0].GetSignature(); Assert.Equal(signature, sig2); #endif @@ -633,7 +633,7 @@ public static void AddFirstSigner_ECDSA(SubjectIdentifierType identifierType, bo Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); Assert.Equal(cms.Certificates[0], firstSigner.Certificate); -#if NETCOREAPP +#if NET byte[] signature = firstSigner.GetSignature(); Assert.NotEmpty(signature); // ECDSA PKIX signature format is a DER SEQUENCE. @@ -655,7 +655,7 @@ public static void AddFirstSigner_ECDSA(SubjectIdentifierType identifierType, bo Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); -#if NETCOREAPP +#if NET byte[] sig2 = cms.SignerInfos[0].GetSignature(); Assert.Equal(signature, sig2); #endif @@ -1165,7 +1165,7 @@ public static void EnsureDataIsolation_NewDocument(bool detached) // CheckSignature doesn't read the public mutable data contentInfo.Content[0] ^= 0xFF; -#if !NETCOREAPP +#if !NET contentInfo.ContentType.Value = Oids.Pkcs7Hashed; #endif cms.CheckSignature(true); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs index 8918d7adbb66c6..c5b7c000e2b733 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsWholeDocumentTests.cs @@ -60,7 +60,7 @@ public static void ReadRsaPssDocument(bool fromSpan) Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, signer.SignerIdentifier.Type); Assert.Equal("1063CAB14FB14C47DC211C0E0285F3EE5946BF2D", signer.SignerIdentifier.Value); Assert.Equal("2.16.840.1.101.3.4.2.1", signer.DigestAlgorithm.Value); -#if NETCOREAPP +#if NET Assert.Equal("1.2.840.113549.1.1.10", signer.SignatureAlgorithm.Value); #endif @@ -91,7 +91,7 @@ public static void ReadRsaPssDocument(bool fromSpan) messageDigestAttr.MessageDigest.ByteArrayToHex()); Assert.IsType(signedAttrs[3].Values[0]); -#if !NETCOREAPP +#if !NET Assert.NotSame(signedAttrs[3].Oid, signedAttrs[3].Values[0].Oid); #endif Assert.Equal( @@ -101,7 +101,7 @@ public static void ReadRsaPssDocument(bool fromSpan) "082A864886F70D0302020128", signedAttrs[3].Values[0].RawData.ByteArrayToHex()); -#if NETCOREAPP +#if NET Assert.Equal( "B93E81D141B3C9F159AB0021910635DC72E8E860BE43C28E5D53243D6DC247B7" + "D4F18C20195E80DEDCC75B29C43CE5047AD775B65BFC93589BD748B950C68BAD" + @@ -170,7 +170,7 @@ public static void ReadRsaPkcs1SimpleDocument() Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type); Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value); -#if NETCOREAPP +#if NET Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value); Assert.Equal( @@ -237,7 +237,7 @@ public static void ReadRsaPkcs1CounterSigned() Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type); Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value); -#if NETCOREAPP +#if NET Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value); Assert.Equal( @@ -311,7 +311,7 @@ public static void CheckNoSignatureDocument() Assert.Null(signer.Certificate); Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value); -#if NETCOREAPP +#if NET Assert.Equal("1.3.6.1.5.5.7.6.2", signer.SignatureAlgorithm.Value); Assert.Equal( @@ -370,7 +370,7 @@ public static void CheckNoSignatureDocument() "833378066BDCCBA7047EF6919843D181A57D6479", csMessageDigest.MessageDigest.ByteArrayToHex()); -#if NETCOREAPP +#if NET Assert.Equal(Oids.Rsa, counterSigner.SignatureAlgorithm.Value); Assert.Equal( @@ -447,7 +447,7 @@ public static void NonEmbeddedCertificate() Assert.Empty(signer.CounterSignerInfos); Assert.Null(signer.Certificate); -#if NETCOREAPP +#if NET Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value); Assert.Equal( @@ -551,7 +551,7 @@ public static void ReadRsaPkcs1DoubleCounterSigned() Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type); Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value); -#if NETCOREAPP +#if NET Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value); Assert.Equal( @@ -597,7 +597,7 @@ public static void ReadRsaPkcs1DoubleCounterSigned() // Assert.NotThrows cms.CheckSignature(true); -#if NETCOREAPP +#if NET Assert.Equal( "1AA282DBED4D862D7CEA30F803E790BDB0C97EE852778CEEDDCD94BB9304A155" + "2E60A8D36052AC8C2D28755F3B2F473824100AB3A6ABD4C15ABD77E0FFE13D0D" + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs index 10a51fc819545a..37d8b29ddc5d11 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs @@ -100,7 +100,7 @@ public static void SignerInfo_CounterSignerInfos_UniquePerCall_WhenNonEmpty() Assert.NotSame(counterSigner.Certificate, counterSigner2.Certificate); Assert.Equal(counterSigner.Certificate, counterSigner2.Certificate); -#if NETCOREAPP +#if NET byte[] signature = counterSigner.GetSignature(); byte[] signature2 = counterSigner2.GetSignature(); @@ -110,7 +110,7 @@ public static void SignerInfo_CounterSignerInfos_UniquePerCall_WhenNonEmpty() } } -#if NETCOREAPP +#if NET [Fact] public static void SignerInfo_GetSignature_UniquePerCall() { @@ -139,7 +139,7 @@ public static void SignerInfo_DigestAlgorithm_NotSame() Assert.NotSame(oid, oid2); } -#if NETCOREAPP +#if NET [Fact] public static void SignerInfo_SignatureAlgorithm_NotSame() { @@ -745,7 +745,7 @@ public static void AddCounterSigner_DSA() Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); Assert.Equal(2, cms.Certificates.Count); -#if NETCOREAPP +#if NET byte[] signature = counterSigner.GetSignature(); Assert.NotEmpty(signature); // DSA PKIX signature format is a DER SEQUENCE. @@ -813,7 +813,7 @@ public static void AddCounterSigner_ECDSA(SubjectIdentifierType identifierType, Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); Assert.Equal(2, cms.Certificates.Count); -#if NETCOREAPP +#if NET byte[] signature = counterSigner.GetSignature(); Assert.NotEmpty(signature); // DSA PKIX signature format is a DER SEQUENCE. diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs index 17fedbe3daa9a0..5a6ece8b2d6c9b 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs @@ -50,7 +50,7 @@ internal static class CryptoHelpers [RequiresDynamicCode(XsltRequiresDynamicCodeMessage)] private static XmlDsigXsltTransform CreateXmlDsigXsltTransform() { -#if NETCOREAPP +#if NET if (!RuntimeFeature.IsDynamicCodeSupported) { // XSLTs are only supported when dynamic code is supported. See https://github.com/dotnet/runtime/issues/84389 @@ -73,7 +73,7 @@ private static XmlDsigXsltTransform CreateXmlDsigXsltTransform() { return (CryptoConfig.CreateFromName(name) ?? CreateFromKnownName(name)) as T; } -#if NETCOREAPP +#if NET catch (NotSupportedException) { if (name == "http://www.w3.org/TR/1999/REC-xslt-19991116") diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs index 22b1c4c355a79b..46e214ab54fa56 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs @@ -17,7 +17,7 @@ public DSASignatureDescription() DigestAlgorithm = "SHA1"; } -#if NETCOREAPP +#if NET [RequiresUnreferencedCode("CreateDeformatter is not trim compatible because the algorithm implementation referenced by DeformatterAlgorithm might be removed.")] #endif public sealed override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key) @@ -28,7 +28,7 @@ public sealed override AsymmetricSignatureDeformatter CreateDeformatter(Asymmetr return item; } -#if NETCOREAPP +#if NET [RequiresUnreferencedCode("CreateFormatter is not trim compatible because the algorithm implementation referenced by FormatterAlgorithm might be removed.")] #endif public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs index 6d5a8fd733e03a..28e0850891d8a1 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs @@ -15,7 +15,7 @@ public RSAPKCS1SignatureDescription(string hashAlgorithmName) DigestAlgorithm = hashAlgorithmName; } -#if NETCOREAPP +#if NET [RequiresUnreferencedCode("CreateDeformatter is not trim compatible because the algorithm implementation referenced by DeformatterAlgorithm might be removed.")] #endif public sealed override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key) @@ -26,7 +26,7 @@ public sealed override AsymmetricSignatureDeformatter CreateDeformatter(Asymmetr return item; } -#if NETCOREAPP +#if NET [RequiresUnreferencedCode("CreateFormatter is not trim compatible because the algorithm implementation referenced by FormatterAlgorithm might be removed.")] #endif public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) @@ -37,7 +37,7 @@ public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAl return item; } -#if NETCOREAPP +#if NET [RequiresUnreferencedCode("CreateDigest is not trim compatible because the algorithm implementation referenced by DigestAlgorithm might be removed.")] #endif public abstract override HashAlgorithm CreateDigest(); diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs index ffffeefa5bac37..5505994fd82933 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs @@ -720,7 +720,7 @@ internal static X509Certificate2Collection BuildBagOfCerts(KeyInfoX509Data keyIn return collection; } -#if NET5_0_OR_GREATER +#if NET internal static string EncodeHexString(byte[] sArray) { return Convert.ToHexString(sArray); @@ -761,7 +761,7 @@ internal static bool IsSelfSigned(X509Chain chain) { AsymmetricAlgorithm? algorithm = (AsymmetricAlgorithm?)certificate.GetRSAPublicKey() ?? certificate.GetECDsaPublicKey(); -#if NETCOREAPP +#if NET if (algorithm is null && !OperatingSystem.IsTvOS() && !OperatingSystem.IsIOS()) { algorithm = certificate.GetDSAPublicKey(); diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlResolverHelper.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlResolverHelper.cs index 3070ffa8e1d233..948f883b80a2eb 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlResolverHelper.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlResolverHelper.cs @@ -11,14 +11,14 @@ internal static class XmlResolverHelper { internal static XmlResolver GetThrowingResolver() { -#if NET7_0_OR_GREATER +#if NET return XmlResolver.ThrowingResolver; #else return XmlThrowingResolver.s_singleton; #endif } -#if !NET7_0_OR_GREATER +#if !NET // An XmlResolver that forbids all external entity resolution. // (Copied from XmlResolver.ThrowingResolver.cs.) private sealed class XmlThrowingResolver : XmlResolver diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/ReferenceTest.cs b/src/libraries/System.Security.Cryptography.Xml/tests/ReferenceTest.cs index a28065dac5a310..db65e8de538167 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/ReferenceTest.cs +++ b/src/libraries/System.Security.Cryptography.Xml/tests/ReferenceTest.cs @@ -131,7 +131,7 @@ public void LoadXPathTransforms() [ConditionalFact] public void LoadXsltTransforms() { -#if NETCOREAPP +#if NET if (!RuntimeFeature.IsDynamicCodeSupported) { throw new SkipTestException("XSLTs are only supported when dynamic code is supported. See https://github.com/dotnet/runtime/issues/84389"); @@ -167,7 +167,7 @@ public void LoadAllTransforms() xsltTransform += ""; xsltTransform += ""; int expectedTransformsCount = 6; -#if NETCOREAPP +#if NET if (!RuntimeFeature.IsDynamicCodeSupported) { // XSLTs are only supported when dynamic code is supported. See https://github.com/dotnet/runtime/issues/84389 diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/Samples/SigningVerifyingX509Cert.cs b/src/libraries/System.Security.Cryptography.Xml/tests/Samples/SigningVerifyingX509Cert.cs index 37431c1e53c124..69af96accd8db0 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/Samples/SigningVerifyingX509Cert.cs +++ b/src/libraries/System.Security.Cryptography.Xml/tests/Samples/SigningVerifyingX509Cert.cs @@ -87,7 +87,7 @@ public void SignedXmlHasDSACertificateVerifiableSignature() xmlDoc.PreserveWhitespace = true; xmlDoc.LoadXml(ExampleXml); -#if NETCOREAPP +#if NET using (DSA key = x509cert.GetDSAPrivateKey()) { SignXml(xmlDoc, key); diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs b/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs index bd22c5b835eed8..54c153694f7bf7 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs +++ b/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs @@ -1673,7 +1673,7 @@ static byte[] GetResponse() => try { -#if NETCOREAPP +#if NET socket = await listener.AcceptSocketAsync(cancellationToken); #else socket = await listener.AcceptSocketAsync(); diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj b/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj index 858a44b23608f9..56458c07a5a0f7 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj @@ -75,6 +75,7 @@ - + + diff --git a/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs b/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs index 16364a4315c354..17e498325abb27 100644 --- a/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs @@ -229,7 +229,7 @@ internal static DSA GetWorkingDSA() { DSA dsa = DSA.Create(); -#if NETCOREAPP +#if NET if (OperatingSystem.IsMacOS()) { // macOS cannot generate DSA keys, so for this platform we will use a fixed key. diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index a6ee388c8ceca2..4bd007d9030c39 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -2587,6 +2587,7 @@ public Shake128() { } public static bool IsSupported { get { throw null; } } public void AppendData(byte[] data) { } public void AppendData(System.ReadOnlySpan data) { } + public System.Security.Cryptography.Shake128 Clone() { throw null; } public void Dispose() { } public byte[] GetCurrentHash(int outputLength) { throw null; } public void GetCurrentHash(System.Span destination) { } @@ -2599,6 +2600,9 @@ public static void HashData(System.IO.Stream source, System.Span destinati public static void HashData(System.ReadOnlySpan source, System.Span destination) { } public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, int outputLength, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public byte[] Read(int outputLength) { throw null; } + public void Read(System.Span destination) { } + public void Reset() { } } public sealed partial class Shake256 : System.IDisposable { @@ -2606,6 +2610,7 @@ public Shake256() { } public static bool IsSupported { get { throw null; } } public void AppendData(byte[] data) { } public void AppendData(System.ReadOnlySpan data) { } + public System.Security.Cryptography.Shake256 Clone() { throw null; } public void Dispose() { } public byte[] GetCurrentHash(int outputLength) { throw null; } public void GetCurrentHash(System.Span destination) { } @@ -2618,6 +2623,9 @@ public static void HashData(System.IO.Stream source, System.Span destinati public static void HashData(System.ReadOnlySpan source, System.Span destination) { } public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, int outputLength, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask HashDataAsync(System.IO.Stream source, System.Memory destination, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public byte[] Read(int outputLength) { throw null; } + public void Read(System.Span destination) { } + public void Reset() { } } public partial class SignatureDescription { diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index b121f8fd75c2d8..05c91987126a78 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -780,6 +780,9 @@ The algorithm's block size is not supported. + + This operation is not supported once the algorithm has started reading. + CryptoApi ECDsa keys are not supported. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.macOS.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.macOS.cs index 3b528f496f4d91..d9f036f61ca5d7 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.macOS.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AesGcm.macOS.cs @@ -11,7 +11,7 @@ public sealed partial class AesGcm { private FixedMemoryKeyBox _keyBox; - // CryptoKit added AES.GCM in macOS 10.15, which is our minimum target for macOS. + // CryptoKit added AES.GCM in macOS 10.15, which is lower than our minimum target for macOS. public static bool IsSupported => true; // CryptoKit only supports 16 byte tags. diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs index aa2cba5f234ba7..7e45061f971a6e 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/ChaCha20Poly1305.macOS.cs @@ -8,7 +8,7 @@ namespace System.Security.Cryptography { public sealed partial class ChaCha20Poly1305 { - // CryptoKit added ChaCha20Poly1305 in macOS 10.15, which is our minimum target for macOS. + // CryptoKit added ChaCha20Poly1305 in macOS 10.15, which is lower than our minimum target for macOS. public static bool IsSupported => true; private FixedMemoryKeyBox _keyBox; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Apple.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Apple.cs index 0b2fde720a20d4..1dbfd5567f02ea 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Apple.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Apple.cs @@ -39,6 +39,8 @@ internal static LiteXof CreateXof(string hashAlgorithmId) public int Finalize(Span destination) => throw new UnreachableException(); public void Current(Span destination) => throw new UnreachableException(); public int Reset() => throw new UnreachableException(); + public LiteXof Clone() => throw new UnreachableException(); + public void Read(Span destination) => throw new UnreachableException(); public void Dispose() => throw new UnreachableException(); #pragma warning restore IDE0060 #pragma warning restore CA1822 diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Browser.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Browser.cs index 92de5db403f3dc..5591479f0c794b 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Browser.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Browser.cs @@ -34,6 +34,8 @@ internal static LiteXof CreateXof(string hashAlgorithmId) public int Finalize(Span destination) => throw new UnreachableException(); public void Current(Span destination) => throw new UnreachableException(); public int Reset() => throw new UnreachableException(); + public LiteXof Clone() => throw new UnreachableException(); + public void Read(Span destination) => throw new UnreachableException(); public void Dispose() => throw new UnreachableException(); #pragma warning restore IDE0060 #pragma warning restore CA1822 diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Unix.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Unix.cs index ab09b7217f89a4..32ebdb5ce092cd 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Unix.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Unix.cs @@ -44,6 +44,12 @@ internal LiteXof(IntPtr algorithm) Interop.Crypto.CheckValidOpenSslHandle(_ctx); } + private LiteXof(SafeEvpMdCtxHandle ctx, IntPtr algorithm) + { + _ctx = ctx; + _algorithm = algorithm; + } + public void Append(ReadOnlySpan data) { if (data.IsEmpty) @@ -70,6 +76,18 @@ public void Current(Span destination) Check(Interop.Crypto.EvpDigestCurrentXOF(_ctx, destination)); } + public LiteXof Clone() + { + SafeEvpMdCtxHandle clone = Interop.Crypto.EvpMdCtxCopyEx(_ctx); + Interop.Crypto.CheckValidOpenSslHandle(clone); + return new LiteXof(clone, _algorithm); + } + + public void Read(Span destination) + { + Check(Interop.Crypto.EvpDigestSqueeze(_ctx, destination)); + } + public void Dispose() { _ctx.Dispose(); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Windows.cs index bb3df4bb2f4c54..324001daee995e 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/LiteHash.Windows.cs @@ -159,10 +159,11 @@ private static void CheckStatus(NTSTATUS status) } } - internal struct LiteXof : ILiteHash + internal readonly struct LiteXof : ILiteHash { + private const int BCRYPT_HASH_DONT_RESET_FLAG = 0x00000001; private readonly nuint _algorithm; - private SafeBCryptHashHandle _hashHandle; + private readonly SafeBCryptHashHandle _hashHandle; internal LiteXof(string algorithm) { @@ -173,7 +174,24 @@ internal LiteXof(string algorithm) _ => throw FailThrow(algorithm), }; - Reset(); + SafeBCryptHashHandle hashHandle; + + NTSTATUS ntStatus = Interop.BCrypt.BCryptCreateHash( + _algorithm, + out hashHandle, + pbHashObject: IntPtr.Zero, + cbHashObject: 0, + secret: ReadOnlySpan.Empty, + cbSecret: 0, + BCryptCreateHashFlags.None); + + if (ntStatus != NTSTATUS.STATUS_SUCCESS) + { + hashHandle.Dispose(); + throw Interop.BCrypt.CreateCryptographicException(ntStatus); + } + + _hashHandle = hashHandle; static Exception FailThrow(string algorithm) { @@ -182,7 +200,13 @@ static Exception FailThrow(string algorithm) } } - public readonly int HashSizeInBytes + private LiteXof(SafeBCryptHashHandle hashHandle, nuint algorithm) + { + _algorithm = algorithm; + _hashHandle = hashHandle; + } + + public int HashSizeInBytes { get { @@ -191,7 +215,7 @@ public readonly int HashSizeInBytes } } - public readonly void Append(ReadOnlySpan data) + public void Append(ReadOnlySpan data) { if (data.IsEmpty) { @@ -206,7 +230,7 @@ public readonly void Append(ReadOnlySpan data) } } - public readonly unsafe int Finalize(Span destination) + public unsafe int Finalize(Span destination) { fixed (byte* pDestination = &Helpers.GetNonNullPinnableReference(destination)) { @@ -221,36 +245,33 @@ public readonly unsafe int Finalize(Span destination) } } - [MemberNotNull(nameof(_hashHandle))] - public void Reset() - { - _hashHandle?.Dispose(); - SafeBCryptHashHandle hashHandle; - - NTSTATUS ntStatus = Interop.BCrypt.BCryptCreateHash( - _algorithm, - out hashHandle, - pbHashObject: IntPtr.Zero, - cbHashObject: 0, - secret: ReadOnlySpan.Empty, - cbSecret: 0, - BCryptCreateHashFlags.None); + public void Reset() => Finalize(Span.Empty); - if (ntStatus != NTSTATUS.STATUS_SUCCESS) + public unsafe void Current(Span destination) + { + using (SafeBCryptHashHandle tmpHash = Interop.BCrypt.BCryptDuplicateHash(_hashHandle)) + fixed (byte* pDestination = &Helpers.GetNonNullPinnableReference(destination)) { - hashHandle.Dispose(); - throw Interop.BCrypt.CreateCryptographicException(ntStatus); + NTSTATUS ntStatus = Interop.BCrypt.BCryptFinishHash(tmpHash, pDestination, destination.Length, dwFlags: 0); + + if (ntStatus != NTSTATUS.STATUS_SUCCESS) + { + throw Interop.BCrypt.CreateCryptographicException(ntStatus); + } } + } - _hashHandle = hashHandle; + public LiteXof Clone() + { + SafeBCryptHashHandle clone = Interop.BCrypt.BCryptDuplicateHash(_hashHandle); + return new LiteXof(clone, _algorithm); } - public readonly unsafe void Current(Span destination) + public unsafe void Read(Span destination) { - using (SafeBCryptHashHandle tmpHash = Interop.BCrypt.BCryptDuplicateHash(_hashHandle)) fixed (byte* pDestination = &Helpers.GetNonNullPinnableReference(destination)) { - NTSTATUS ntStatus = Interop.BCrypt.BCryptFinishHash(tmpHash, pDestination, destination.Length, dwFlags: 0); + NTSTATUS ntStatus = Interop.BCrypt.BCryptFinishHash(_hashHandle, pDestination, destination.Length, dwFlags: BCRYPT_HASH_DONT_RESET_FLAG); if (ntStatus != NTSTATUS.STATUS_SUCCESS) { @@ -259,7 +280,7 @@ public readonly unsafe void Current(Span destination) } } - public readonly void Dispose() + public void Dispose() { _hashHandle.Dispose(); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake128.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake128.cs index 14dc8e0eac407c..80740c59a657dd 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake128.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake128.cs @@ -19,10 +19,10 @@ namespace System.Security.Cryptography /// public sealed partial class Shake128 : IDisposable { - // Some platforms have a mutable struct for LiteXof, do not mark this field as readonly. - private LiteXof _hashProvider; + private readonly LiteXof _hashProvider; private bool _disposed; private ConcurrencyBlock _block; + private bool _reading; /// /// Initializes a new instance of the class. @@ -37,6 +37,11 @@ public Shake128() _hashProvider = LiteHashProvider.CreateXof(HashAlgorithmId); } + internal Shake128(LiteXof hashProvider) + { + _hashProvider = hashProvider; + } + /// /// Gets a value that indicates whether the algorithm is supported on the current platform. /// @@ -71,6 +76,7 @@ public void AppendData(ReadOnlySpan data) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); _hashProvider.Append(data); } } @@ -93,6 +99,7 @@ public byte[] GetHashAndReset(int outputLength) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); byte[] output = new byte[outputLength]; _hashProvider.Finalize(output); _hashProvider.Reset(); @@ -113,6 +120,7 @@ public void GetHashAndReset(Span destination) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); _hashProvider.Finalize(destination); _hashProvider.Reset(); } @@ -136,6 +144,7 @@ public byte[] GetCurrentHash(int outputLength) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); byte[] output = new byte[outputLength]; _hashProvider.Current(output); return output; @@ -155,10 +164,99 @@ public void GetCurrentHash(Span destination) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); _hashProvider.Current(destination); } } + /// + /// Retrieves the hash for the data accumulated from prior calls to the AppendData methods without + /// resetting the object to its initial state and allowing additional calls to continue retrieving the hash. + /// + /// The size of the hash to produce. + /// The computed hash. + /// + /// is negative. + /// + /// An error has occurred during the operation. + /// The object has already been disposed. + /// + /// The platform does not support multiple reads of the hash. can be used + /// to perform a single operation. + /// + public byte[] Read(int outputLength) + { + ArgumentOutOfRangeException.ThrowIfNegative(outputLength); + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + byte[] output = new byte[outputLength]; + _hashProvider.Read(output); + _reading = true; + return output; + } + } + + /// + /// Fills the buffer with the hash for the data accumulated from prior calls to the AppendData methods without + /// resetting the object to its initial state and allowing additional calls to continue retrieving the hash. + /// + /// The buffer to fill with the hash. + /// An error has occurred during the operation. + /// The object has already been disposed. + /// + /// The platform does not support multiple reads of the hash. can be used + /// to perform a single operation. + /// + public void Read(Span destination) + { + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + _hashProvider.Read(destination); + _reading = true; + } + } + + /// + /// Resets the instance back to its initial state. + /// + /// An error has occurred during the operation. + /// The object has already been disposed. + public void Reset() + { + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + _hashProvider.Reset(); + _reading = false; + } + } + + /// + /// Creates a new instance of with the existing appended data preserved. + /// + /// A clone of the current instance. + /// An error has occurred during the operation. + /// + /// The current instance is being read from and cannot be cloned. + /// + /// The object has already been disposed. + public Shake128 Clone() + { + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + CheckReading(); + LiteXof clone = _hashProvider.Clone(); + return new Shake128(clone); + } + } + /// /// Release all resources used by the current instance of the class. /// @@ -385,5 +483,13 @@ private static void CheckPlatformSupport() } private void CheckDisposed() => ObjectDisposedException.ThrowIf(_disposed, this); + + private void CheckReading() + { + if (_reading) + { + throw new InvalidOperationException(SR.InvalidOperation_AlreadyReading); + } + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake256.cs index c801adde9395ca..d861257cf1e480 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/Shake256.cs @@ -19,10 +19,10 @@ namespace System.Security.Cryptography /// public sealed partial class Shake256 : IDisposable { - // Some platforms have a mutable struct for LiteXof, do not mark this field as readonly. - private LiteXof _hashProvider; + private readonly LiteXof _hashProvider; private bool _disposed; private ConcurrencyBlock _block; + private bool _reading; /// /// Initializes a new instance of the class. @@ -37,6 +37,11 @@ public Shake256() _hashProvider = LiteHashProvider.CreateXof(HashAlgorithmId); } + internal Shake256(LiteXof hashProvider) + { + _hashProvider = hashProvider; + } + /// /// Gets a value that indicates whether the algorithm is supported on the current platform. /// @@ -71,6 +76,7 @@ public void AppendData(ReadOnlySpan data) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); _hashProvider.Append(data); } } @@ -93,6 +99,7 @@ public byte[] GetHashAndReset(int outputLength) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); byte[] output = new byte[outputLength]; _hashProvider.Finalize(output); _hashProvider.Reset(); @@ -113,6 +120,7 @@ public void GetHashAndReset(Span destination) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); _hashProvider.Finalize(destination); _hashProvider.Reset(); } @@ -136,6 +144,7 @@ public byte[] GetCurrentHash(int outputLength) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); byte[] output = new byte[outputLength]; _hashProvider.Current(output); return output; @@ -155,10 +164,99 @@ public void GetCurrentHash(Span destination) using (ConcurrencyBlock.Enter(ref _block)) { + CheckReading(); _hashProvider.Current(destination); } } + /// + /// Retrieves the hash for the data accumulated from prior calls to the AppendData methods without + /// resetting the object to its initial state and allowing additional calls to continue retrieving the hash. + /// + /// The size of the hash to produce. + /// The computed hash. + /// + /// is negative. + /// + /// An error has occurred during the operation. + /// The object has already been disposed. + /// + /// The platform does not support multiple reads of the hash. can be used + /// to perform a single operation. + /// + public byte[] Read(int outputLength) + { + ArgumentOutOfRangeException.ThrowIfNegative(outputLength); + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + byte[] output = new byte[outputLength]; + _hashProvider.Read(output); + _reading = true; + return output; + } + } + + /// + /// Fills the buffer with the hash for the data accumulated from prior calls to the AppendData methods without + /// resetting the object to its initial state and allowing additional calls to continue retrieving the hash. + /// + /// The buffer to fill with the hash. + /// An error has occurred during the operation. + /// The object has already been disposed. + /// + /// The platform does not support multiple reads of the hash. can be used + /// to perform a single operation. + /// + public void Read(Span destination) + { + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + _hashProvider.Read(destination); + _reading = true; + } + } + + /// + /// Resets the instance back to its initial state. + /// + /// An error has occurred during the operation. + /// The object has already been disposed. + public void Reset() + { + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + _hashProvider.Reset(); + _reading = false; + } + } + + /// + /// Creates a new instance of with the existing appended data preserved. + /// + /// A clone of the current instance. + /// An error has occurred during the operation. + /// + /// The current instance is being read from and cannot be cloned. + /// + /// The object has already been disposed. + public Shake256 Clone() + { + CheckDisposed(); + + using (ConcurrencyBlock.Enter(ref _block)) + { + CheckReading(); + LiteXof clone = _hashProvider.Clone(); + return new Shake256(clone); + } + } + /// /// Release all resources used by the current instance of the class. /// @@ -385,5 +483,13 @@ private static void CheckPlatformSupport() } private void CheckDisposed() => ObjectDisposedException.ThrowIf(_disposed, this); + + private void CheckReading() + { + if (_reading) + { + throw new InvalidOperationException(SR.InvalidOperation_AlreadyReading); + } + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/AsymmetricAlgorithm/Trivial.cs b/src/libraries/System.Security.Cryptography/tests/AsymmetricAlgorithm/Trivial.cs index 1fb2f0306aa8ef..97a6ba6d3548ae 100644 --- a/src/libraries/System.Security.Cryptography/tests/AsymmetricAlgorithm/Trivial.cs +++ b/src/libraries/System.Security.Cryptography/tests/AsymmetricAlgorithm/Trivial.cs @@ -51,7 +51,7 @@ public static void ValidKeySizeUsesProperty() } } -#if NETCOREAPP +#if NET [Fact] public static void ClearCallsDispose() { diff --git a/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs b/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs index ced6edcf350951..00ae5286b25a92 100644 --- a/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/ChaCha20Poly1305Tests.cs @@ -475,7 +475,7 @@ public static void CheckIsSupported() } else if (PlatformDetection.IsOSX) { - // CryptoKit is supported on macOS 10.15+, which is our minimum target. + // CryptoKit is supported on macOS 10.15+, which is lower than our minimum target. expectedIsSupported = true; } else if (PlatformDetection.OpenSslPresentOnSystem && PlatformDetection.IsOpenSslSupported) diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultDSAProvider.cs b/src/libraries/System.Security.Cryptography/tests/DefaultDSAProvider.cs index e04a1ce81f2602..03c3bf5d02a349 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultDSAProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultDSAProvider.cs @@ -12,7 +12,7 @@ public DSA Create() public DSA Create(int keySize) { -#if NETCOREAPP +#if NET return DSA.Create(keySize); #else DSA dsa = Create(); diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs index 001869125e0ca5..91015c49a39f4e 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs @@ -19,7 +19,7 @@ public ECDsa Create(int keySize) return ec; } -#if NETCOREAPP +#if NET public ECDsa Create(ECCurve curve) { return ECDsa.Create(curve); diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs b/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs index c65b78ace1288e..ab19c2aa03344a 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultRSAProvider.cs @@ -15,7 +15,7 @@ public class DefaultRSAProvider : IRSAProvider public RSA Create(int keySize) { -#if NETCOREAPP +#if NET return RSA.Create(keySize); #else RSA rsa = Create(); diff --git a/src/libraries/System.Security.Cryptography/tests/Shake128Tests.cs b/src/libraries/System.Security.Cryptography/tests/Shake128Tests.cs index e203d77f46b6cf..8cfa95b57621e1 100644 --- a/src/libraries/System.Security.Cryptography/tests/Shake128Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Shake128Tests.cs @@ -21,6 +21,10 @@ public class Traits : IShakeTrait public static void GetHashAndReset(Shake128 shake, Span destination) => shake.GetHashAndReset(destination); public static byte[] GetCurrentHash(Shake128 shake, int outputLength) => shake.GetCurrentHash(outputLength); public static void GetCurrentHash(Shake128 shake, Span destination) => shake.GetCurrentHash(destination); + public static void Read(Shake128 shake, Span destination) => shake.Read(destination); + public static byte[] Read(Shake128 shake, int outputLength) => shake.Read(outputLength); + public static void Reset(Shake128 shake) => shake.Reset(); + public static Shake128 Clone(Shake128 shake) => shake.Clone(); public static byte[] HashData(byte[] source, int outputLength) => Shake128.HashData(source, outputLength); public static byte[] HashData(ReadOnlySpan source, int outputLength) => Shake128.HashData(source, outputLength); diff --git a/src/libraries/System.Security.Cryptography/tests/Shake256Tests.cs b/src/libraries/System.Security.Cryptography/tests/Shake256Tests.cs index 9631752e69444e..23886ccb2b2dce 100644 --- a/src/libraries/System.Security.Cryptography/tests/Shake256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Shake256Tests.cs @@ -21,6 +21,10 @@ public class Traits : IShakeTrait public static void GetHashAndReset(Shake256 shake, Span destination) => shake.GetHashAndReset(destination); public static byte[] GetCurrentHash(Shake256 shake, int outputLength) => shake.GetCurrentHash(outputLength); public static void GetCurrentHash(Shake256 shake, Span destination) => shake.GetCurrentHash(destination); + public static void Read(Shake256 shake, Span destination) => shake.Read(destination); + public static byte[] Read(Shake256 shake, int outputLength) => shake.Read(outputLength); + public static void Reset(Shake256 shake) => shake.Reset(); + public static Shake256 Clone(Shake256 shake) => shake.Clone(); public static byte[] HashData(byte[] source, int outputLength) => Shake256.HashData(source, outputLength); public static byte[] HashData(ReadOnlySpan source, int outputLength) => Shake256.HashData(source, outputLength); diff --git a/src/libraries/System.Security.Cryptography/tests/ShakeTestDriver.cs b/src/libraries/System.Security.Cryptography/tests/ShakeTestDriver.cs index d0c25b1722eeaa..658d1b83a80d26 100644 --- a/src/libraries/System.Security.Cryptography/tests/ShakeTestDriver.cs +++ b/src/libraries/System.Security.Cryptography/tests/ShakeTestDriver.cs @@ -12,7 +12,7 @@ namespace System.Security.Cryptography.Tests { - public interface IShakeTrait where TShake : IDisposable, new() + public interface IShakeTrait where TShake : class, IDisposable, new() { static abstract TShake Create(); static abstract bool IsSupported { get; } @@ -22,6 +22,10 @@ namespace System.Security.Cryptography.Tests static abstract void GetHashAndReset(TShake shake, Span destination); static abstract byte[] GetCurrentHash(TShake shake, int outputLength); static abstract void GetCurrentHash(TShake shake, Span destination); + static abstract void Read(TShake shake, Span destination); + static abstract byte[] Read(TShake shake, int outputLength); + static abstract void Reset(TShake shake); + static abstract TShake Clone(TShake shake); static abstract byte[] HashData(byte[] source, int outputLength); static abstract byte[] HashData(ReadOnlySpan source, int outputLength); @@ -37,12 +41,21 @@ namespace System.Security.Cryptography.Tests public abstract class ShakeTestDriver where TShakeTrait : IShakeTrait - where TShake : IDisposable, new() + where TShake : class, IDisposable, new() { protected abstract IEnumerable<(string Msg, string Output)> Fips202Kats { get; } public static bool IsSupported => TShakeTrait.IsSupported; public static bool IsNotSupported => !IsSupported; + public static bool IsReadSupported + { + get + { + const long OpenSsl_3_2_0 = 0x30200000L; + return IsSupported && (PlatformDetection.IsWindows || SafeEvpPKeyHandle.OpenSslVersion >= OpenSsl_3_2_0); + } + } + [ConditionalFact(nameof(IsSupported))] public void KnownAnswerTests_Allocated_AllAtOnce() { @@ -151,6 +164,113 @@ public void KnownAnswerTests_Allocated_Hash_Destination() } } + [ConditionalFact(nameof(IsReadSupported))] + public void KnownAnswerTests_Allocated_Read_Twice() + { + foreach ((string Msg, string Output) kat in Fips202Kats) + { + byte[] message = Convert.FromHexString(kat.Msg); + + using (TShake shake = new TShake()) + { + TShakeTrait.AppendData(shake, message); + Span hash = new byte[kat.Output.Length / 2]; + ReadChunked(shake, hash); + Assert.Equal(kat.Output, Convert.ToHexString(hash), ignoreCase: true); + + TShakeTrait.Reset(shake); + hash.Clear(); + + TShakeTrait.AppendData(shake, message); + ReadChunked(shake, hash); + Assert.Equal(kat.Output, Convert.ToHexString(hash), ignoreCase: true); + } + } + } + + [ConditionalFact(nameof(IsReadSupported))] + public void KnownAnswerTests_Allocated_Read_GetHashAndReset() + { + foreach ((string Msg, string Output) kat in Fips202Kats) + { + byte[] message = Convert.FromHexString(kat.Msg); + + using (TShake shake = new TShake()) + { + TShakeTrait.AppendData(shake, message); + Span hash = new byte[kat.Output.Length / 2]; + ReadChunked(shake, hash); + Assert.Equal(kat.Output, Convert.ToHexString(hash), ignoreCase: true); + + TShakeTrait.Reset(shake); + hash.Clear(); + + TShakeTrait.AppendData(shake, message); + TShakeTrait.GetHashAndReset(shake, hash); + Assert.Equal(kat.Output, Convert.ToHexString(hash), ignoreCase: true); + } + } + } + + [ConditionalFact(nameof(IsSupported))] + public void KnownAnswerTests_Clone_Independent_Unobserved() + { + foreach ((string Msg, string Output) kat in Fips202Kats) + { + byte[] message = Convert.FromHexString(kat.Msg); + byte[] hash = new byte[kat.Output.Length / 2]; + + using (TShake shake = new TShake()) + using (TShake clone = TShakeTrait.Clone(shake)) + { + TShakeTrait.AppendData(shake, "badbadbad"u8); + + TShakeTrait.AppendData(clone, message); + TShakeTrait.GetCurrentHash(clone, hash); + Assert.Equal(kat.Output, Convert.ToHexString(hash), ignoreCase: true); + } + } + } + + [ConditionalFact(nameof(IsSupported))] + public void KnownAnswerTests_Clone_Independent_Disposed() + { + foreach ((string Msg, string Output) kat in Fips202Kats) + { + byte[] message = Convert.FromHexString(kat.Msg); + byte[] hash = new byte[kat.Output.Length / 2]; + + TShake shake = new TShake(); + using (TShake clone = TShakeTrait.Clone(shake)) + { + shake.Dispose(); + + TShakeTrait.AppendData(clone, message); + TShakeTrait.GetCurrentHash(clone, hash); + Assert.Equal(kat.Output, Convert.ToHexString(hash), ignoreCase: true); + } + } + } + + [ConditionalFact(nameof(IsSupported))] + public void KnownAnswerTests_Reset() + { + foreach ((string Msg, string Output) kat in Fips202Kats) + { + byte[] message = Convert.FromHexString(kat.Msg); + byte[] hash = new byte[kat.Output.Length / 2]; + + using (TShake shake = new TShake()) + { + TShakeTrait.AppendData(shake, "badbadbad"u8); + TShakeTrait.Reset(shake); + TShakeTrait.AppendData(shake, message); + TShakeTrait.GetCurrentHash(shake, hash); + Assert.Equal(kat.Output, Convert.ToHexString(hash), ignoreCase: true); + } + } + } + [ConditionalFact(nameof(IsSupported))] public void KnownAnswerTests_OneShot_HashData_ByteArray() { @@ -515,6 +635,10 @@ public void ArgValidation_Allocated_UseAfterDispose() Assert.Throws(() => TShakeTrait.GetHashAndReset(shake, buffer.AsSpan())); Assert.Throws(() => TShakeTrait.GetCurrentHash(shake, outputLength: 1)); Assert.Throws(() => TShakeTrait.GetCurrentHash(shake, buffer.AsSpan())); + Assert.Throws(() => TShakeTrait.Clone(shake)); + Assert.Throws(() => TShakeTrait.Reset(shake)); + Assert.Throws(() => TShakeTrait.Read(shake, buffer.AsSpan())); + Assert.Throws(() => TShakeTrait.Read(shake, outputLength: 1)); } [ConditionalFact(nameof(IsNotSupported))] @@ -539,6 +663,103 @@ public void IsSupported_AgreesWithPlatform() Assert.Equal(TShakeTrait.IsSupported, PlatformDetection.SupportsSha3); } + [ConditionalFact(nameof(IsSupported))] + public void Clone_DifferentInstance() + { + using (TShake shake = new TShake()) + using (TShake clone = TShakeTrait.Clone(shake)) + { + Assert.NotSame(shake, clone); + } + } + + [ConditionalFact(nameof(IsReadSupported))] + public void Read_MixedAppendAfterRead() + { + using (TShake shake = new TShake()) + { + TShakeTrait.Read(shake, Span.Empty); + + Assert.Throws(() => TShakeTrait.AppendData(shake, ReadOnlySpan.Empty)); + Assert.Throws(() => TShakeTrait.AppendData(shake, Array.Empty())); + + TShakeTrait.Reset(shake); + + // Assert.NoThrow + TShakeTrait.AppendData(shake, ReadOnlySpan.Empty); + TShakeTrait.AppendData(shake, Array.Empty()); + } + } + + [ConditionalFact(nameof(IsReadSupported))] + public void Read_MixedCloneAfterRead() + { + using (TShake shake = new TShake()) + { + TShakeTrait.Read(shake, Span.Empty); + Assert.Throws(() => TShakeTrait.Clone(shake)); + + TShakeTrait.Reset(shake); + + using (TShake clone = TShakeTrait.Clone(shake)) + { + Assert.NotNull(clone); + } + } + } + + [ConditionalFact(nameof(IsReadSupported))] + public void Read_MixedGetHashAndReset() + { + using (TShake shake = new TShake()) + { + TShakeTrait.Read(shake, Span.Empty); + Assert.Throws(() => TShakeTrait.GetHashAndReset(shake, Span.Empty)); + Assert.Throws(() => TShakeTrait.GetHashAndReset(shake, outputLength: 0)); + + TShakeTrait.Reset(shake); + + // Assert.NoThrow + TShakeTrait.GetHashAndReset(shake, Span.Empty); + TShakeTrait.GetHashAndReset(shake, outputLength: 0); + } + } + + [ConditionalFact(nameof(IsReadSupported))] + public void Read_MixedGetCurrentHash() + { + using (TShake shake = new TShake()) + { + TShakeTrait.Read(shake, Span.Empty); + + // Cannot GetCurrentHash while reading. + Assert.Throws(() => TShakeTrait.GetCurrentHash(shake, Span.Empty)); + Assert.Throws(() => TShakeTrait.GetCurrentHash(shake, outputLength: 0)); + + TShakeTrait.Reset(shake); + + // Assert.NoThrow + TShakeTrait.GetCurrentHash(shake, Span.Empty); + TShakeTrait.GetCurrentHash(shake, outputLength: 0); + } + } + + [ConditionalFact(nameof(IsSupported))] + public void Read_NotSupported() + { + // This is testing when a TShake can be created, but the platform does not have Read. + if (IsReadSupported) + { + return; + } + + using (TShake shake = new TShake()) + { + Assert.Throws(() => TShakeTrait.Read(shake, Span.Empty)); + Assert.Throws(() => TShakeTrait.Read(shake, outputLength: 0)); + } + } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public void GetHashAndReset_ConcurrentUseDoesNotCrashProcess() { @@ -580,5 +801,18 @@ static void ThreadWork(object obj) } } } + + private static void ReadChunked(TShake shake, Span destination) + { + int read = 0; + int outputLength = destination.Length; + + while (read < outputLength) + { + int size = Math.Min(Math.Max(outputLength / 4, 1), outputLength - read); + TShakeTrait.Read(shake, destination.Slice(read, size)); + read += size; + } + } } } diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CertificateRequestUsageTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CertificateRequestUsageTests.cs index e65a0445b09b28..8c434619d72eb0 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CertificateRequestUsageTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/CertificateCreation/CertificateRequestUsageTests.cs @@ -551,7 +551,7 @@ public static void InvalidSignatureAlgorithmEncoding(string caseName, string sig Exception exception = Assert.Throws( () => request.Create(request.SubjectName, generator, now, now.AddDays(1), new byte[1])); -#if NETCOREAPP +#if NET if (CultureInfo.CurrentCulture.Name == "en-US") { Assert.Contains("ASN1", exception.Message, StringComparison.OrdinalIgnoreCase); diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.cs index 0c8e374018564d..fb286e393c98d6 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/X509StoreTests.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NETCOREAPP +#if NET #define HAVE_STORE_ISOPEN #endif diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.Forwards.cs b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.Forwards.cs index 4d9a824761f533..c4f0228c054129 100644 --- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.Forwards.cs +++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.Forwards.cs @@ -15,7 +15,7 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Permissions.SecurityPermissionFlag))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Policy.Evidence))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Policy.EvidenceBase))] -#if NETCOREAPP +#if NET [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.IStackWalk))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.PermissionSet))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Security.Permissions.PermissionState))] diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs index 512d130416ea6a..5d2fc5fabc8b31 100644 --- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs +++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs @@ -17,7 +17,7 @@ void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Ser } namespace System.Configuration { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class ConfigurationPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -31,7 +31,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.All, AllowMultiple=true, Inherited=false)] @@ -43,7 +43,7 @@ public ConfigurationPermissionAttribute(System.Security.Permissions.SecurityActi } namespace System.Data.Common { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public abstract partial class DBDataPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -65,7 +65,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -84,7 +84,7 @@ protected DBDataPermissionAttribute(System.Security.Permissions.SecurityAction a } namespace System.Data.Odbc { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class OdbcPermission : System.Data.Common.DBDataPermission @@ -95,7 +95,7 @@ public OdbcPermission(System.Security.Permissions.PermissionState state, bool al public override void Add(string connectionString, string restrictions, System.Data.KeyRestrictionBehavior behavior) { } public override System.Security.IPermission Copy() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -107,7 +107,7 @@ public OdbcPermissionAttribute(System.Security.Permissions.SecurityAction action } namespace System.Data.OleDb { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class OleDbPermission : System.Data.Common.DBDataPermission @@ -120,7 +120,7 @@ public OleDbPermission(System.Security.Permissions.PermissionState state, bool a public string Provider { get { throw null; } set { } } public override System.Security.IPermission Copy() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -135,7 +135,7 @@ public OleDbPermissionAttribute(System.Security.Permissions.SecurityAction actio } namespace System.Data.OracleClient { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class OraclePermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -151,7 +151,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -171,7 +171,7 @@ public OraclePermissionAttribute(System.Security.Permissions.SecurityAction acti } namespace System.Data.SqlClient { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class SqlClientPermission : System.Data.Common.DBDataPermission @@ -182,7 +182,7 @@ public SqlClientPermission(System.Security.Permissions.PermissionState state, bo public override void Add(string connectionString, string restrictions, System.Data.KeyRestrictionBehavior behavior) { } public override System.Security.IPermission Copy() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -194,7 +194,7 @@ public SqlClientPermissionAttribute(System.Security.Permissions.SecurityAction a } namespace System.Diagnostics { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class EventLogPermission : System.Security.Permissions.ResourcePermissionBase @@ -215,7 +215,7 @@ public enum EventLogPermissionAccess Write = 16, Administer = 48, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Event | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -249,7 +249,7 @@ protected override void OnRemove(int index, object value) { } protected override void OnSet(int index, object oldValue, object newValue) { } public void Remove(System.Diagnostics.EventLogPermissionEntry value) { } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class PerformanceCounterPermission : System.Security.Permissions.ResourcePermissionBase @@ -270,7 +270,7 @@ public enum PerformanceCounterPermissionAccess Instrument = 3, Administer = 7, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Event | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -360,7 +360,7 @@ public void Remove(System.DirectoryServices.DirectoryServicesPermissionEntry val } namespace System.Drawing.Printing { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class PrintingPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -376,7 +376,7 @@ public override void FromXml(System.Security.SecurityElement element) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.All, AllowMultiple=true)] @@ -396,7 +396,7 @@ public enum PrintingPermissionLevel } namespace System.Net { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class DnsPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -410,7 +410,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -434,7 +434,7 @@ public enum NetworkAccess Connect = 64, Accept = 128, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class SocketPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -453,7 +453,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -474,7 +474,7 @@ public enum TransportType Tcp = 2, All = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class WebPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -495,7 +495,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -517,7 +517,7 @@ public enum SmtpAccess Connect = 1, ConnectToUnrestrictedPort = 2, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class SmtpPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -535,7 +535,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -555,7 +555,7 @@ public enum NetworkInformationAccess Read = 1, Ping = 4, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class NetworkInformationPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -572,7 +572,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -585,7 +585,7 @@ public NetworkInformationPermissionAttribute(System.Security.Permissions.Securit } namespace System.Net.PeerToPeer { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class PnrpPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -599,7 +599,7 @@ public override void FromXml(System.Security.SecurityElement e) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -618,7 +618,7 @@ public enum PnrpScope } namespace System.Net.PeerToPeer.Collaboration { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class PeerCollaborationPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -632,7 +632,7 @@ public override void FromXml(System.Security.SecurityElement e) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -644,7 +644,7 @@ public PeerCollaborationPermissionAttribute(System.Security.Permissions.Security } namespace System.Security { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public abstract partial class CodeAccessPermission : System.Security.IPermission, System.Security.ISecurityEncodable, System.Security.IStackWalk @@ -670,7 +670,7 @@ public static void RevertPermitOnly() { } public abstract System.Security.SecurityElement ToXml(); public virtual System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public partial class HostProtectionException : System.SystemException @@ -723,7 +723,7 @@ public partial interface ISecurityPolicyEncodable void FromXml(System.Security.SecurityElement e, System.Security.Policy.PolicyLevel level); System.Security.SecurityElement ToXml(System.Security.Policy.PolicyLevel level); } -#if !NETCOREAPP +#if !NET public partial interface IStackWalk { void Assert(); @@ -732,7 +732,7 @@ public partial interface IStackWalk void PermitOnly(); } #endif -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class NamedPermissionSet : System.Security.PermissionSet @@ -750,7 +750,7 @@ public override void FromXml(System.Security.SecurityElement et) { } public override int GetHashCode() { throw null; } public override System.Security.SecurityElement ToXml() { throw null; } } -#if !NETCOREAPP +#if !NET public partial class PermissionSet : System.Collections.ICollection, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Security.ISecurityEncodable, System.Security.IStackWalk { public PermissionSet(System.Security.Permissions.PermissionState state) { } @@ -800,7 +800,7 @@ public enum PolicyLevelType Enterprise = 2, AppDomain = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class SecurityContext : System.IDisposable @@ -821,7 +821,7 @@ public enum SecurityContextSource CurrentAppDomain = 0, CurrentAssembly = 1, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public static partial class SecurityManager @@ -882,7 +882,7 @@ public XmlSyntaxException(string message, System.Exception inner) { } } namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class DataProtectionPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -898,7 +898,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -912,7 +912,7 @@ public DataProtectionPermissionAttribute(System.Security.Permissions.SecurityAct public bool UnprotectMemory { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -925,7 +925,7 @@ public enum DataProtectionPermissionFlags UnprotectMemory = 8, AllFlags = 15, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class EnvironmentPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -943,7 +943,7 @@ public void SetPathList(System.Security.Permissions.EnvironmentPermissionAccess public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -954,7 +954,7 @@ public enum EnvironmentPermissionAccess Write = 2, AllAccess = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -966,7 +966,7 @@ public EnvironmentPermissionAttribute(System.Security.Permissions.SecurityAction public string Write { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class FileDialogPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -982,7 +982,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -993,7 +993,7 @@ public enum FileDialogPermissionAccess Save = 2, OpenSave = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1004,7 +1004,7 @@ public FileDialogPermissionAttribute(System.Security.Permissions.SecurityAction public bool Save { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class FileIOPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1031,7 +1031,7 @@ public void SetPathList(System.Security.Permissions.FileIOPermissionAccess acces public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -1044,7 +1044,7 @@ public enum FileIOPermissionAccess PathDiscovery = 8, AllAccess = 15, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1064,7 +1064,7 @@ public FileIOPermissionAttribute(System.Security.Permissions.SecurityAction acti public string Write { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class GacIdentityPermission : System.Security.CodeAccessPermission @@ -1078,7 +1078,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1087,7 +1087,7 @@ public sealed partial class GacIdentityPermissionAttribute : System.Security.Per public GacIdentityPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Delegate | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1107,7 +1107,7 @@ public HostProtectionAttribute(System.Security.Permissions.SecurityAction action public bool UI { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -1125,7 +1125,7 @@ public enum HostProtectionResource MayLeakOnAbort = 256, All = 511, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum IsolatedStorageContainment @@ -1143,7 +1143,7 @@ public enum IsolatedStorageContainment AdministerIsolatedStorageByUser = 112, UnrestrictedIsolatedStorage = 240, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class IsolatedStorageFilePermission : System.Security.Permissions.IsolatedStoragePermission @@ -1155,7 +1155,7 @@ public IsolatedStorageFilePermission(System.Security.Permissions.PermissionState public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1164,7 +1164,7 @@ public sealed partial class IsolatedStorageFilePermissionAttribute : System.Secu public IsolatedStorageFilePermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public abstract partial class IsolatedStoragePermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1176,7 +1176,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public bool IsUnrestricted() { throw null; } public override System.Security.SecurityElement ToXml() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public abstract partial class IsolatedStoragePermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute @@ -1185,14 +1185,14 @@ protected IsolatedStoragePermissionAttribute(System.Security.Permissions.Securit public System.Security.Permissions.IsolatedStorageContainment UsageAllowed { get { throw null; } set { } } public long UserQuota { get { throw null; } set { } } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public partial interface IUnrestrictedPermission { bool IsUnrestricted(); } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class KeyContainerPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1210,7 +1210,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class KeyContainerPermissionAccessEntry @@ -1227,7 +1227,7 @@ public KeyContainerPermissionAccessEntry(string keyStore, string providerName, i public override bool Equals(object o) { throw null; } public override int GetHashCode() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class KeyContainerPermissionAccessEntryCollection : System.Collections.ICollection, System.Collections.IEnumerable @@ -1246,7 +1246,7 @@ public void CopyTo(System.Security.Permissions.KeyContainerPermissionAccessEntry public void Remove(System.Security.Permissions.KeyContainerPermissionAccessEntry accessEntry) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class KeyContainerPermissionAccessEntryEnumerator : System.Collections.IEnumerator @@ -1257,7 +1257,7 @@ public KeyContainerPermissionAccessEntryEnumerator() { } public bool MoveNext() { throw null; } public void Reset() { } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1272,7 +1272,7 @@ public KeyContainerPermissionAttribute(System.Security.Permissions.SecurityActio public int ProviderType { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum KeyContainerPermissionFlags @@ -1289,7 +1289,7 @@ public enum KeyContainerPermissionFlags ChangeAcl = 8192, AllFlags = 13111, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class MediaPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1311,7 +1311,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1323,7 +1323,7 @@ public MediaPermissionAttribute(System.Security.Permissions.SecurityAction actio public System.Security.Permissions.MediaPermissionVideo Video { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum MediaPermissionAudio @@ -1333,7 +1333,7 @@ public enum MediaPermissionAudio SafeAudio = 2, AllAudio = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum MediaPermissionImage @@ -1343,7 +1343,7 @@ public enum MediaPermissionImage SafeImage = 2, AllImage = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum MediaPermissionVideo @@ -1353,7 +1353,7 @@ public enum MediaPermissionVideo SafeVideo = 2, AllVideo = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1368,14 +1368,14 @@ public PermissionSetAttribute(System.Security.Permissions.SecurityAction action) public override System.Security.IPermission CreatePermission() { throw null; } public System.Security.PermissionSet CreatePermissionSet() { throw null; } } -#if !NETCOREAPP +#if !NET public enum PermissionState { None = 0, Unrestricted = 1, } #endif -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class PrincipalPermission : System.Security.IPermission, System.Security.ISecurityEncodable, System.Security.Permissions.IUnrestrictedPermission @@ -1395,13 +1395,13 @@ public void FromXml(System.Security.SecurityElement elem) { } public System.Security.SecurityElement ToXml() { throw null; } public System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)] public sealed partial class PrincipalPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("PrincipalPermissionAttribute is not honored by the runtime and must not be used.", true, DiagnosticId = "SYSLIB0002", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public PrincipalPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } @@ -1410,7 +1410,7 @@ public PrincipalPermissionAttribute(System.Security.Permissions.SecurityAction a public string Role { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class PublisherIdentityPermission : System.Security.CodeAccessPermission @@ -1425,7 +1425,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1437,7 +1437,7 @@ public PublisherIdentityPermissionAttribute(System.Security.Permissions.Security public string X509Certificate { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class ReflectionPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1453,7 +1453,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1469,7 +1469,7 @@ public ReflectionPermissionAttribute(System.Security.Permissions.SecurityAction public bool TypeInformation { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -1485,7 +1485,7 @@ public enum ReflectionPermissionFlag AllFlags = 7, RestrictedMemberAccess = 8, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class RegistryPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1505,7 +1505,7 @@ public void SetPathList(System.Security.Permissions.RegistryPermissionAccess acc public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -1517,7 +1517,7 @@ public enum RegistryPermissionAccess Create = 4, AllAccess = 7, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1534,7 +1534,7 @@ public RegistryPermissionAttribute(System.Security.Permissions.SecurityAction ac public string Write { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public abstract partial class ResourcePermissionBase : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1557,7 +1557,7 @@ protected void RemovePermissionAccess(System.Security.Permissions.ResourcePermis public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public partial class ResourcePermissionBaseEntry @@ -1567,7 +1567,7 @@ public ResourcePermissionBaseEntry(int permissionAccess, string[] permissionAcce public int PermissionAccess { get { throw null; } } public string[] PermissionAccessPath { get { throw null; } } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class SecurityPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1583,7 +1583,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class SiteIdentityPermission : System.Security.CodeAccessPermission @@ -1598,7 +1598,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1608,7 +1608,7 @@ public SiteIdentityPermissionAttribute(System.Security.Permissions.SecurityActio public string Site { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class StorePermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1624,7 +1624,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1641,7 +1641,7 @@ public StorePermissionAttribute(System.Security.Permissions.SecurityAction actio public bool RemoveFromStore { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -1657,7 +1657,7 @@ public enum StorePermissionFlags EnumerateCertificates = 128, AllFlags = 247, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class StrongNameIdentityPermission : System.Security.CodeAccessPermission @@ -1674,7 +1674,7 @@ public override void FromXml(System.Security.SecurityElement e) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1686,7 +1686,7 @@ public StrongNameIdentityPermissionAttribute(System.Security.Permissions.Securit public string Version { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class StrongNamePublicKeyBlob @@ -1696,7 +1696,7 @@ public StrongNamePublicKeyBlob(byte[] publicKey) { } public override int GetHashCode() { throw null; } public override string ToString() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class TypeDescriptorPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1712,7 +1712,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1723,7 +1723,7 @@ public TypeDescriptorPermissionAttribute(System.Security.Permissions.SecurityAct public bool RestrictedRegistrationAccess { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.FlagsAttribute] @@ -1732,7 +1732,7 @@ public enum TypeDescriptorPermissionFlags NoFlags = 0, RestrictedRegistrationAccess = 1, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class UIPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1751,7 +1751,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1762,7 +1762,7 @@ public UIPermissionAttribute(System.Security.Permissions.SecurityAction action) public System.Security.Permissions.UIPermissionWindow Window { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum UIPermissionClipboard @@ -1771,7 +1771,7 @@ public enum UIPermissionClipboard OwnClipboard = 1, AllClipboard = 2, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum UIPermissionWindow @@ -1781,7 +1781,7 @@ public enum UIPermissionWindow SafeTopLevelWindows = 2, AllWindows = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class UrlIdentityPermission : System.Security.CodeAccessPermission @@ -1796,7 +1796,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1806,7 +1806,7 @@ public UrlIdentityPermissionAttribute(System.Security.Permissions.SecurityAction public string Url { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class WebBrowserPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -1823,7 +1823,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1833,7 +1833,7 @@ public WebBrowserPermissionAttribute(System.Security.Permissions.SecurityAction public System.Security.Permissions.WebBrowserPermissionLevel Level { get { throw null; } set { } } public override System.Security.IPermission CreatePermission() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public enum WebBrowserPermissionLevel @@ -1842,7 +1842,7 @@ public enum WebBrowserPermissionLevel Safe = 1, Unrestricted = 2, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class ZoneIdentityPermission : System.Security.CodeAccessPermission @@ -1857,7 +1857,7 @@ public override void FromXml(System.Security.SecurityElement esd) { } public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] @@ -1909,14 +1909,14 @@ public sealed partial class ApplicationTrust : System.Security.Policy.EvidenceBa { public ApplicationTrust() { } public ApplicationTrust(System.ApplicationIdentity identity) { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public ApplicationTrust(System.Security.PermissionSet defaultGrantSet, System.Collections.Generic.IEnumerable fullTrustAssemblies) { } public System.ApplicationIdentity ApplicationIdentity { get { throw null; } set { } } public System.Security.Policy.PolicyStatement DefaultGrantSet { get { throw null; } set { } } public object ExtraInfo { get { throw null; } set { } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public System.Collections.Generic.IList FullTrustAssemblies { get { throw null; } } @@ -2000,7 +2000,7 @@ public void RemoveChild(System.Security.Policy.CodeGroup group) { } public System.Security.SecurityElement ToXml() { throw null; } public System.Security.SecurityElement ToXml(System.Security.Policy.PolicyLevel level) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class FileCodeGroup : System.Security.Policy.CodeGroup @@ -2026,7 +2026,7 @@ public sealed partial class FirstMatchCodeGroup : System.Security.Policy.CodeGro public override System.Security.Policy.PolicyStatement Resolve(System.Security.Policy.Evidence evidence) { throw null; } public override System.Security.Policy.CodeGroup ResolveMatchingCodeGroups(System.Security.Policy.Evidence evidence) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class GacInstalled : System.Security.Policy.EvidenceBase, System.Security.Policy.IIdentityPermissionFactory @@ -2085,7 +2085,7 @@ void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Ser public System.Security.SecurityElement ToXml() { throw null; } public System.Security.SecurityElement ToXml(System.Security.Policy.PolicyLevel level) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public partial interface IIdentityPermissionFactory @@ -2153,18 +2153,18 @@ internal PolicyLevel() { } public void AddFullTrustAssembly(System.Security.Policy.StrongName sn) { } [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")] public void AddFullTrustAssembly(System.Security.Policy.StrongNameMembershipCondition snMC) { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public void AddNamedPermissionSet(System.Security.NamedPermissionSet permSet) { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public System.Security.NamedPermissionSet ChangeNamedPermissionSet(string name, System.Security.PermissionSet pSet) { throw null; } [System.ObsoleteAttribute("AppDomain policy levels are obsolete. See https://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] public static System.Security.Policy.PolicyLevel CreateAppDomainLevel() { throw null; } public void FromXml(System.Security.SecurityElement e) { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public System.Security.NamedPermissionSet GetNamedPermissionSet(string name) { throw null; } @@ -2173,11 +2173,11 @@ public void Recover() { } public void RemoveFullTrustAssembly(System.Security.Policy.StrongName sn) { } [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")] public void RemoveFullTrustAssembly(System.Security.Policy.StrongNameMembershipCondition snMC) { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public System.Security.NamedPermissionSet RemoveNamedPermissionSet(System.Security.NamedPermissionSet permSet) { throw null; } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public System.Security.NamedPermissionSet RemoveNamedPermissionSet(string name) { throw null; } @@ -2188,17 +2188,17 @@ public void Reset() { } } public sealed partial class PolicyStatement : System.Security.ISecurityEncodable, System.Security.ISecurityPolicyEncodable { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public PolicyStatement(System.Security.PermissionSet permSet) { } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public PolicyStatement(System.Security.PermissionSet permSet, System.Security.Policy.PolicyStatementAttribute attributes) { } public System.Security.Policy.PolicyStatementAttribute Attributes { get { throw null; } set { } } public string AttributeString { get { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public System.Security.PermissionSet PermissionSet { get { throw null; } set { } } @@ -2218,7 +2218,7 @@ public enum PolicyStatementAttribute LevelFinal = 2, All = 3, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class Publisher : System.Security.Policy.EvidenceBase, System.Security.Policy.IIdentityPermissionFactory @@ -2245,7 +2245,7 @@ public void FromXml(System.Security.SecurityElement e, System.Security.Policy.Po public System.Security.SecurityElement ToXml() { throw null; } public System.Security.SecurityElement ToXml(System.Security.Policy.PolicyLevel level) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class Site : System.Security.Policy.EvidenceBase, System.Security.Policy.IIdentityPermissionFactory @@ -2273,7 +2273,7 @@ public void FromXml(System.Security.SecurityElement e, System.Security.Policy.Po public System.Security.SecurityElement ToXml() { throw null; } public System.Security.SecurityElement ToXml(System.Security.Policy.PolicyLevel level) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class StrongName : System.Security.Policy.EvidenceBase, System.Security.Policy.IIdentityPermissionFactory @@ -2288,7 +2288,7 @@ public StrongName(System.Security.Permissions.StrongNamePublicKeyBlob blob, stri public override int GetHashCode() { throw null; } public override string ToString() { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class StrongNameMembershipCondition : System.Security.ISecurityEncodable, System.Security.ISecurityPolicyEncodable, System.Security.Policy.IMembershipCondition @@ -2333,7 +2333,7 @@ public sealed partial class UnionCodeGroup : System.Security.Policy.CodeGroup public override System.Security.Policy.PolicyStatement Resolve(System.Security.Policy.Evidence evidence) { throw null; } public override System.Security.Policy.CodeGroup ResolveMatchingCodeGroups(System.Security.Policy.Evidence evidence) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class Url : System.Security.Policy.EvidenceBase, System.Security.Policy.IIdentityPermissionFactory @@ -2360,7 +2360,7 @@ public void FromXml(System.Security.SecurityElement e, System.Security.Policy.Po public System.Security.SecurityElement ToXml() { throw null; } public System.Security.SecurityElement ToXml(System.Security.Policy.PolicyLevel level) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class Zone : System.Security.Policy.EvidenceBase, System.Security.Policy.IIdentityPermissionFactory @@ -2391,7 +2391,7 @@ public void FromXml(System.Security.SecurityElement e, System.Security.Policy.Po } namespace System.ServiceProcess { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class ServiceControllerPermission : System.Security.Permissions.ResourcePermissionBase @@ -2409,7 +2409,7 @@ public enum ServiceControllerPermissionAccess Browse = 2, Control = 6, } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Event | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple = true, Inherited = false)] @@ -2449,7 +2449,7 @@ public void Remove(System.ServiceProcess.ServiceControllerPermissionEntry value) } namespace System.Transactions { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class DistributedTransactionPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -2463,7 +2463,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.All, AllowMultiple=true)] @@ -2476,7 +2476,7 @@ public DistributedTransactionPermissionAttribute(System.Security.Permissions.Sec } namespace System.Web { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class AspNetHostingPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission @@ -2492,7 +2492,7 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif [System.AttributeUsageAttribute(System.AttributeTargets.All, AllowMultiple=true, Inherited=false)] diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs index bd7e4dd59a6c7b..f3e0de569038cb 100644 --- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs +++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.netcoreapp.cs @@ -6,7 +6,7 @@ namespace System.Xaml.Permissions { -#if NETCOREAPP +#if NET [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif public sealed partial class XamlLoadPermission : System.Security.CodeAccessPermission, System.Security.Permissions.IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermission.cs b/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermission.cs index 3adc471ddc8949..47967148e4b60c 100644 --- a/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermission.cs @@ -6,7 +6,7 @@ namespace System.Configuration { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class ConfigurationPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs index 8366e422d9172f..43a98812096e14 100644 --- a/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Configuration { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermission.cs b/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermission.cs index 93b727f99073f2..3982f48df334ff 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermission.cs @@ -6,7 +6,7 @@ namespace System.Data.Common { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public abstract class DBDataPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs index 9968cb6d565abb..ac1e409a951df6 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs @@ -5,7 +5,7 @@ namespace System.Data.Common { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, diff --git a/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermission.cs b/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermission.cs index 6504d49d88814b..2dca7ee412de82 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermission.cs @@ -7,7 +7,7 @@ namespace System.Data.Odbc { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class OdbcPermission : DBDataPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermissionAttribute.cs index c6286aa49ba751..e0bd5ec1abf82d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/Odbc/OdbcPermissionAttribute.cs @@ -7,7 +7,7 @@ namespace System.Data.Odbc { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | diff --git a/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermission.cs b/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermission.cs index d71f863adcf374..7b162ca30c2696 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermission.cs @@ -7,7 +7,7 @@ namespace System.Data.OleDb { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class OleDbPermission : DBDataPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermissionAttribute.cs index c4e0aca2d7a287..c5e90d99441762 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/OleDb/OleDbPermissionAttribute.cs @@ -7,7 +7,7 @@ namespace System.Data.OleDb { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | diff --git a/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermission.cs b/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermission.cs index a0389c9a0be15f..3517fd1cb4ee9d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermission.cs @@ -6,7 +6,7 @@ namespace System.Data.OracleClient { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class OraclePermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs index 639d38aa48e91e..bc7175def787ec 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs @@ -5,7 +5,7 @@ namespace System.Data.OracleClient { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | diff --git a/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermission.cs b/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermission.cs index e3cc4ced62e7a2..1cd20d3ead17b6 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermission.cs @@ -6,7 +6,7 @@ namespace System.Data.SqlClient { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class SqlClientPermission : DBDataPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermissionAttribute.cs index 0979d37e899ff9..fffc013004f700 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/SqlClient/SqlClientPermissionAttribute.cs @@ -7,7 +7,7 @@ namespace System.Data.SqlClient { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, diff --git a/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermission.cs b/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermission.cs index e1e64c3c12be69..206e729cbb09c8 100644 --- a/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermission.cs @@ -5,7 +5,7 @@ namespace System.Diagnostics { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class EventLogPermission : ResourcePermissionBase diff --git a/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs index e296e032d6ba79..a0406ccde6a240 100644 --- a/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Diagnostics { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct diff --git a/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermission.cs b/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermission.cs index 49cee1607c3381..d3b0c2b6e15593 100644 --- a/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermission.cs @@ -5,7 +5,7 @@ namespace System.Diagnostics { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class PerformanceCounterPermission : ResourcePermissionBase diff --git a/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs index 804e21d7d809b2..0f7322763e104b 100644 --- a/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs @@ -5,7 +5,7 @@ using System.Security.Permissions; namespace System.Diagnostics { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Event, diff --git a/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermission.cs b/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermission.cs index e429ac0b32599a..9981ec0a12d57d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermission.cs @@ -6,7 +6,7 @@ namespace System.Drawing.Printing { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class PrintingPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs index 654f04f6ede1f0..71c3d6e46d6581 100644 --- a/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs @@ -5,7 +5,7 @@ namespace System.Drawing.Printing { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true)] diff --git a/src/libraries/System.Security.Permissions/src/System/Net/DnsPermission.cs b/src/libraries/System.Security.Permissions/src/System/Net/DnsPermission.cs index 86817bf064ea29..4bc042aa3c42aa 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/DnsPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/DnsPermission.cs @@ -6,7 +6,7 @@ namespace System.Net { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class DnsPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs index ab40a425fcaa8e..61f45a9f646d81 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Net { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | diff --git a/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermission.cs b/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermission.cs index d9c5c6edba6a74..4284d30ea6b87d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermission.cs @@ -6,7 +6,7 @@ namespace System.Net.Mail { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class SmtpPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs index 8d8a3379277e46..3a91cbdffafb5d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Net.Mail { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | diff --git a/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermission.cs b/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermission.cs index 40a7e39426acbe..1acf38c0fd91ab 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermission.cs @@ -6,7 +6,7 @@ namespace System.Net.NetworkInformation { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class NetworkInformationPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs index d25b0cf35e4e84..befe4af33830df 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Net.NetworkInformation { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermission.cs b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermission.cs index 25627f89a6bd05..c09cceea2a47a3 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermission.cs @@ -6,7 +6,7 @@ namespace System.Net.PeerToPeer.Collaboration { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class PeerCollaborationPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs index 8e171c3cd5c7f8..5fb68c79dcf682 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Net.PeerToPeer.Collaboration { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | diff --git a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermission.cs b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermission.cs index c7b3ccbdf7789a..bac836ed20b7a9 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermission.cs @@ -6,7 +6,7 @@ namespace System.Net.PeerToPeer { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class PnrpPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs index b9df6e845e49ed..88b06a69b287f7 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Net.PeerToPeer { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | diff --git a/src/libraries/System.Security.Permissions/src/System/Net/SocketPermission.cs b/src/libraries/System.Security.Permissions/src/System/Net/SocketPermission.cs index 88e835058e7872..1e51df16e9606b 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/SocketPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/SocketPermission.cs @@ -6,7 +6,7 @@ namespace System.Net { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class SocketPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs index 88147043b9218a..cf4611a39e6e66 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Net { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | diff --git a/src/libraries/System.Security.Permissions/src/System/Net/WebPermission.cs b/src/libraries/System.Security.Permissions/src/System/Net/WebPermission.cs index e61b27b590f2d8..e7fe49c24dd72c 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/WebPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/WebPermission.cs @@ -8,7 +8,7 @@ namespace System.Net { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class WebPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs index 7113110a896b36..82f30ea9df7222 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Net { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | diff --git a/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs index 4ecc14aca2bff1..9ca3f51ce606bf 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs @@ -3,7 +3,7 @@ namespace System.Security { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public abstract partial class CodeAccessPermission : IPermission, ISecurityEncodable, IStackWalk diff --git a/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs b/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs index b93a00a2a8e59b..455e045198c419 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/HostProtectionException.cs @@ -8,7 +8,7 @@ namespace System.Security { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Serializable] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs b/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs index 26bfa5dae85d9b..b437033366e084 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs @@ -5,7 +5,7 @@ namespace System.Security { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class NamedPermissionSet : PermissionSet diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermission.cs index 2af3cafe200eb0..f7c18edfea5e03 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class DataProtectionPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionAttribute.cs index 5c6d99af3565a7..b3cf765ca13e34 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionFlags.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionFlags.cs index 44a442408e8f8a..80c1dd19d18012 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionFlags.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/DataProtectionPermissionFlags.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermission.cs index 5c26c149475416..76f0c82c8029c4 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class EnvironmentPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAccess.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAccess.cs index b5dee502e691a8..0a7f56c80ffff0 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAccess.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAccess.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAttribute.cs index d68a1e4842fbb4..b69d26db2be97b 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/EnvironmentPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermission.cs index 6774ece3a08074..952148edcb99c4 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class FileDialogPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAccess.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAccess.cs index 80dfc8f43e1606..8d2eb8a87bd02c 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAccess.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAccess.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAttribute.cs index a6dc55eb78b656..9f4c8b6fc8ebaa 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileDialogPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermission.cs index 7df64c4145df16..99e507ecd7c579 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class FileIOPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAccess.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAccess.cs index e3fb61c97b2391..029e63b1a0938d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAccess.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAccess.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAttribute.cs index 1780e55dde857c..702cc1fae17931 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/FileIOPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermission.cs index a0d0abc573fdb9..39604e13f555e1 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class GacIdentityPermission : CodeAccessPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermissionAttribute.cs index bdeee8607fd10d..928f72a5b51fa4 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/GacIdentityPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionAttribute.cs index 56f6d8a24bbe1c..ecf10307271e5b 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(4205), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionResource.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionResource.cs index d1db88246d0037..81e284a6564778 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionResource.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/HostProtectionResource.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IUnrestrictedPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IUnrestrictedPermission.cs index a4c95a4a13fd23..04e5fa166a59a1 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IUnrestrictedPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IUnrestrictedPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public partial interface IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageContainment.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageContainment.cs index 1563eba6e790ff..4292c351f4f575 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageContainment.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageContainment.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum IsolatedStorageContainment diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermission.cs index fafbdca772d713..4e3535109fbc12 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class IsolatedStorageFilePermission : IsolatedStoragePermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermissionAttribute.cs index e7d95b86409154..8789e27a496d04 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStorageFilePermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermission.cs index d0d08571e6a8e5..c33e6fcae17746 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public abstract class IsolatedStoragePermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermissionAttribute.cs index 30189ad078167e..77bdd246411bb5 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/IsolatedStoragePermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public abstract class IsolatedStoragePermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermission.cs index 0f6a490160057f..5567368fc678a7 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class KeyContainerPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntry.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntry.cs index 771c23abb4db7c..038ab40f6d9361 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntry.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntry.cs @@ -5,7 +5,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class KeyContainerPermissionAccessEntry diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryCollection.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryCollection.cs index 4dd5f15a0d0995..f4312632fb71dc 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryCollection.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryCollection.cs @@ -5,7 +5,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class KeyContainerPermissionAccessEntryCollection : ICollection diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryEnumerator.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryEnumerator.cs index 86ed27dd250cab..e8af76d424051e 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryEnumerator.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAccessEntryEnumerator.cs @@ -5,7 +5,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class KeyContainerPermissionAccessEntryEnumerator : IEnumerator diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAttribute.cs index 7211ff86ccbaf0..239772f6912b0a 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionFlags.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionFlags.cs index 50004c265344b5..0a4ece5eb35d52 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionFlags.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/KeyContainerPermissionFlags.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum KeyContainerPermissionFlags diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/MediaPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/MediaPermission.cs index 26d3b914f868ec..543f37aa11671d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/MediaPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/MediaPermission.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum MediaPermissionAudio @@ -13,7 +13,7 @@ public enum MediaPermissionAudio AllAudio } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum MediaPermissionVideo @@ -24,7 +24,7 @@ public enum MediaPermissionVideo AllVideo, } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum MediaPermissionImage @@ -35,7 +35,7 @@ public enum MediaPermissionImage AllImage, } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class MediaPermission : CodeAccessPermission, IUnrestrictedPermission @@ -61,7 +61,7 @@ public override void FromXml(SecurityElement securityElement) { } public MediaPermissionImage Image { get { return MediaPermissionImage.AllImage; } } } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PermissionSetAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PermissionSetAttribute.cs index c36c4cbc73bd98..6bfe07a081b8e2 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PermissionSetAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PermissionSetAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs index 060fd7b4f06794..aebdfcfbe66185 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs @@ -8,7 +8,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class PrincipalPermission : IPermission, ISecurityEncodable, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs index b8a3ff91e7b4e3..14a620670ec878 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermissionAttribute.cs @@ -3,13 +3,13 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(68), AllowMultiple = true, Inherited = false)] public sealed partial class PrincipalPermissionAttribute : CodeAccessSecurityAttribute { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.PrincipalPermissionAttributeMessage, error: true, DiagnosticId = Obsoletions.PrincipalPermissionAttributeDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public PrincipalPermissionAttribute(SecurityAction action) : base(default(SecurityAction)) { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermission.cs index b0faace69f7ecd..1c326f70458146 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermission.cs @@ -5,7 +5,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class PublisherIdentityPermission : CodeAccessPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermissionAttribute.cs index d8ce7f50636b88..567d880bfdc8cb 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PublisherIdentityPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermission.cs index d6577df8242439..153550aa2a74be 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class ReflectionPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionAttribute.cs index aeec90580dccd7..f6762fe4944bbc 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionFlag.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionFlag.cs index 1c9e39eb6b3d7f..14d809eee162e2 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionFlag.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ReflectionPermissionFlag.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermission.cs index 04fa83df808422..03cefc8f6ae055 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermission.cs @@ -5,7 +5,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class RegistryPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAccess.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAccess.cs index b2f0384acdc1d3..2f50d5d5fecd65 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAccess.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAccess.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAttribute.cs index da29af354dc307..9c4495a8ea3b18 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/RegistryPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBase.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBase.cs index 597647caf26d87..4297b80a495567 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBase.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBase.cs @@ -5,7 +5,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public abstract class ResourcePermissionBase : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBaseEntry.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBaseEntry.cs index 77c012439029b6..ade10e2674c7a3 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBaseEntry.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ResourcePermissionBaseEntry.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public class ResourcePermissionBaseEntry diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SecurityPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SecurityPermission.cs index a1aa39a9764f73..5df48d3d440f9e 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SecurityPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SecurityPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class SecurityPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermission.cs index 160a9301aed394..d1296b7bd7e4b5 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class SiteIdentityPermission : CodeAccessPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermissionAttribute.cs index 9110f6b74f7402..da1eacf54f7688 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/SiteIdentityPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermission.cs index 691439b51dd580..07a2ea11dbe4a6 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class StorePermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionAttribute.cs index c3c50ebf60afe5..8614491c3d21d2 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionFlags.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionFlags.cs index 283e66a697f7c5..13b271e49dc847 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionFlags.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StorePermissionFlags.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermission.cs index 1d66fa2f7e48ac..2fd19c8447fd3d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class StrongNameIdentityPermission : CodeAccessPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermissionAttribute.cs index 07b3014ec9a7fb..7863adc97853a8 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNameIdentityPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs index 44b39f9c8ad986..513e5e04b21cb2 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class StrongNamePublicKeyBlob diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermission.cs index d1e18e0a81069e..8ba9f50cdb8aa9 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class TypeDescriptorPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionAttribute.cs index 767a40af5103d2..708244fba8b5ce 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionFlags.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionFlags.cs index b8c76becc953b8..ad40546c57cefc 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionFlags.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/TypeDescriptorPermissionFlags.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [Flags] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermission.cs index a325753b611342..95e3fadeea8b4b 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class UIPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionAttribute.cs index f5569f8af056c0..8de20804274028 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionClipboard.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionClipboard.cs index cbe563a8ecffb8..7739ac11bd19e6 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionClipboard.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionClipboard.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum UIPermissionClipboard diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionWindow.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionWindow.cs index c87c0b8dfdf661..766027238938e0 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionWindow.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UIPermissionWindow.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum UIPermissionWindow diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermission.cs index 1ddc1172e27372..7a74ef52fcd150 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class UrlIdentityPermission : CodeAccessPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermissionAttribute.cs index 49ce74de84e48d..cda8134abe7f60 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/UrlIdentityPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/WebBrowserPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/WebBrowserPermission.cs index 3f0670d9fa276a..c4ac4a3fb126f3 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/WebBrowserPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/WebBrowserPermission.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public enum WebBrowserPermissionLevel @@ -12,7 +12,7 @@ public enum WebBrowserPermissionLevel Unrestricted } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class WebBrowserPermission : CodeAccessPermission, IUnrestrictedPermission @@ -30,7 +30,7 @@ public override void FromXml(SecurityElement securityElement) { } public WebBrowserPermissionLevel Level { get { return WebBrowserPermissionLevel.Unrestricted; } set { } } } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermission.cs index 61e1945c22ef96..0caf076e6e585e 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermission.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class ZoneIdentityPermission : CodeAccessPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermissionAttribute.cs index 0f66c4bd431761..2833529125c59a 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/ZoneIdentityPermissionAttribute.cs @@ -3,7 +3,7 @@ namespace System.Security.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage((AttributeTargets)(109), AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/ApplicationTrust.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/ApplicationTrust.cs index b17afed7b99df7..6646fe2979389f 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/ApplicationTrust.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/ApplicationTrust.cs @@ -9,14 +9,14 @@ public sealed partial class ApplicationTrust : EvidenceBase, ISecurityEncodable { public ApplicationTrust() { } public ApplicationTrust(ApplicationIdentity identity) { } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public ApplicationTrust(PermissionSet defaultGrantSet, IEnumerable fullTrustAssemblies) { } public ApplicationIdentity ApplicationIdentity { get; set; } public PolicyStatement DefaultGrantSet { get; set; } public object ExtraInfo { get; set; } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public IList FullTrustAssemblies { get { return default(IList); } } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/FileCodeGroup.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/FileCodeGroup.cs index 599d70f03c4317..4e73e5d26f9b86 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/FileCodeGroup.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/FileCodeGroup.cs @@ -3,7 +3,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class FileCodeGroup : CodeGroup diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs index f6565fbf791617..ddee079fb88dbc 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs @@ -3,7 +3,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class GacInstalled : EvidenceBase, IIdentityPermissionFactory diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs index f519bf2c06c2da..b310bdb61d5a59 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs @@ -3,7 +3,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public partial interface IIdentityPermissionFactory diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs index 74afa9599191c4..06c65039eee7ac 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs @@ -18,18 +18,18 @@ internal PolicyLevel() { } public void AddFullTrustAssembly(StrongName sn) { } [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")] public void AddFullTrustAssembly(StrongNameMembershipCondition snMC) { } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public void AddNamedPermissionSet(NamedPermissionSet permSet) { } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public NamedPermissionSet ChangeNamedPermissionSet(string name, PermissionSet pSet) { return default(NamedPermissionSet); } [Obsolete("AppDomain policy levels are obsolete. See https://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] public static PolicyLevel CreateAppDomainLevel() { return default(PolicyLevel); } public void FromXml(SecurityElement e) { } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public NamedPermissionSet GetNamedPermissionSet(string name) { return default(NamedPermissionSet); } @@ -38,11 +38,11 @@ public void Recover() { } public void RemoveFullTrustAssembly(StrongName sn) { } [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")] public void RemoveFullTrustAssembly(StrongNameMembershipCondition snMC) { } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public NamedPermissionSet RemoveNamedPermissionSet(NamedPermissionSet permSet) { return default(NamedPermissionSet); } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public NamedPermissionSet RemoveNamedPermissionSet(string name) { return default(NamedPermissionSet); } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs index d94b4ebaec305d..7ded9666afeb99 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs @@ -5,17 +5,17 @@ namespace System.Security.Policy { public sealed partial class PolicyStatement : ISecurityEncodable, ISecurityPolicyEncodable { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public PolicyStatement(PermissionSet permSet) { } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public PolicyStatement(PermissionSet permSet, PolicyStatementAttribute attributes) { } public PolicyStatementAttribute Attributes { get; set; } public string AttributeString { get { return null; } } -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public PermissionSet PermissionSet { get; set; } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs index 82d4a4c014ac61..ada8aecc2c1448 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs @@ -5,7 +5,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class Publisher : EvidenceBase, IIdentityPermissionFactory diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs index e257cb4d44f126..885d0cdf5a37ca 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs @@ -3,7 +3,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class Site : EvidenceBase, IIdentityPermissionFactory diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongName.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongName.cs index 7f9521026ed3fc..6ef2b7de49a826 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongName.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongName.cs @@ -5,7 +5,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class StrongName : EvidenceBase, IIdentityPermissionFactory diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongNameMembershipCondition.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongNameMembershipCondition.cs index e7fa159370023c..a4fcaaa3ac2a72 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongNameMembershipCondition.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/StrongNameMembershipCondition.cs @@ -5,7 +5,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class StrongNameMembershipCondition : ISecurityEncodable, ISecurityPolicyEncodable, IMembershipCondition diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs index a108d3691fb56b..c83c904c5056c2 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs @@ -3,7 +3,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class Url : EvidenceBase, IIdentityPermissionFactory diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs index 2e08fd3e3a0f01..e494f429238cb8 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs @@ -3,7 +3,7 @@ namespace System.Security.Policy { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class Zone : EvidenceBase, IIdentityPermissionFactory diff --git a/src/libraries/System.Security.Permissions/src/System/Security/SecurityContext.cs b/src/libraries/System.Security.Permissions/src/System/Security/SecurityContext.cs index 1ee1b1d5e60a92..8d8756a54fb145 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/SecurityContext.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/SecurityContext.cs @@ -5,7 +5,7 @@ namespace System.Security { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed partial class SecurityContext : System.IDisposable diff --git a/src/libraries/System.Security.Permissions/src/System/Security/SecurityManager.cs b/src/libraries/System.Security.Permissions/src/System/Security/SecurityManager.cs index 0ff033c383beb9..9f02c6f3951431 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/SecurityManager.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/SecurityManager.cs @@ -6,7 +6,7 @@ namespace System.Security { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public static partial class SecurityManager diff --git a/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermission.cs b/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermission.cs index c049d1e6704697..af27008cee09a3 100644 --- a/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermission.cs @@ -5,7 +5,7 @@ namespace System.ServiceProcess { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class ServiceControllerPermission : ResourcePermissionBase diff --git a/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs index bf7d8cbd98da3d..fea924e61bd5ce 100644 --- a/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.ServiceProcess { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly | AttributeTargets.Event, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermission.cs b/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermission.cs index 0905e0f5b7bd23..7107e3fd7a23f4 100644 --- a/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermission.cs @@ -6,7 +6,7 @@ namespace System.Transactions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class DistributedTransactionPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs index cf17caabf319bf..4c794df14bee42 100644 --- a/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Transactions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true)] diff --git a/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermission.cs b/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermission.cs index 74b2a712674cb5..9735b517fe4f90 100644 --- a/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermission.cs @@ -6,7 +6,7 @@ namespace System.Web { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class AspNetHostingPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs index d5c8631f21623a..9b91e5a31dc784 100644 --- a/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs @@ -6,7 +6,7 @@ namespace System.Web { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] diff --git a/src/libraries/System.Security.Permissions/src/System/Xaml/Permissions/XamlLoadPermission.cs b/src/libraries/System.Security.Permissions/src/System/Xaml/Permissions/XamlLoadPermission.cs index e5b1f021d1c734..5ce3a929edeb7e 100644 --- a/src/libraries/System.Security.Permissions/src/System/Xaml/Permissions/XamlLoadPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Xaml/Permissions/XamlLoadPermission.cs @@ -10,7 +10,7 @@ namespace System.Xaml.Permissions { -#if NETCOREAPP +#if NET [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] #endif public sealed class XamlLoadPermission : CodeAccessPermission, IUnrestrictedPermission diff --git a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/DateTimeHelper.cs b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/DateTimeHelper.cs index ee0bb46bdfb161..b9b6cada89d568 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/DateTimeHelper.cs +++ b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/DateTimeHelper.cs @@ -58,7 +58,7 @@ private static bool Rfc3339DateTimeParser(string dateTimeString, out DateTimeOff ++i; } -#if NETCOREAPP +#if NET dateTimeString = string.Concat(dateTimeString.AsSpan(0, 19), dateTimeString.AsSpan(i)); #else dateTimeString = dateTimeString.Substring(0, 19) + dateTimeString.Substring(i); diff --git a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/XmlBuffer.cs b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/XmlBuffer.cs index 17f3cfa2e1e7ad..4c31f32bf505a2 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/XmlBuffer.cs +++ b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/XmlBuffer.cs @@ -87,7 +87,7 @@ public void Close() _buffer = new byte[_stream.Length]; _stream.Position = 0; -#if NET7_0_OR_GREATER +#if NET _stream.ReadExactly(_buffer); #else int totalRead = 0; diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index dc3a9d931f13e3..fa6be7f42e7403 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -73,7 +73,7 @@ public unsafe void RequestAdditionalTime(int milliseconds) } } -#if NETCOREAPP +#if NET /// /// When this method is called from OnStart, OnStop, OnPause or OnContinue, /// the specified wait hint is passed to the diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs index 2892e1abebe46f..3041721ecaa6a0 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceController.cs @@ -934,7 +934,7 @@ public void Stop() /// /// true to stop all running dependent services together with the service; false to stop only the service. /// -#if NETCOREAPP +#if NET public #else private diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/SessionChangeDescription.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/SessionChangeDescription.cs index e4924e93c414e5..0503b80316e893 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/SessionChangeDescription.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/SessionChangeDescription.cs @@ -6,7 +6,7 @@ namespace System.ServiceProcess { public readonly struct SessionChangeDescription -#if NETCOREAPP +#if NET : IEquatable #endif { diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs index 2d097c766c3322..f0b49f902fa838 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs @@ -70,7 +70,7 @@ private void Cleanup() } } -#if NETCOREAPP +#if NET [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsPrivilegedProcess))] [InlineData(-2)] [InlineData((long)int.MaxValue + 1)] diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/AudioBase.cs b/src/libraries/System.Speech/src/Internal/Synthesis/AudioBase.cs index 782cd59fb6c34c..c8ecfa78483570 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/AudioBase.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/AudioBase.cs @@ -122,7 +122,7 @@ internal void PlayWaveFile(AudioData audio) { byte[] data = new byte[(int)audio._stream.Length]; -#if NET7_0_OR_GREATER +#if NET audio._stream.ReadExactly(data); #else int totalRead = 0; diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/EngineSite.cs b/src/libraries/System.Speech/src/Internal/Synthesis/EngineSite.cs index a658f37ca6180b..c6caca4d9c25bf 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/EngineSite.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/EngineSite.cs @@ -175,7 +175,7 @@ public Stream LoadResource(Uri uri, string mediaType) MemoryStream memStream = new(cLen); byte[] ab = new byte[cLen]; -#if NET7_0_OR_GREATER +#if NET stream.ReadExactly(ab); #else int totalRead = 0; diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/CodePagesEncodingProvider.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/CodePagesEncodingProvider.cs index c984dbf460d8a4..58bb679c7712ae 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/CodePagesEncodingProvider.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/CodePagesEncodingProvider.cs @@ -197,7 +197,7 @@ public static EncodingProvider Instance internal static unsafe ref T GetNonNullPinnableReference(T[] array) where T : struct { return ref -#if NET5_0_OR_GREATER +#if NET MemoryMarshal.GetArrayDataReference(array); #else array.Length != 0 ? ref array[0] : ref Unsafe.AsRef((void*)1); diff --git a/src/libraries/System.Text.Encodings.Web/src/System/IO/TextWriterExtensions.cs b/src/libraries/System.Text.Encodings.Web/src/System/IO/TextWriterExtensions.cs index bcb3cb0bd77830..11bff860545bd3 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System/IO/TextWriterExtensions.cs +++ b/src/libraries/System.Text.Encodings.Web/src/System/IO/TextWriterExtensions.cs @@ -3,7 +3,7 @@ using System.Diagnostics; -#if !NETCOREAPP +#if !NET using System.Buffers; #endif @@ -29,7 +29,7 @@ public static void WritePartialString(this TextWriter writer, string value, int // if slicing is required, call TextWriter.Write(ROS) if available; // otherwise rent an array and implement the Write routine ourselves ReadOnlySpan sliced = value.AsSpan(offset, count); -#if NETCOREAPP +#if NET writer.Write(sliced); #else char[] rented = ArrayPool.Shared.Rent(sliced.Length); diff --git a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/AllowedBmpCodePointsBitmap.cs b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/AllowedBmpCodePointsBitmap.cs index 377d1d0c071d45..d989b7c267e78d 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/AllowedBmpCodePointsBitmap.cs +++ b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/AllowedBmpCodePointsBitmap.cs @@ -6,7 +6,7 @@ using System.Runtime.CompilerServices; using System.Text.Unicode; -#if NETCOREAPP +#if NET using System.Numerics; #endif @@ -69,7 +69,7 @@ public void ForbidUndefinedCharacters() Span thisAllowedCharactersBitmap = new Span(pBitmap, BitmapLengthInDWords); Debug.Assert(definedCharsBitmapAsLittleEndian.Length == thisAllowedCharactersBitmap.Length * sizeof(uint)); -#if NETCOREAPP +#if NET if (Vector.IsHardwareAccelerated && BitConverter.IsLittleEndian) { while (!definedCharsBitmapAsLittleEndian.IsEmpty) diff --git a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.Ascii.cs b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.Ascii.cs index 03c0e7fc324bfd..d2aac7f94f4cfb 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.Ascii.cs +++ b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.Ascii.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if NETCOREAPP +#if NET using System.Runtime.Intrinsics; #endif @@ -22,7 +22,7 @@ private unsafe partial struct AllowedAsciiCodePoints [FieldOffset(0)] // ensure same offset with AsVector field private fixed byte AsBytes[16]; -#if NETCOREAPP +#if NET #if !TARGET_BROWSER [FieldOffset(0)] // ensure same offset with AsBytes field internal Vector128 AsVector; diff --git a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.cs b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.cs index 56fc2b77a93872..e3f12a3b2a84de 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.cs +++ b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/OptimizedInboxTextEncoder.cs @@ -5,11 +5,11 @@ using System.Diagnostics; using System.Runtime.CompilerServices; -#if NETCOREAPP +#if NET using System.Runtime.Intrinsics.X86; #endif -#if NETCOREAPP +#if NET using System.Runtime.Intrinsics.Arm; #endif @@ -347,7 +347,7 @@ public int GetIndexOfFirstByteToEncode(ReadOnlySpan data) int dataOriginalLength = data.Length; -#if NETCOREAPP +#if NET if (Ssse3.IsSupported || (AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian)) { int asciiBytesSkipped; @@ -416,7 +416,7 @@ public unsafe int GetIndexOfFirstCharToEncode(ReadOnlySpan data) // The SIMD-enabled version handles only ASCII characters. nuint idx = 0; -#if NETCOREAPP +#if NET if (Ssse3.IsSupported) { idx = GetIndexOfFirstCharToEncodeSsse3(pData, lengthInChars); diff --git a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs index 41b620e1beec02..4c9aee5292948a 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs +++ b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs @@ -150,7 +150,7 @@ private string EncodeToNewString(ReadOnlySpan value, int indexOfFirstCharT ReadOnlySpan remainingInput = value.Slice(indexOfFirstCharToEncode); ValueStringBuilder stringBuilder = new ValueStringBuilder(stackalloc char[EncodeStartingOutputBufferSize]); -#if !NETCOREAPP +#if !NET // Can't call string.Concat later in the method, so memcpy now. stringBuilder.Append(value.Slice(0, indexOfFirstCharToEncode)); #endif @@ -175,7 +175,7 @@ private string EncodeToNewString(ReadOnlySpan value, int indexOfFirstCharT stringBuilder.Length -= destBuffer.Length - charsWrittenJustNow; } while (!remainingInput.IsEmpty); -#if NETCOREAPP +#if NET string retVal = string.Concat(value.Slice(0, indexOfFirstCharToEncode), stringBuilder.AsSpan()); stringBuilder.Dispose(); return retVal; diff --git a/src/libraries/System.Text.Json/Common/JsonCamelCaseNamingPolicy.cs b/src/libraries/System.Text.Json/Common/JsonCamelCaseNamingPolicy.cs index 436489906a6250..43fa642a3c6d2d 100644 --- a/src/libraries/System.Text.Json/Common/JsonCamelCaseNamingPolicy.cs +++ b/src/libraries/System.Text.Json/Common/JsonCamelCaseNamingPolicy.cs @@ -12,7 +12,7 @@ public override string ConvertName(string name) return name; } -#if NETCOREAPP +#if NET return string.Create(name.Length, name, (chars, name) => { name.CopyTo(chars); diff --git a/src/libraries/System.Text.Json/Common/JsonHelpers.cs b/src/libraries/System.Text.Json/Common/JsonHelpers.cs index 5711afa8370689..ad718eba4a41fe 100644 --- a/src/libraries/System.Text.Json/Common/JsonHelpers.cs +++ b/src/libraries/System.Text.Json/Common/JsonHelpers.cs @@ -11,7 +11,7 @@ namespace System.Text.Json { internal static partial class JsonHelpers { -#if !NETCOREAPP +#if !NET /// /// netstandard/netfx polyfill for Dictionary.TryAdd /// @@ -55,7 +55,7 @@ internal static bool RequiresSpecialNumberHandlingOnWrite(JsonNumberHandling? ha internal static void StableSortByKey(this List items, Func keySelector) where TKey : unmanaged, IComparable { -#if NET6_0_OR_GREATER +#if NET Span span = CollectionsMarshal.AsSpan(items); // Tuples implement lexical ordering OOTB which can be used to encode stable sorting diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 0ff5bdc90a66ee..e16277de475290 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -659,7 +659,9 @@ namespace System.Text.Json.Nodes public sealed partial class JsonArray : System.Text.Json.Nodes.JsonNode, System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.IEnumerable { public JsonArray(System.Text.Json.Nodes.JsonNodeOptions? options = default(System.Text.Json.Nodes.JsonNodeOptions?)) { } + public JsonArray(System.Text.Json.Nodes.JsonNodeOptions options, System.ReadOnlySpan items) { } public JsonArray(System.Text.Json.Nodes.JsonNodeOptions options, params System.Text.Json.Nodes.JsonNode?[] items) { } + public JsonArray(System.ReadOnlySpan items) { } public JsonArray(params System.Text.Json.Nodes.JsonNode?[] items) { } public int Count { get { throw null; } } bool System.Collections.Generic.ICollection.IsReadOnly { get { throw null; } } @@ -1352,6 +1354,7 @@ public enum JsonTypeInfoKind } public static partial class JsonTypeInfoResolver { + public static System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver Combine(System.ReadOnlySpan resolvers) { throw null; } public static System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver Combine(params System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver?[] resolvers) { throw null; } public static System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver WithAddedModifier(this System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver resolver, System.Action modifier) { throw null; } } diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs index 847da900ad35d8..bbf2e3846a6bcd 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs @@ -12,7 +12,7 @@ public static partial class JsonMetadataServices public static System.Text.Json.Serialization.JsonConverter HalfConverter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter TimeOnlyConverter { get { throw null; } } -#if NET7_0_OR_GREATER +#if NET public static System.Text.Json.Serialization.JsonConverter Int128Converter { get { throw null; } } [System.CLSCompliantAttribute(false)] public static System.Text.Json.Serialization.JsonConverter UInt128Converter { get { throw null; } } diff --git a/src/libraries/System.Text.Json/src/System/ReflectionExtensions.cs b/src/libraries/System.Text.Json/src/System/ReflectionExtensions.cs index 9dab389dd045a0..ec6b46db24e877 100644 --- a/src/libraries/System.Text.Json/src/System/ReflectionExtensions.cs +++ b/src/libraries/System.Text.Json/src/System/ReflectionExtensions.cs @@ -97,7 +97,7 @@ private static bool HasCustomAttributeWithName(this MemberInfo memberInfo, strin object?[] parameters) { ConstructorInfo ctorInfo = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, parameterTypes, null)!; -#if NETCOREAPP +#if NET return ctorInfo.Invoke(BindingFlags.DoNotWrapExceptions, null, parameters, null); #else object? result = null; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs index afdbf4bd0b9b26..a53df982c12eb4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs @@ -240,7 +240,7 @@ private void Enlarge() // Note: Array.MaxLength exists only on .NET 6 or greater, // so for the other versions value is hardcoded const int MaxArrayLength = 0x7FFFFFC7; -#if NET6_0_OR_GREATER +#if NET Debug.Assert(MaxArrayLength == Array.MaxLength); #endif diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs index f9b1fffd4243b2..6bd5a2814b6460 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs @@ -833,7 +833,7 @@ private static ArraySegment ReadToEnd(Stream stream) } private static async -#if NETCOREAPP +#if NET ValueTask> #else Task> @@ -871,7 +871,7 @@ private static async Debug.Assert(rented.Length >= JsonConstants.Utf8Bom.Length); lastRead = await stream.ReadAsync( -#if NETCOREAPP +#if NET rented.AsMemory(written, utf8BomLength - written), #else rented, @@ -902,7 +902,7 @@ private static async } lastRead = await stream.ReadAsync( -#if NETCOREAPP +#if NET rented.AsMemory(written), #else rented, diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 7fe47499c1aa85..c2dbc58e131a0c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -65,7 +65,7 @@ internal static partial class JsonConstants // When transcoding from UTF8 -> UTF16, the byte count threshold where we rent from the array pool before performing a normal alloc. public const long ArrayPoolMaxSizeBeforeUsingNormalAlloc = -#if NET6_0_OR_GREATER +#if NET 1024 * 1024 * 1024; // ArrayPool limit increased in .NET 6 #else 1024 * 1024; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs index f6c6e9255d9c31..751f262acf3a34 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs @@ -95,7 +95,7 @@ public static bool TryParseAsISO(ReadOnlySpan source, out DateTimeOffset v return TryCreateDateTimeOffsetInterpretingDataAsLocalTime(parseData, out value); } -#if NETCOREAPP +#if NET public static bool TryParseAsIso(ReadOnlySpan source, out DateOnly value) { if (TryParseDateTimeOffset(source, out DateTimeParseData parseData) && diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs index 322b1d315c091e..63e2e177f49eb3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs @@ -76,7 +76,7 @@ static bool TryAdvanceWithReadAhead(scoped ref Utf8JsonReader reader) } } -#if !NETCOREAPP +#if !NET /// /// Returns if is a valid Unicode scalar /// value, i.e., is in [ U+0000..U+D7FF ], inclusive; or [ U+E000..U+10FFFF ], inclusive. @@ -165,7 +165,7 @@ public static bool TrySkipPartial(this ref Utf8JsonReader reader) /// public static string Utf8GetString(ReadOnlySpan bytes) { -#if NETCOREAPP +#if NET return Encoding.UTF8.GetString(bytes); #else if (bytes.Length == 0) @@ -191,7 +191,7 @@ public static Dictionary CreateDictionaryFromCollection comparer) where TKey : notnull { -#if !NETCOREAPP +#if !NET var dictionary = new Dictionary(comparer); foreach (KeyValuePair item in collection) @@ -207,7 +207,7 @@ public static Dictionary CreateDictionaryFromCollection + /// Initializes a new instance of the class that contains items from the specified params span. + /// + /// Options to control the behavior. + /// The items to add to the new . + public JsonArray(JsonNodeOptions options, /*params*/ ReadOnlySpan items) : base(options) + { + InitializeFromSpan(items); + } + /// /// Initializes a new instance of the class that contains items from the specified array. /// @@ -48,6 +58,15 @@ public JsonArray(params JsonNode?[] items) : base() InitializeFromArray(items); } + /// + /// Initializes a new instance of the class that contains items from the specified span. + /// + /// The items to add to the new . + public JsonArray(/*params*/ ReadOnlySpan items) : base() + { + InitializeFromSpan(items); + } + internal override JsonValueKind GetValueKindCore() => JsonValueKind.Array; internal override JsonNode DeepCloneCore() @@ -129,9 +148,30 @@ private void InitializeFromArray(JsonNode?[] items) { var list = new List(items); - for (int i = 0; i < items.Length; i++) + for (int i = 0; i < list.Count; i++) + { + list[i]?.AssignParent(this); + } + + _list = list; + } + + private void InitializeFromSpan(ReadOnlySpan items) + { + List list = new(items.Length); + +#if NET8_0_OR_GREATER + list.AddRange(items); +#else + foreach (JsonNode? item in items) + { + list.Add(item); + } +#endif + + for (int i = 0; i < list.Count; i++) { - items[i]?.AssignParent(this); + list[i]?.AssignParent(this); } _list = list; @@ -206,7 +246,7 @@ internal override void GetPath(ref ValueStringBuilder path, JsonNode? child) Debug.Assert(index >= 0); path.Append('['); -#if NETCOREAPP +#if NET Span chars = stackalloc char[JsonConstants.MaximumFormatUInt32Length]; bool formatted = ((uint)index).TryFormat(chars, out int charsWritten); Debug.Assert(formatted); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs index 7408aaecc53ce0..298a59a6471739 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs @@ -210,7 +210,7 @@ public static string TranscodeHelper(ReadOnlySpan utf8Unescaped) { try { -#if NETCOREAPP +#if NET return s_utf8Encoding.GetString(utf8Unescaped); #else if (utf8Unescaped.IsEmpty) @@ -241,7 +241,7 @@ public static int TranscodeHelper(ReadOnlySpan utf8Unescaped, Span d { try { -#if NETCOREAPP +#if NET return s_utf8Encoding.GetChars(utf8Unescaped, destination); #else if (utf8Unescaped.IsEmpty) @@ -285,7 +285,7 @@ public static void ValidateUtf8(ReadOnlySpan utf8Buffer) #else try { -#if NETCOREAPP +#if NET s_utf8Encoding.GetCharCount(utf8Buffer); #else if (utf8Buffer.IsEmpty) @@ -317,7 +317,7 @@ internal static int GetUtf8ByteCount(ReadOnlySpan text) { try { -#if NETCOREAPP +#if NET return s_utf8Encoding.GetByteCount(text); #else if (text.IsEmpty) @@ -348,7 +348,7 @@ internal static int GetUtf8FromText(ReadOnlySpan text, Span dest) { try { -#if NETCOREAPP +#if NET return s_utf8Encoding.GetBytes(text, dest); #else if (text.IsEmpty) @@ -379,7 +379,7 @@ internal static int GetUtf8FromText(ReadOnlySpan text, Span dest) internal static string GetTextFromUtf8(ReadOnlySpan utf8Text) { -#if NETCOREAPP +#if NET return s_utf8Encoding.GetString(utf8Text); #else if (utf8Text.IsEmpty) @@ -528,7 +528,7 @@ private static bool TryUnescape(ReadOnlySpan source, Span destinatio + JsonConstants.UnicodePlane01StartValue; } -#if NETCOREAPP +#if NET var rune = new Rune(scalar); bool success = rune.TryEncodeToUtf8(destination.Slice(written), out int bytesWritten); #else @@ -601,7 +601,7 @@ private static bool TryUnescape(ReadOnlySpan source, Span destinatio return false; } -#if !NETCOREAPP +#if !NET /// /// Copies the UTF-8 code unit representation of this scalar to an output buffer. /// The buffer must be large enough to hold the required number of s. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs index 9cdcc0ddfad74f..b426f61cbb31dd 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs @@ -145,7 +145,7 @@ public static bool TryGetEscapedGuid(ReadOnlySpan source, out Guid value) return false; } -#if NETCOREAPP +#if NET public static bool TryGetFloatingPointConstant(ReadOnlySpan span, out Half value) { if (span.Length == 3) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs index 8635031292e32c..22d3cc1c497d81 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs @@ -633,7 +633,7 @@ private static int FindMismatch(ReadOnlySpan span, ReadOnlySpan lite int indexOfFirstMismatch; -#if NET7_0_OR_GREATER +#if NET indexOfFirstMismatch = span.CommonPrefixLength(literal); #else int minLength = Math.Min(span.Length, literal.Length); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs index 622ba2cf21d19e..3d1c4ce8fce545 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs @@ -93,7 +93,7 @@ public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, public static bool IsNonGenericStackOrQueue(this Type type) { -#if NETCOREAPP +#if NET // Optimize for linking scenarios where mscorlib is trimmed out. const string stackTypeName = "System.Collections.Stack, System.Collections.NonGeneric"; const string queueTypeName = "System.Collections.Queue, System.Collections.NonGeneric"; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs index 82e7e2699a956e..c102a0879e1ac6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/CharConverter.cs @@ -36,7 +36,7 @@ public override char Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSer public override void Write(Utf8JsonWriter writer, char value, JsonSerializerOptions options) { writer.WriteStringValue( -#if NETCOREAPP +#if NET new ReadOnlySpan(in value) #else value.ToString() @@ -53,7 +53,7 @@ internal override char ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type ty internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, char value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { writer.WritePropertyName( -#if NETCOREAPP +#if NET new ReadOnlySpan(in value) #else value.ToString() diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index 99b576030243eb..5f9ddf1eee1b62 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -61,7 +61,7 @@ public EnumConverter(EnumConverterOptions converterOptions, JsonNamingPolicy? na _nameCacheForReading = new ConcurrentDictionary(); } -#if NETCOREAPP +#if NET string[] names = Enum.GetNames(); T[] values = Enum.GetValues(); #else @@ -74,7 +74,7 @@ public EnumConverter(EnumConverterOptions converterOptions, JsonNamingPolicy? na for (int i = 0; i < names.Length; i++) { -#if NETCOREAPP +#if NET T value = values[i]; #else T value = (T)values.GetValue(i)!; @@ -106,7 +106,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial return default; } -#if NETCOREAPP +#if NET if (TryParseEnumCore(ref reader, out T value)) #else string? enumString = reader.GetString(); @@ -116,7 +116,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial return value; } -#if NETCOREAPP +#if NET return ReadEnumUsingNamingPolicy(reader.GetString()); #else return ReadEnumUsingNamingPolicy(enumString); @@ -270,7 +270,7 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions internal override T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { -#if NETCOREAPP +#if NET if (TryParseEnumCore(ref reader, out T value)) #else string? enumString = reader.GetString(); @@ -280,7 +280,7 @@ internal override T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeT return value; } -#if NETCOREAPP +#if NET return ReadEnumUsingNamingPolicy(reader.GetString()); #else return ReadEnumUsingNamingPolicy(enumString); @@ -362,14 +362,14 @@ internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, T value, J } private bool TryParseEnumCore( -#if NETCOREAPP +#if NET ref Utf8JsonReader reader, #else string? source, #endif out T value) { -#if NETCOREAPP +#if NET char[]? rentedBuffer = null; int bufferLength = reader.ValueLength; @@ -393,7 +393,7 @@ private bool TryParseEnumCore( value = default; } -#if NETCOREAPP +#if NET if (rentedBuffer != null) { charBuffer.Slice(0, charsWritten).Clear(); @@ -525,7 +525,7 @@ private static string[] SplitFlagsEnum(string value) { // todo: optimize implementation here by leveraging https://github.com/dotnet/runtime/issues/934. return value.Split( -#if NETCOREAPP +#if NET ValueSeparator #else new string[] { ValueSeparator }, StringSplitOptions.None diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs index c3e60ab0448d34..85e0d8f67398a4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/VersionConverter.cs @@ -7,7 +7,7 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class VersionConverter : JsonPrimitiveConverter { -#if NETCOREAPP +#if NET private const int MinimumVersionLength = 3; // 0.0 private const int MaximumVersionLength = 43; // 2147483647.2147483647.2147483647.2147483647 @@ -34,7 +34,7 @@ private static Version ReadCore(ref Utf8JsonReader reader) { Debug.Assert(reader.TokenType is JsonTokenType.PropertyName or JsonTokenType.String); -#if NETCOREAPP +#if NET if (!JsonHelpers.IsInRangeInclusive(reader.ValueLength, MinimumVersionLength, MaximumEscapedVersionLength)) { ThrowHelper.ThrowFormatException(DataType.Version); @@ -84,7 +84,7 @@ public override void Write(Utf8JsonWriter writer, Version? value, JsonSerializer return; } -#if NETCOREAPP +#if NET #if NET8_0_OR_GREATER Span span = stackalloc byte[MaximumVersionLength]; #else @@ -110,7 +110,7 @@ internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, Version va ThrowHelper.ThrowArgumentNullException(nameof(value)); } -#if NETCOREAPP +#if NET #if NET8_0_OR_GREATER Span span = stackalloc byte[MaximumVersionLength]; #else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index 469abaae498d25..cf8b87696ea713 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -214,7 +214,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali bool success; if ( -#if NETCOREAPP +#if NET !typeof(T).IsValueType && #endif CanBePolymorphic) @@ -367,7 +367,7 @@ internal bool TryWrite(Utf8JsonWriter writer, in T? value, JsonSerializerOptions bool success; if ( -#if NETCOREAPP +#if NET // Short-circuit the check against "is not null"; treated as a constant by recent versions of the JIT. !typeof(T).IsValueType && #else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs index c8fd040736dbb9..e171d8cdebe490 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs @@ -213,7 +213,7 @@ internal void ClearCaches() internal sealed class CachingContext { private readonly ConcurrentDictionary _cache = new(); -#if !NETCOREAPP +#if !NET private readonly Func _cacheEntryFactory; #endif @@ -221,7 +221,7 @@ public CachingContext(JsonSerializerOptions options, int hashCode) { Options = options; HashCode = hashCode; -#if !NETCOREAPP +#if !NET _cacheEntryFactory = type => CreateCacheEntry(type, this); #endif } @@ -254,7 +254,7 @@ public void Clear() private CacheEntry GetOrAddCacheEntry(Type type) { -#if NETCOREAPP +#if NET return _cache.GetOrAdd(type, CreateCacheEntry, this); #else return _cache.GetOrAdd(type, _cacheEntryFactory); @@ -605,7 +605,7 @@ static void AddHashCode(ref HashCode hc, TValue? value) } } -#if !NETCOREAPP +#if !NET /// /// Polyfill for System.HashCode. /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Converters.cs index 117e3ba3d63a97..c96e2a1c8f5da5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Converters.cs @@ -51,7 +51,7 @@ private static Dictionary GetDefaultSimpleConverters() Add(JsonMetadataServices.CharConverter); Add(JsonMetadataServices.DateTimeConverter); Add(JsonMetadataServices.DateTimeOffsetConverter); -#if NETCOREAPP +#if NET Add(JsonMetadataServices.DateOnlyConverter); Add(JsonMetadataServices.TimeOnlyConverter); Add(JsonMetadataServices.HalfConverter); @@ -74,7 +74,7 @@ private static Dictionary GetDefaultSimpleConverters() Add(JsonMetadataServices.UInt16Converter); Add(JsonMetadataServices.UInt32Converter); Add(JsonMetadataServices.UInt64Converter); -#if NET7_0_OR_GREATER +#if NET Add(JsonMetadataServices.Int128Converter); Add(JsonMetadataServices.UInt128Converter); #endif diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs index 3a39315eba51c0..3ce9c15709819a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs @@ -23,7 +23,7 @@ internal static MemberAccessor MemberAccessor static MemberAccessor Initialize() { MemberAccessor value = -#if NETCOREAPP +#if NET // if dynamic code isn't supported, fallback to reflection RuntimeFeature.IsDynamicCodeSupported ? new ReflectionEmitCachingMemberAccessor() : diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs index 83a24191b8fe25..9c6cb4b9e3ce3d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs @@ -50,7 +50,7 @@ public static partial class JsonMetadataServices public static JsonConverter DateTimeOffsetConverter => s_dateTimeOffsetConverter ??= new DateTimeOffsetConverter(); private static JsonConverter? s_dateTimeOffsetConverter; -#if NETCOREAPP +#if NET /// /// Returns a instance that converts values. /// @@ -108,7 +108,7 @@ public static partial class JsonMetadataServices public static JsonConverter Int64Converter => s_int64Converter ??= new Int64Converter(); private static JsonConverter? s_int64Converter; -#if NET7_0_OR_GREATER +#if NET /// /// Returns a instance that converts values. /// @@ -188,7 +188,7 @@ public static partial class JsonMetadataServices public static JsonConverter ObjectConverter => s_objectConverter ??= new DefaultObjectConverter(); private static JsonConverter? s_objectConverter; -#if NETCOREAPP +#if NET /// /// Returns a instance that converts values. /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs index 959490b53f19fc..4a6f10aa440630 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfo.cs @@ -623,10 +623,10 @@ private bool NumberHandingIsApplicable() potentialNumberType == typeof(ushort) || potentialNumberType == typeof(uint) || potentialNumberType == typeof(ulong) || -#if NETCOREAPP +#if NET potentialNumberType == typeof(Half) || #endif -#if NET7_0_OR_GREATER +#if NET potentialNumberType == typeof(Int128) || potentialNumberType == typeof(UInt128) || #endif diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs index 379a3754cf574f..01369330feb68f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs @@ -160,7 +160,7 @@ internal override bool GetMemberAndWriteJson(object obj, ref WriteStack state, U T value = Get!(obj); if ( -#if NETCOREAPP +#if NET !typeof(T).IsValueType && // treated as a constant by recent versions of the JIT. #else !EffectiveConverter.IsValueType && diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index e915c5bf4879ea..f8d5bffedc51dc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -1249,7 +1249,7 @@ internal void SetCreateObjectIfCompatible(Delegate? createObject) private static bool IsByRefLike(Type type) { -#if NETCOREAPP +#if NET return type.IsByRefLike; #else if (!type.IsValueType) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs index d916334c1925a3..08bec6e288981b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.WriteHelpers.cs @@ -36,7 +36,7 @@ internal void Serialize( writer.Flush(); } else if ( -#if NETCOREAPP +#if NET !typeof(T).IsValueType && #endif Converter.CanBePolymorphic && @@ -96,7 +96,7 @@ internal async Task SerializeAsync( await bufferWriter.WriteToStreamAsync(utf8Json, cancellationToken).ConfigureAwait(false); } else if ( -#if NETCOREAPP +#if NET !typeof(T).IsValueType && #endif Converter.CanBePolymorphic && @@ -222,7 +222,7 @@ internal void Serialize( } } else if ( -#if NETCOREAPP +#if NET !typeof(T).IsValueType && #endif Converter.CanBePolymorphic && diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoResolver.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoResolver.cs index 216329609f3b90..9bd63188cbe525 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoResolver.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoResolver.cs @@ -30,6 +30,25 @@ public static IJsonTypeInfoResolver Combine(params IJsonTypeInfoResolver?[] reso ThrowHelper.ThrowArgumentNullException(nameof(resolvers)); } + return Combine((ReadOnlySpan)resolvers); + } + + /// + /// Combines multiple sources into one. + /// + /// Sequence of contract resolvers to be queried for metadata. + /// A combining results from . + /// + /// The combined resolver will query each of in the specified order, + /// returning the first result that is non-null. If all return null, + /// then the combined resolver will also return . + /// + /// Can be used to combine multiple sources, + /// which typically define contract metadata for small subsets of types. + /// It can also be used to fall back to wherever necessary. + /// + public static IJsonTypeInfoResolver Combine(/*params*/ ReadOnlySpan resolvers) + { var resolverChain = new JsonTypeInfoResolverChain(); foreach (IJsonTypeInfoResolver? resolver in resolvers) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.Cache.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.Cache.cs index 8e966a122a4ffe..dc203854c3d858 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.Cache.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.Cache.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NETFRAMEWORK || NETCOREAPP +#if NETFRAMEWORK || NET using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -30,7 +30,7 @@ public TValue GetOrAdd(TKey key, Func valueFactory) where { CacheEntry entry = _cache.GetOrAdd( key, -#if NETCOREAPP +#if NET static (TKey key, Func valueFactory) => new(valueFactory(key)), valueFactory); #else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs index 4efe2a3af47f12..dc18286f7e1270 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitCachingMemberAccessor.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NETFRAMEWORK || NETCOREAPP +#if NETFRAMEWORK || NET using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Reflection; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs index 5e6f6986539e10..7bda4bda73f5eb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NETFRAMEWORK || NETCOREAPP +#if NETFRAMEWORK || NET using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs index 593bb6a20dffa0..dc624235377a3f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs @@ -49,7 +49,7 @@ public readonly async ValueTask ReadFromStreamAsync( do { int bytesRead = await utf8Json.ReadAsync( -#if NETCOREAPP +#if NET bufferState._buffer.AsMemory(bufferState._count), #else bufferState._buffer, bufferState._count, bufferState._buffer.Length - bufferState._count, @@ -80,7 +80,7 @@ public void ReadFromStream(Stream utf8Json) do { int bytesRead = utf8Json.Read( -#if NETCOREAPP +#if NET _buffer.AsSpan(_count)); #else _buffer, _count, _buffer.Length - _count); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index d183423c132325..5647005377e3f0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -412,7 +412,7 @@ public static void ReThrowWithPath(scoped ref ReadStack state, JsonReaderExcepti string message = ex.Message; // Insert the "Path" portion before "LineNumber" and "BytePositionInLine". -#if NETCOREAPP +#if NET int iPos = message.AsSpan().LastIndexOf(" LineNumber: "); #else int iPos = message.LastIndexOf(" LineNumber: ", StringComparison.Ordinal); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 62705446f8f5d1..140ecfb9112314 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -6,7 +6,7 @@ using System.Diagnostics; using System.Text.Encodings.Web; -#if !NETCOREAPP +#if !NET using System.Runtime.CompilerServices; #endif @@ -42,7 +42,7 @@ internal static partial class JsonWriterHelper 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // U+00F0..U+00FF ]; -#if NETCOREAPP +#if NET private const string HexFormatString = "X4"; #endif @@ -290,7 +290,7 @@ private static void EscapeNextChars(char value, Span destination, ref int break; default: destination[written++] = 'u'; -#if NETCOREAPP +#if NET int intChar = value; intChar.TryFormat(destination.Slice(written), out int charsWritten, HexFormatString); Debug.Assert(charsWritten == 4); @@ -302,7 +302,7 @@ private static void EscapeNextChars(char value, Span destination, ref int } } -#if !NETCOREAPP +#if !NET private static int WriteHex(int value, Span destination, int written) { destination[written++] = HexConverter.ToCharUpper(value >> 12); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index b5dccf9423be6d..b2e05f589fc10c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -264,7 +264,7 @@ public static unsafe bool IsValidUtf8String(ReadOnlySpan bytes) #else try { -#if NETCOREAPP +#if NET s_utf8Encoding.GetCharCount(bytes); #else if (!bytes.IsEmpty) @@ -286,7 +286,7 @@ public static unsafe bool IsValidUtf8String(ReadOnlySpan bytes) internal static unsafe OperationStatus ToUtf8(ReadOnlySpan source, Span destination, out int written) { -#if NETCOREAPP +#if NET OperationStatus status = Utf8.FromUtf16(source, destination, out int charsRead, out written, replaceInvalidSequences: false, isFinalBlock: true); Debug.Assert(status is OperationStatus.Done or OperationStatus.DestinationTooSmall or OperationStatus.InvalidData); Debug.Assert(charsRead == source.Length || status is not OperationStatus.Done); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 03fab27688d0dc..abaa20358cf6a7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -106,7 +106,7 @@ private static bool TryFormatDouble(double value, Span destination, out in // the .NET Core 3.0 logic of forwarding to the UTF16 formatter and transcoding it back to UTF8, // with some additional changes to remove dependencies on Span APIs which don't exist downlevel. -#if NETCOREAPP +#if NET return Utf8Formatter.TryFormat(value, destination, out bytesWritten); #else string utf16Text = value.ToString(JsonConstants.DoubleFormatString, CultureInfo.InvariantCulture); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 7342704d3479ae..c65c92a89c0357 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -106,7 +106,7 @@ private static bool TryFormatSingle(float value, Span destination, out int // the .NET Core 3.0 logic of forwarding to the UTF16 formatter and transcoding it back to UTF8, // with some additional changes to remove dependencies on Span APIs which don't exist downlevel. -#if NETCOREAPP +#if NET return Utf8Formatter.TryFormat(value, destination, out bytesWritten); #else string utf16Text = value.ToString(JsonConstants.SingleFormatString, CultureInfo.InvariantCulture); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index fcf3ab2d4c2547..f357a89d5d2d04 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -8,7 +8,7 @@ using System.Threading; using System.Threading.Tasks; -#if !NETCOREAPP +#if !NET using System.Runtime.InteropServices; #endif @@ -309,7 +309,7 @@ public void Flush() _arrayBufferWriter.Advance(BytesPending); BytesPending = 0; -#if NETCOREAPP +#if NET _stream.Write(_arrayBufferWriter.WrittenSpan); #else Debug.Assert(_arrayBufferWriter.WrittenMemory.Length == _arrayBufferWriter.WrittenCount); @@ -423,7 +423,7 @@ public async Task FlushAsync(CancellationToken cancellationToken = default) _arrayBufferWriter.Advance(BytesPending); BytesPending = 0; -#if NETCOREAPP +#if NET await _stream.WriteAsync(_arrayBufferWriter.WrittenMemory, cancellationToken).ConfigureAwait(false); #else Debug.Assert(_arrayBufferWriter.WrittenMemory.Length == _arrayBufferWriter.WrittenCount); diff --git a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Dictionary.NonStringKey.cs b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Dictionary.NonStringKey.cs index dfaff9130fa78a..4d61a6f8b3091d 100644 --- a/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Dictionary.NonStringKey.cs +++ b/src/libraries/System.Text.Json/tests/Common/CollectionTests/CollectionTests.Dictionary.NonStringKey.cs @@ -46,7 +46,7 @@ public static IEnumerable GetTestDictionaries() yield return WrapArgs(DateTime.MaxValue, 1, expectedJson: $@"{{""{DateTime.MaxValue:O}"":1}}"); yield return WrapArgs(DateTimeOffset.MaxValue, 1, expectedJson: $@"{{""{DateTimeOffset.MaxValue:O}"":1}}"); yield return WrapArgs(TimeSpan.MaxValue, 1, expectedJson: $@"{{""{TimeSpan.MaxValue}"":1}}"); -#if NET6_0_OR_GREATER +#if NET yield return WrapArgs(DateOnly.MaxValue, 1, expectedJson: $@"{{""{DateOnly.MaxValue:O}"":1}}"); yield return WrapArgs(TimeOnly.MaxValue, 1, expectedJson: $@"{{""{TimeOnly.MaxValue:O}"":1}}"); #endif @@ -66,7 +66,7 @@ public static IEnumerable GetTestDictionaries() yield return WrapArgs(ushort.MaxValue, 1); yield return WrapArgs(uint.MaxValue, 1); yield return WrapArgs(ulong.MaxValue, 1); -#if NETCOREAPP +#if NET yield return WrapArgs(Half.MinValue, 1); yield return WrapArgs(Int128.MinValue, 1); yield return WrapArgs(UInt128.MaxValue, 1); @@ -340,7 +340,7 @@ public async Task TestEscapedValuesOnDeserialize(string escapedPropertyName, obj new object[] { @"\u0042\u0061\u0072\u002c\u0042\u0061\u007a", MyEnumFlags.Bar | MyEnumFlags.Baz, typeof(Dictionary) }, new object[] { @"\u002b", '+', typeof(Dictionary) }, -#if NETCOREAPP +#if NET new object[] { @"\u0033\u002e\u0031\u0032\u0035\u0065\u0034", (Half)3.125e4, typeof(Dictionary) }, new object[] { @"\u002D\u0031\u0037\u0030\u0031\u0034\u0031\u0031\u0038\u0033\u0034\u0036\u0030\u0034\u0036\u0039\u0032\u0033\u0031\u0037\u0033\u0031\u0036\u0038\u0037\u0033\u0030\u0033\u0037\u0031\u0035\u0038\u0038\u0034\u0031\u0030\u0035\u0037\u0032\u0038", diff --git a/src/libraries/System.Text.Json/tests/Common/JsonNumberTestData.cs b/src/libraries/System.Text.Json/tests/Common/JsonNumberTestData.cs index d2d2591ade5ffb..83cf29458dd063 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonNumberTestData.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonNumberTestData.cs @@ -20,7 +20,7 @@ internal class JsonNumberTestData public static List Floats { get; set; } public static List Doubles { get; set; } public static List Decimals { get; set; } -#if NETCOREAPP +#if NET public static List Int128s { get; set; } public static List UInt128s { get; set; } public static List Halfs { get; set; } @@ -37,7 +37,7 @@ internal class JsonNumberTestData public static List NullableFloats { get; set; } public static List NullableDoubles { get; set; } public static List NullableDecimals { get; set; } -#if NETCOREAPP +#if NET public static List NullableInt128s { get; set; } public static List NullableUInt128s { get; set; } public static List NullableHalfs { get; set; } @@ -247,7 +247,7 @@ static JsonNumberTestData() } #endregion -#if NETCOREAPP +#if NET #region generate Int128s Int128s = new List { @@ -381,7 +381,7 @@ static JsonNumberTestData() NullableFloats = new List(Floats.Select(num => (float?)num)); NullableDoubles = new List(Doubles.Select(num => (double?)num)); NullableDecimals = new List(Decimals.Select(num => (decimal?)num)); -#if NETCOREAPP +#if NET NullableInt128s = new List(Int128s.Select(num => (Int128?)num)); NullableUInt128s = new List(UInt128s.Select(num => (UInt128?)num)); NullableHalfs = new List(Halfs.Select(num => (Half?)num)); diff --git a/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs b/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs index f641a4a31290c0..8d96c4e79c432b 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs @@ -15,7 +15,7 @@ namespace System.Text.Json { internal static partial class JsonTestHelper { -#if NETCOREAPP +#if NET public const string DoubleFormatString = null; public const string SingleFormatString = null; #else @@ -23,7 +23,7 @@ internal static partial class JsonTestHelper public const string SingleFormatString = "G9"; #endif -#if NETCOREAPP +#if NET public static Half NextHalf(Random random) { double mantissa = (random.NextDouble() * 2.0) - 1.0; diff --git a/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs b/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs index 6b16a631576fa2..833b01114dc682 100644 --- a/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/NumberHandlingTests.cs @@ -63,7 +63,7 @@ public async Task Number_AsRootType_RoundTrip() await RunAsRootTypeTest(JsonNumberTestData.Floats); await RunAsRootTypeTest(JsonNumberTestData.Doubles); await RunAsRootTypeTest(JsonNumberTestData.Decimals); -#if NETCOREAPP +#if NET await RunAsRootTypeTest(JsonNumberTestData.Int128s); await RunAsRootTypeTest(JsonNumberTestData.UInt128s); await RunAsRootTypeTest(JsonNumberTestData.Halfs); @@ -79,7 +79,7 @@ public async Task Number_AsRootType_RoundTrip() await RunAsRootTypeTest(JsonNumberTestData.NullableFloats); await RunAsRootTypeTest(JsonNumberTestData.NullableDoubles); await RunAsRootTypeTest(JsonNumberTestData.NullableDecimals); -#if NETCOREAPP +#if NET await RunAsRootTypeTest(JsonNumberTestData.NullableInt128s); await RunAsRootTypeTest(JsonNumberTestData.NullableUInt128s); await RunAsRootTypeTest(JsonNumberTestData.NullableHalfs); @@ -383,7 +383,7 @@ public async Task Number_AsCollectionElement_RoundTrip() await RunAsCollectionElementTest(JsonNumberTestData.Floats); await RunAsCollectionElementTest(JsonNumberTestData.Doubles); await RunAsCollectionElementTest(JsonNumberTestData.Decimals); -#if NETCOREAPP +#if NET await RunAsCollectionElementTest(JsonNumberTestData.Int128s); await RunAsCollectionElementTest(JsonNumberTestData.UInt128s); await RunAsCollectionElementTest(JsonNumberTestData.Halfs); @@ -403,7 +403,7 @@ public async Task Number_AsCollectionElement_RoundTrip() await RunAsCollectionElementTest(JsonNumberTestData.NullableFloats); await RunAsCollectionElementTest(JsonNumberTestData.NullableDoubles); await RunAsCollectionElementTest(JsonNumberTestData.NullableDecimals); -#if NETCOREAPP +#if NET await RunAsCollectionElementTest(JsonNumberTestData.NullableInt128s); await RunAsCollectionElementTest(JsonNumberTestData.NullableUInt128s); await RunAsCollectionElementTest(JsonNumberTestData.NullableHalfs); @@ -781,7 +781,7 @@ public async Task FloatingPointConstants_Pass() async Task PerformFloatingPointSerialization(string testString) { string testStringAsJson = $@"""{testString}"""; -#if NETCOREAPP +#if NET string testJson = @$"{{""HalfNumber"":{testStringAsJson},""FloatNumber"":{testStringAsJson},""DoubleNumber"":{testStringAsJson}}}"; #else string testJson = @$"{{""FloatNumber"":{testStringAsJson},""DoubleNumber"":{testStringAsJson}}}"; @@ -792,14 +792,14 @@ async Task PerformFloatingPointSerialization(string testString) { case "NaN": obj = await Serializer.DeserializeWrapper(testJson, s_optionsAllowFloatConstants); -#if NETCOREAPP +#if NET Assert.Equal(Half.NaN, obj.HalfNumber); #endif Assert.Equal(float.NaN, obj.FloatNumber); Assert.Equal(double.NaN, obj.DoubleNumber); obj = await Serializer.DeserializeWrapper(testJson, s_optionReadFromStr); -#if NETCOREAPP +#if NET Assert.Equal(Half.NaN, obj.HalfNumber); #endif Assert.Equal(float.NaN, obj.FloatNumber); @@ -807,14 +807,14 @@ async Task PerformFloatingPointSerialization(string testString) break; case "Infinity": obj = await Serializer.DeserializeWrapper(testJson, s_optionsAllowFloatConstants); -#if NETCOREAPP +#if NET Assert.Equal(Half.PositiveInfinity, obj.HalfNumber); #endif Assert.Equal(float.PositiveInfinity, obj.FloatNumber); Assert.Equal(double.PositiveInfinity, obj.DoubleNumber); obj = await Serializer.DeserializeWrapper(testJson, s_optionReadFromStr); -#if NETCOREAPP +#if NET Assert.Equal(Half.PositiveInfinity, obj.HalfNumber); #endif Assert.Equal(float.PositiveInfinity, obj.FloatNumber); @@ -822,14 +822,14 @@ async Task PerformFloatingPointSerialization(string testString) break; case "-Infinity": obj = await Serializer.DeserializeWrapper(testJson, s_optionsAllowFloatConstants); -#if NETCOREAPP +#if NET Assert.Equal(Half.NegativeInfinity, obj.HalfNumber); #endif Assert.Equal(float.NegativeInfinity, obj.FloatNumber); Assert.Equal(double.NegativeInfinity, obj.DoubleNumber); obj = await Serializer.DeserializeWrapper(testJson, s_optionReadFromStr); -#if NETCOREAPP +#if NET Assert.Equal(Half.NegativeInfinity, obj.HalfNumber); #endif Assert.Equal(float.NegativeInfinity, obj.FloatNumber); @@ -877,7 +877,7 @@ public async Task FloatingPointConstants_Fail(string testString) { string testStringAsJson = $@"""{testString}"""; string testJson; -#if NETCOREAPP +#if NET testJson = @$"{{""HalfNumber"":{testStringAsJson}}}"; await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(testJson, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(testJson, s_optionReadFromStr)); @@ -894,7 +894,7 @@ public async Task FloatingPointConstants_Fail(string testString) [Fact] public async Task AllowFloatingPointConstants_WriteAsNumber_IfNotConstant() { -#if NETCOREAPP +#if NET Half half = (Half)1; // Not written as "1" Assert.Equal("1", await Serializer.SerializeWrapper(half, s_optionsAllowFloatConstants)); @@ -914,7 +914,7 @@ public async Task AllowFloatingPointConstants_WriteAsNumber_IfNotConstant() [InlineData("-Infinity")] public async Task Unquoted_FloatingPointConstants_Read_Fail(string testString) { -#if NETCOREAPP +#if NET await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(testString, s_optionsAllowFloatConstants)); #endif await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(testString, s_optionsAllowFloatConstants)); @@ -924,7 +924,7 @@ public async Task Unquoted_FloatingPointConstants_Read_Fail(string testString) public struct StructWithNumbers { -#if NETCOREAPP +#if NET public Half HalfNumber { get; set; } #endif public float FloatNumber { get; set; } @@ -985,7 +985,7 @@ public async Task FloatingPointConstants_IncompatibleNumber() await AssertFloatingPointIncompatible_Fails(); await AssertFloatingPointIncompatible_Fails(); await AssertFloatingPointIncompatible_Fails(); -#if NETCOREAPP +#if NET await AssertFloatingPointIncompatible_Fails(); await AssertFloatingPointIncompatible_Fails(); await AssertFloatingPointIncompatible_Fails(); @@ -1031,7 +1031,7 @@ public async Task UnsupportedFormats() await AssertUnsupportedFormatThrows(); await AssertUnsupportedFormatThrows(); await AssertUnsupportedFormatThrows(); -#if NETCOREAPP +#if NET await AssertUnsupportedFormatThrows(); await AssertUnsupportedFormatThrows(); await AssertUnsupportedFormatThrows(); @@ -1058,7 +1058,7 @@ private async Task AssertUnsupportedFormatThrows() } } -#if NETCOREAPP +#if NET [Fact] public async Task InvalidNumberFormatThrows() { @@ -1103,7 +1103,7 @@ public async Task EscapingTest() await PerformEscapingTest(JsonNumberTestData.Floats, options); await PerformEscapingTest(JsonNumberTestData.Doubles, options); await PerformEscapingTest(JsonNumberTestData.Decimals, options); -#if NETCOREAPP +#if NET await PerformEscapingTest(JsonNumberTestData.Int128s, options); await PerformEscapingTest(JsonNumberTestData.UInt128s, options); await PerformEscapingTest(JsonNumberTestData.Halfs, options); @@ -1180,7 +1180,7 @@ public async Task Number_RoundtripNull() await Perform_Number_RoundTripNull_Test(); await Perform_Number_RoundTripNull_Test(); await Perform_Number_RoundTripNull_Test(); -#if NETCOREAPP +#if NET await Perform_Number_RoundTripNull_Test(); await Perform_Number_RoundTripNull_Test(); await Perform_Number_RoundTripNull_Test(); @@ -1210,7 +1210,7 @@ public async Task NullableNumber_RoundtripNull() await Perform_NullableNumber_RoundTripNull_Test(); await Perform_NullableNumber_RoundTripNull_Test(); await Perform_NullableNumber_RoundTripNull_Test(); -#if NETCOREAPP +#if NET await Perform_NullableNumber_RoundTripNull_Test(); await Perform_NullableNumber_RoundTripNull_Test(); await Perform_NullableNumber_RoundTripNull_Test(); @@ -1243,7 +1243,7 @@ public async Task Disallow_ArbritaryStrings_On_AllowFloatingPointConstants() await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); -#if NETCOREAPP +#if NET await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); @@ -1259,7 +1259,7 @@ public async Task Disallow_ArbritaryStrings_On_AllowFloatingPointConstants() await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); -#if NETCOREAPP +#if NET await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); await Assert.ThrowsAsync(async () => await Serializer.DeserializeWrapper(json, s_optionsAllowFloatConstants)); diff --git a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs index 9f8af715fdb8e4..92c12b1dfc44c9 100644 --- a/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/Common/TestClasses/TestClasses.cs @@ -1907,7 +1907,7 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, int value, JsonS public static class ReflectionExtensions { -#if NET6_0_OR_GREATER +#if NET [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public static Type WithConstructors( [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] diff --git a/src/libraries/System.Text.Json/tests/Common/Utf8MemoryStream.cs b/src/libraries/System.Text.Json/tests/Common/Utf8MemoryStream.cs index 2904d744aa949a..c28b5bb6c1127b 100644 --- a/src/libraries/System.Text.Json/tests/Common/Utf8MemoryStream.cs +++ b/src/libraries/System.Text.Json/tests/Common/Utf8MemoryStream.cs @@ -20,7 +20,7 @@ public Utf8MemoryStream(string text) : base(Encoding.UTF8.GetBytes(text)) { } -#if NETCOREAPP +#if NET public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => base.WriteAsync(buffer, _ignoreCancellationTokenOnWriteAsync ? default : cancellationToken); #endif diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs index 182981002b742b..a26c22e1dde2c6 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs @@ -38,7 +38,7 @@ public interface ITestContext public JsonTypeInfo JsonElement { get; } public JsonTypeInfo ClassWithEnumAndNullable { get; } public JsonTypeInfo ClassWithNullableProperties { get; } -#if NETCOREAPP +#if NET public JsonTypeInfo ClassWithDateOnlyAndTimeOnlyValues { get; } #endif public JsonTypeInfo ClassWithCustomConverter { get; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs index 308a6b8a104600..2db01d53c6eba9 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs @@ -34,7 +34,7 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties))] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(RealWorldContextTests.ClassWithDateOnlyAndTimeOnlyValues))] #endif [JsonSerializable(typeof(ClassWithCustomConverter))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs index 10e394518cdf5e..7c99a9f7ec4bbb 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs @@ -33,7 +33,7 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Metadata)] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(RealWorldContextTests.ClassWithDateOnlyAndTimeOnlyValues), GenerationMode = JsonSourceGenerationMode.Metadata)] #endif [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata)] @@ -137,7 +137,7 @@ public override void EnsureFastPathGeneratedAsExpected() [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties))] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(RealWorldContextTests.ClassWithDateOnlyAndTimeOnlyValues))] #endif [JsonSerializable(typeof(ClassWithCustomConverter))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs index 529bd598b6ea25..d2ef2350092be6 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs @@ -34,7 +34,7 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(RealWorldContextTests.ClassWithDateOnlyAndTimeOnlyValues), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] #endif [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs index 00ce5d49d45131..152b716d2aaf16 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs @@ -893,7 +893,7 @@ void RunTest(ClassWithNullableProperties expected) } } -#if NETCOREAPP +#if NET [Fact] public virtual void ClassWithDateOnlyAndTimeOnlyValues_Roundtrip() { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/NumberHandlingTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/NumberHandlingTests.cs index 0fdcf44a0e88ee..9b5ae831bc43aa 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/NumberHandlingTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/NumberHandlingTests.cs @@ -244,7 +244,7 @@ public NumberHandlingTests_Metadata() [JsonSerializable(typeof(List))] [JsonSerializable(typeof(Queue))] [JsonSerializable(typeof(ImmutableList))] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(Int128))] [JsonSerializable(typeof(Int128[]))] [JsonSerializable(typeof(ConcurrentQueue))] @@ -694,7 +694,7 @@ public NumberHandlingTests_Default() [JsonSerializable(typeof(List))] [JsonSerializable(typeof(List))] [JsonSerializable(typeof(List))] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(Int128))] [JsonSerializable(typeof(Int128[]))] [JsonSerializable(typeof(ConcurrentQueue))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs index 162a8b12bd7e74..937117a84b7d1c 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs @@ -35,7 +35,7 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties))] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(RealWorldContextTests.ClassWithDateOnlyAndTimeOnlyValues))] #endif [JsonSerializable(typeof(ClassWithCustomConverter))] @@ -88,7 +88,7 @@ internal partial class SerializationContext : JsonSerializerContext, ITestContex [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Serialization)] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(RealWorldContextTests.ClassWithDateOnlyAndTimeOnlyValues), GenerationMode = JsonSourceGenerationMode.Serialization)] #endif [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] @@ -144,7 +144,7 @@ internal partial class SerializationWithPerTypeAttributeContext : JsonSerializer [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Serialization)] -#if NETCOREAPP +#if NET [JsonSerializable(typeof(RealWorldContextTests.ClassWithDateOnlyAndTimeOnlyValues), GenerationMode = JsonSourceGenerationMode.Serialization)] #endif [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] @@ -482,7 +482,7 @@ void RunTest(ClassWithNullableProperties expected) } } -#if NETCOREAPP +#if NET [Fact] public override void ClassWithDateOnlyAndTimeOnlyValues_Roundtrip() { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs index 09daf5795dab24..7f56065297f171 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs @@ -46,7 +46,7 @@ public static CSharpParseOptions CreateParseOptions( documentationMode: documentationMode ?? DocumentationMode.Parse); } -#if NETCOREAPP +#if NET private static readonly Assembly systemRuntimeAssembly = Assembly.Load(new AssemblyName("System.Runtime")); #endif @@ -68,7 +68,7 @@ public static Compilation CreateCompilation( MetadataReference.CreateFromFile(typeof(GeneratedCodeAttribute).Assembly.Location), MetadataReference.CreateFromFile(typeof(ReadOnlySpan<>).Assembly.Location), MetadataReference.CreateFromFile(typeof(Console).Assembly.Location), -#if NETCOREAPP +#if NET MetadataReference.CreateFromFile(typeof(LinkedList<>).Assembly.Location), MetadataReference.CreateFromFile(systemRuntimeAssembly.Location), #else @@ -94,7 +94,7 @@ public static Compilation CreateCompilation( SyntaxTree[] syntaxTrees = new[] { CSharpSyntaxTree.ParseText(source, parseOptions), -#if !NETCOREAPP +#if !NET CSharpSyntaxTree.ParseText(NetfxPolyfillAttributes, parseOptions), #endif }; @@ -169,7 +169,7 @@ public static byte[] CreateAssemblyImage(Compilation compilation) return ms.ToArray(); } -#if !NETCOREAPP +#if !NET private const string NetfxPolyfillAttributes = """ namespace System.Runtime.CompilerServices { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs index e2f08b988441c0..0143e7dd1c4154 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs @@ -711,7 +711,7 @@ public class NestedGenericClass [InlineData("public ref partial struct MyGenericRefStruct")] [InlineData("public readonly partial struct MyReadOnlyStruct")] [InlineData("public readonly ref partial struct MyReadOnlyRefStruct")] -#if ROSLYN4_0_OR_GREATER && NETCOREAPP +#if ROSLYN4_0_OR_GREATER && NET [InlineData("public partial record MyRecord(int x)", LanguageVersion.CSharp10)] [InlineData("public partial record struct MyRecordStruct(int x)", LanguageVersion.CSharp10)] #endif @@ -771,7 +771,7 @@ internal partial class JsonContext : JsonSerializerContext CompilationHelper.RunJsonSourceGenerator(compilation); } -#if ROSLYN4_4_OR_GREATER && NETCOREAPP +#if ROSLYN4_4_OR_GREATER && NET [Fact] public void ShadowedMemberInitializers() { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/AssemblyInfo.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/AssemblyInfo.cs new file mode 100644 index 00000000000000..68af8051230a6d --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/AssemblyInfo.cs @@ -0,0 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Xunit; + +[assembly: ActiveIssue("Interpreter with debug runtime can be very slow", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter), nameof(PlatformDetection.IsDebugRuntime))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs index ef51703958151c..3b8a7b8c4b6b4e 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonNode/JsonArrayTests.cs @@ -12,6 +12,25 @@ namespace System.Text.Json.Nodes.Tests { public static class JsonArrayTests { + [Fact] + public static void ParamsContructors() + { + JsonArray expectedArray = [41, 42, 43]; + JsonNodeOptions options = new JsonNodeOptions { PropertyNameCaseInsensitive = true }; + + Verify(new JsonArray(new JsonNode[] { 41, 42, 43 }), null); + Verify(new JsonArray((ReadOnlySpan)new JsonNode[] { 41, 42, 43 }), null); + Verify(new JsonArray(options, new JsonNode[] { 41, 42, 43 }), options); + Verify(new JsonArray(options, (ReadOnlySpan)new JsonNode[] { 41, 42, 43 }), options); + + void Verify(JsonArray jsonArray, JsonNodeOptions? expectedOptions) + { + Assert.Equal(expectedArray.Count, jsonArray.Count); + JsonNodeTests.AssertDeepEqual(expectedArray, jsonArray); + Assert.Equal(expectedOptions, jsonArray.Options); + } + } + [Fact] public static void FromElement() { @@ -34,7 +53,7 @@ public static void FromElement() public static void FromElement_WrongNodeTypeThrows(string json) { using (JsonDocument document = JsonDocument.Parse(json)) - Assert.Throws(() => JsonArray.Create(document.RootElement)); + Assert.Throws(() => JsonArray.Create(document.RootElement)); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonTestHelper.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonTestHelper.cs index 3083d0bed99a02..adaff17da693c2 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonTestHelper.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonTestHelper.cs @@ -754,7 +754,7 @@ public static TException AssertThrows(ref Utf8JsonReader json, Asser throw ex is null ? ThrowsException.ForNoException(typeof(TException)) : ThrowsException.ForIncorrectExceptionType(typeof(TException), ex); } -#if NETCOREAPP +#if NET // This is needed due to the fact that git might normalize line endings when checking-out files public static string NormalizeLineEndings(this string value) => value.ReplaceLineEndings(); #else diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.Dynamic.Sample.Tests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.Dynamic.Sample.Tests.cs index 69c53e91e37d37..3eef5a856aee20 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.Dynamic.Sample.Tests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.Dynamic.Sample.Tests.cs @@ -59,7 +59,7 @@ public static void VerifyPrimitives() Assert.IsType(obj); double dbl = (double)obj; -#if !NETCOREAPP +#if !NET string temp = dbl.ToString(System.Globalization.CultureInfo.InvariantCulture); // The reader uses "G17" format which causes temp to be 4.2000000000000002 in this case. dbl = double.Parse(temp, System.Globalization.CultureInfo.InvariantCulture); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/JsonTypeInfoResolverTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/JsonTypeInfoResolverTests.cs index 9136555b0fd9c9..17e1a73c970a00 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/JsonTypeInfoResolverTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/JsonTypeInfoResolverTests.cs @@ -7,32 +7,46 @@ namespace System.Text.Json.Serialization.Tests { - public static partial class JsonTypeInfoResolverTests + public class JsonTypeInfoResolverCombineArrayTests : JsonTypeInfoResolverCombineTests { + public override IJsonTypeInfoResolver Combine(params IJsonTypeInfoResolver?[] resolvers) => + JsonTypeInfoResolver.Combine(resolvers); + [Fact] - public static void CombineNullArgument() + public void CombineNullArgument() { IJsonTypeInfoResolver[] resolvers = null; - Assert.Throws(() => JsonTypeInfoResolver.Combine(resolvers)); + Assert.Throws(() => Combine(resolvers)); } + } + + public class JsonTypeInfoResolverCombineSpanTests : JsonTypeInfoResolverCombineTests + { + public override IJsonTypeInfoResolver Combine(params IJsonTypeInfoResolver?[] resolvers) => + JsonTypeInfoResolver.Combine((ReadOnlySpan)resolvers); + } + + public abstract class JsonTypeInfoResolverCombineTests + { + public abstract IJsonTypeInfoResolver Combine(params IJsonTypeInfoResolver?[] resolvers); [Fact] - public static void Combine_ShouldFlattenResolvers() + public void Combine_ShouldFlattenResolvers() { DefaultJsonTypeInfoResolver nonNullResolver1 = new(); DefaultJsonTypeInfoResolver nonNullResolver2 = new(); DefaultJsonTypeInfoResolver nonNullResolver3 = new(); - ValidateCombinations(Array.Empty(), JsonTypeInfoResolver.Combine()); - ValidateCombinations(Array.Empty(), JsonTypeInfoResolver.Combine(new IJsonTypeInfoResolver[] { null })); - ValidateCombinations(Array.Empty(), JsonTypeInfoResolver.Combine(null, null)); - ValidateCombinations(new[] { nonNullResolver1 }, JsonTypeInfoResolver.Combine(nonNullResolver1, null)); - ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2 }, JsonTypeInfoResolver.Combine(nonNullResolver1, nonNullResolver2, null)); - ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2 }, JsonTypeInfoResolver.Combine(nonNullResolver1, null, nonNullResolver2)); - ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2, nonNullResolver3 }, JsonTypeInfoResolver.Combine(JsonTypeInfoResolver.Combine(JsonTypeInfoResolver.Combine(nonNullResolver1), nonNullResolver2), nonNullResolver3)); - ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2, nonNullResolver3 }, JsonTypeInfoResolver.Combine(JsonTypeInfoResolver.Combine(nonNullResolver1, null, nonNullResolver2), nonNullResolver3)); + ValidateCombinations(Array.Empty(), Combine()); + ValidateCombinations(Array.Empty(), Combine(new IJsonTypeInfoResolver[] { null })); + ValidateCombinations(Array.Empty(), Combine(null, null)); + ValidateCombinations(new[] { nonNullResolver1 }, Combine(nonNullResolver1, null)); + ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2 }, Combine(nonNullResolver1, nonNullResolver2, null)); + ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2 }, Combine(nonNullResolver1, null, nonNullResolver2)); + ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2, nonNullResolver3 }, Combine(Combine(Combine(nonNullResolver1), nonNullResolver2), nonNullResolver3)); + ValidateCombinations(new[] { nonNullResolver1, nonNullResolver2, nonNullResolver3 }, Combine(Combine(nonNullResolver1, null, nonNullResolver2), nonNullResolver3)); - static void ValidateCombinations(IJsonTypeInfoResolver[] expectedResolvers, IJsonTypeInfoResolver combinedResolver) + void ValidateCombinations(IJsonTypeInfoResolver[] expectedResolvers, IJsonTypeInfoResolver combinedResolver) { if (expectedResolvers.Length == 1) { @@ -46,9 +60,9 @@ static void ValidateCombinations(IJsonTypeInfoResolver[] expectedResolvers, IJso } [Fact] - public static void CombiningZeroResolversProducesValidResolver() + public void CombiningZeroResolversProducesValidResolver() { - IJsonTypeInfoResolver resolver = JsonTypeInfoResolver.Combine(); + IJsonTypeInfoResolver resolver = Combine(); Assert.NotNull(resolver); // calling twice to make sure we get the same answer @@ -57,7 +71,7 @@ public static void CombiningZeroResolversProducesValidResolver() } [Fact] - public static void CombiningSingleResolverProducesSameAnswersAsInputResolver() + public void CombiningSingleResolverProducesSameAnswersAsInputResolver() { JsonSerializerOptions options = new(); JsonTypeInfo t1 = JsonTypeInfo.CreateJsonTypeInfo(typeof(int), options); @@ -74,7 +88,7 @@ public static void CombiningSingleResolverProducesSameAnswersAsInputResolver() return null; }); - IJsonTypeInfoResolver combined = JsonTypeInfoResolver.Combine(resolver); + IJsonTypeInfoResolver combined = Combine(resolver); Assert.Same(t1, combined.GetTypeInfo(typeof(int), options)); Assert.Same(t2, combined.GetTypeInfo(typeof(uint), options)); @@ -84,7 +98,7 @@ public static void CombiningSingleResolverProducesSameAnswersAsInputResolver() } [Fact] - public static void CombiningUsesAndRespectsAllResolversInOrder() + public void CombiningUsesAndRespectsAllResolversInOrder() { JsonSerializerOptions options = new(); JsonTypeInfo t1 = JsonTypeInfo.CreateJsonTypeInfo(typeof(int), options); @@ -121,7 +135,7 @@ public static void CombiningUsesAndRespectsAllResolversInOrder() return null; }); - IJsonTypeInfoResolver combined = JsonTypeInfoResolver.Combine(r1, r2, r3); + IJsonTypeInfoResolver combined = Combine(r1, r2, r3); resolverId = 1; Assert.Same(t1, combined.GetTypeInfo(typeof(int), options)); @@ -144,7 +158,7 @@ public static void CombiningUsesAndRespectsAllResolversInOrder() Assert.Equal(4, resolverId); } - private static IList GetAndValidateCombinedResolvers(IJsonTypeInfoResolver resolver) + private IList GetAndValidateCombinedResolvers(IJsonTypeInfoResolver resolver) { var list = (IList)resolver; @@ -155,8 +169,12 @@ private static IList GetAndValidateCombinedResolvers(IJso return list; } + } + + public class JsonTypeInfoResolverTests + { [Fact] - public static void WithAddedModifier_CallsModifierOnResolvedMetadata() + public void WithAddedModifier_CallsModifierOnResolvedMetadata() { int modifierInvocationCount = 0; JsonSerializerOptions options = new(); @@ -175,11 +193,11 @@ public static void WithAddedModifier_CallsModifierOnResolvedMetadata() } [Fact] - public static void WithAddedModifier_DoesNotCallModifierOnUnResolvedMetadata() + public void WithAddedModifier_DoesNotCallModifierOnUnResolvedMetadata() { int modifierInvocationCount = 0; JsonSerializerOptions options = new(); - TestResolver resolver = new((_,_) => null); + TestResolver resolver = new((_, _) => null); IJsonTypeInfoResolver resolverWithModifier = resolver.WithAddedModifier(_ => modifierInvocationCount++); @@ -191,7 +209,7 @@ public static void WithAddedModifier_DoesNotCallModifierOnUnResolvedMetadata() } [Fact] - public static void WithAddedModifier_CanChainMultipleModifiers() + public void WithAddedModifier_CanChainMultipleModifiers() { int modifier1InvocationCount = 0; int modifier2InvocationCount = 0; @@ -208,7 +226,7 @@ public static void WithAddedModifier_CanChainMultipleModifiers() } [Fact] - public static void WithAddedModifier_ChainingDoesNotMutateIntermediateResolvers() + public void WithAddedModifier_ChainingDoesNotMutateIntermediateResolvers() { int modifier1InvocationCount = 0; int modifier2InvocationCount = 0; @@ -233,7 +251,7 @@ public static void WithAddedModifier_ChainingDoesNotMutateIntermediateResolvers( } [Fact] - public static void WithAddedModifier_ThrowsOnNullArguments() + public void WithAddedModifier_ThrowsOnNullArguments() { TestResolver resolver = new(JsonTypeInfo.CreateJsonTypeInfo); @@ -242,7 +260,7 @@ public static void WithAddedModifier_ThrowsOnNullArguments() } [Fact] - public static void NullResolver_ReturnsObjectMetadata() + public void NullResolver_ReturnsObjectMetadata() { var options = new JsonSerializerOptions(); var resolver = new NullResolver(); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.ReadTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.ReadTests.cs index 437acca92b09b2..b080c282911e22 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.ReadTests.cs @@ -391,7 +391,7 @@ public static void ReadPrimitiveUri() private static int SingleToInt32Bits(float value) { -#if NETCOREAPP +#if NET return BitConverter.SingleToInt32Bits(value); #else return Unsafe.As(ref value); @@ -470,7 +470,7 @@ private static void DeserializeLongJsonString(int stringLength) string json; char fillChar = 'x'; -#if NETCOREAPP +#if NET json = string.Create(stringLength, fillChar, (chars, fillChar) => { chars.Fill(fillChar); @@ -566,7 +566,7 @@ public static void TimeSpan_Read_Failure(string json, bool addQuotes = true) Assert.Throws(() => JsonSerializer.Deserialize(json)); } -#if NETCOREAPP +#if NET [Theory] [InlineData("1970-01-01")] [InlineData("2002-02-13")] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.WriteTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.WriteTests.cs index af83df3f9696d6..a59e7dc9170334 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Value.WriteTests.cs @@ -148,7 +148,7 @@ public static void TimeSpan_Write_Success(string value, string? expectedValue = Assert.Equal(json, JsonConvert.SerializeObject(ts)); } -#if NETCOREAPP +#if NET [Theory] [InlineData("1970-01-01")] [InlineData("2002-02-13")] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj index cada80f5cee613..9eb2e9a2e63d78 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj @@ -31,6 +31,7 @@ + @@ -306,6 +307,7 @@ - + + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/TrimmingTests/System.Text.Json.TrimmingTests.proj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/TrimmingTests/System.Text.Json.TrimmingTests.proj index 6d9885fed2a91a..37188a8dce70d6 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/TrimmingTests/System.Text.Json.TrimmingTests.proj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/TrimmingTests/System.Text.Json.TrimmingTests.proj @@ -1,7 +1,9 @@ - + + Helper.cs diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs index 7ccda56d737a2a..4515e69412d3f3 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs @@ -3069,7 +3069,7 @@ public void WritingHugeBase64Bytes(JsonWriterOptions options) } // https://github.com/dotnet/runtime/issues/30746 - [Theory] + [Theory, OuterLoop("Very long running test")] [MemberData(nameof(JsonOptions_TestData))] [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/45464", ~RuntimeConfiguration.Release)] public void Writing3MBBase64Bytes(JsonWriterOptions options) @@ -4421,6 +4421,7 @@ public void EscapeAsciiCharacters(JsonWriterOptions options) [Theory] [MemberData(nameof(JsonOptions_TestData))] + [OuterLoop("Too slow", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime))] public void EscapeCharacters(JsonWriterOptions options) { // Do not include surrogate pairs. @@ -5303,6 +5304,7 @@ public void WriteDoubleValue(JsonWriterOptions options, double value) [Theory] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] [MemberData(nameof(WriteValue_TestData))] + [OuterLoop("Too slow", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime))] public void WriteNumbers(JsonWriterOptions options, string keyString) { var random = new Random(42); @@ -7634,7 +7636,7 @@ private static IEnumerable JsonOptions() return from indented in new[] { true, false } from skipValidation in new[] { true, false } from indentCharacter in indented ? new char?[] { null, ' ', '\t' } : [] - from indentSize in indented ? new int?[] { null, 0, 1, 2, 127 } : [] + from indentSize in indented ? new int?[] { null, 0, 1, 2, 3 } : [] from newLine in indented ? new string?[] { null, "\n", "\r\n" } : [] select CreateOptions(indented, indentCharacter, indentSize, skipValidation, newLine); diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs index b2ab52c4c71fac..486371fd3e0b76 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs @@ -5405,7 +5405,7 @@ private static string GetSHA256FieldName(string prefix, string toEncode) { #pragma warning disable CA1850 // SHA256.HashData isn't available on netstandard2.0 using SHA256 sha = SHA256.Create(); - return $"{prefix}{ToHexStringNoDashes(Encoding.UTF8.GetBytes(toEncode))}"; + return $"{prefix}{ToHexStringNoDashes(sha.ComputeHash(Encoding.UTF8.GetBytes(toEncode)))}"; #pragma warning restore CA1850 } @@ -5602,7 +5602,7 @@ private static string DescribeLoop(RegexNode node, RegexMethod rm) } private static string ToHexStringNoDashes(byte[] bytes) => -#if NETCOREAPP +#if NET Convert.ToHexString(bytes); #else BitConverter.ToString(bytes).Replace("-", ""); diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs index 5666498347e468..3c24bdc78ad06f 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs @@ -563,7 +563,7 @@ public static string ConvertOldStringsToClass(string set, string category) } return -#if NETCOREAPP2_1_OR_GREATER +#if NET string #else StringExtensions @@ -1304,7 +1304,7 @@ static bool InitializeValue(char ch, string set, ref uint[]? asciiLazyCache) } uint[]? cache = asciiLazyCache ?? Interlocked.CompareExchange(ref asciiLazyCache, new uint[CacheArrayLength], null) ?? asciiLazyCache; -#if NET5_0_OR_GREATER +#if NET Interlocked #else InterlockedExtensions @@ -1594,7 +1594,7 @@ internal static unsafe string CharsToStringClass(ReadOnlySpan chars) #pragma warning disable CS8500 // takes address of managed type ReadOnlySpan tmpChars = chars; // avoid address exposing the span and impacting the other code in the method that uses it return -#if NETCOREAPP2_1_OR_GREATER +#if NET string #else StringExtensions diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs index 926a28339162f6..556a187203f035 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexPrefixAnalyzer.cs @@ -59,9 +59,11 @@ static bool FindPrefixesCore(RegexNode node, List results, bool i // If we're too deep to analyze further, we can't trust what we've already computed, so stop iterating. // Also bail if any of our results is already hitting the threshold, or if this node is RTL, which is // not worth the complexity of handling. + // Or if we've already discovered more than the allowed number of prefixes. if (!StackHelper.TryEnsureSufficientExecutionStack() || !results.TrueForAll(sb => sb.Length < MaxPrefixLength) || - (node.Options & RegexOptions.RightToLeft) != 0) + (node.Options & RegexOptions.RightToLeft) != 0 || + results.Count > MaxPrefixes) { return false; } @@ -162,23 +164,30 @@ static bool FindPrefixesCore(RegexNode node, List results, bool i int reps = node.Kind is RegexNodeKind.Set ? 1 : Math.Min(node.M, MaxPrefixLength); if (!ignoreCase) { - int existingCount = results.Count; - - // Duplicate all of the existing strings for all of the new suffixes, other than the first. - foreach (char suffix in setChars.Slice(1, charCount - 1)) + for (int rep = 0; rep < reps; rep++) { - for (int existing = 0; existing < existingCount; existing++) + int existingCount = results.Count; + if (existingCount * charCount > MaxPrefixes) { - StringBuilder newSb = new StringBuilder().Append(results[existing]); - newSb.Append(suffix, reps); - results.Add(newSb); + return false; } - } - // Then append the first suffix to all of the existing strings. - for (int existing = 0; existing < existingCount; existing++) - { - results[existing].Append(setChars[0], reps); + // Duplicate all of the existing strings for all of the new suffixes, other than the first. + foreach (char suffix in setChars.Slice(1, charCount - 1)) + { + for (int existing = 0; existing < existingCount; existing++) + { + StringBuilder newSb = new StringBuilder().Append(results[existing]); + newSb.Append(suffix); + results.Add(newSb); + } + } + + // Then append the first suffix to all of the existing strings. + for (int existing = 0; existing < existingCount; existing++) + { + results[existing].Append(setChars[0]); + } } } else @@ -248,6 +257,12 @@ static bool FindPrefixesCore(RegexNode node, List results, bool i { _ = FindPrefixesCore(node.Child(i), alternateBranchResults, ignoreCase); + // If we now have too many results, bail. + if ((allBranchResults?.Count ?? 0) + alternateBranchResults.Count > MaxPrefixes) + { + return false; + } + Debug.Assert(alternateBranchResults.Count > 0); foreach (StringBuilder sb in alternateBranchResults) { @@ -359,7 +374,7 @@ static bool Process(RegexNode node, ref ValueStringBuilder vsb) } // Alternation: find a string that's a shared prefix of all branches - case RegexNodeKind.Alternate: + case RegexNodeKind.Alternate when !rtl: // for RTL we'd need to be matching the suffixes of the alternation cases { int childCount = node.ChildCount(); diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexWriter.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexWriter.cs index 5284c09339bd7b..4d779d4f48f127 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexWriter.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexWriter.cs @@ -177,7 +177,7 @@ private void Emit(RegexOpcode op, int opd1, int opd2) /// private int StringCode(string str) { -#if NET6_0_OR_GREATER +#if NET ref int i = ref CollectionsMarshal.GetValueRefOrAddDefault(_stringTable, str, out bool exists); if (!exists) { diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexNode.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexNode.cs index b20564cee32a1c..a138c819be00fa 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexNode.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexNode.cs @@ -243,7 +243,7 @@ bool WithCache(uint context) Debug.Assert(context < CharKind.ContextLimit); - // If nullablity has been computed for the given context then return it + // If nullability has been computed for the given context then return it byte b = Volatile.Read(ref _nullabilityCache[context]); if (b != UndefinedByte) { diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs index 27d8f18298a0bd..6ad4f5a526c4be 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/UnicodeCategoryConditions.cs @@ -33,7 +33,7 @@ static UnicodeCategoryConditions() /// Gets a that represents the specified . public static BDD GetCategory(UnicodeCategory category) => - Volatile.Read(ref s_categories[(int)category]) ?? + s_categories[(int)category] ?? Interlocked.CompareExchange(ref s_categories[(int)category], BDD.Deserialize(UnicodeCategoryRanges.GetSerializedCategory(category)), null) ?? s_categories[(int)category]!; diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Threading/StackHelper.cs b/src/libraries/System.Text.RegularExpressions/src/System/Threading/StackHelper.cs index c338c2bb73e95c..ded50c662ea4a4 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Threading/StackHelper.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Threading/StackHelper.cs @@ -12,7 +12,7 @@ internal static class StackHelper /// Tries to ensure there is sufficient stack to execute the average .NET function. public static bool TryEnsureSufficientExecutionStack() { -#if NETCOREAPP2_0_OR_GREATER +#if NET return RuntimeHelpers.TryEnsureSufficientExecutionStack(); #else try diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.CompileToAssembly.Tests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.CompileToAssembly.Tests.cs index a669f65bd023ed..c1d17ffa6a3ae5 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.CompileToAssembly.Tests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.CompileToAssembly.Tests.cs @@ -14,63 +14,62 @@ namespace System.Text.RegularExpressions.Tests [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] public class RegexCompileToAssemblyTests : FileCleanupTestBase { - public static bool IsDebug => typeof(Regex).Assembly.GetCustomAttributes(false).OfType().Any(da => da.IsJITTrackingEnabled); - public static bool IsRelease => !IsDebug; - public static bool IsDebugAndRemoteExecutorSupported => IsDebug && RemoteExecutor.IsSupported; - - [ConditionalFact(nameof(IsRelease))] - public void CompileToAssembly_PNSE() + [Fact] + public void CompileToAssembly_SimpleTest() { - Assert.Throws(() => Regex.CompileToAssembly(null, null)); - Assert.Throws(() => Regex.CompileToAssembly(null, null, null)); - Assert.Throws(() => Regex.CompileToAssembly(null, null, null, null)); + bool isDebug = typeof(Regex).Assembly.GetCustomAttributes(false).OfType().Any(da => da.IsJITTrackingEnabled); - Assert.Throws(() => Regex.CompileToAssembly( - [new RegexCompilationInfo("abcd", RegexOptions.None, "abcd", "SomeNamespace", true)], - new AssemblyName("abcd"))); + if (!isDebug) + { + Assert.Throws(() => Regex.CompileToAssembly(null, null)); + Assert.Throws(() => Regex.CompileToAssembly(null, null, null)); + Assert.Throws(() => Regex.CompileToAssembly(null, null, null, null)); - Assert.Throws(() => Regex.CompileToAssembly( - [new RegexCompilationInfo("abcd", RegexOptions.None, "abcd", "SomeNamespace", true)], - new AssemblyName("abcd"), - [new CustomAttributeBuilder(typeof(AssemblyCompanyAttribute).GetConstructor([typeof(string)]), new[] { "TestCompany" })])); + Assert.Throws(() => Regex.CompileToAssembly( + [new RegexCompilationInfo("abcd", RegexOptions.None, "abcd", "SomeNamespace", true)], + new AssemblyName("abcd"))); - Assert.Throws(() => Regex.CompileToAssembly( - [new RegexCompilationInfo("abcd", RegexOptions.None, "abcd", "SomeNamespace", true)], - new AssemblyName("abcd"), - [new CustomAttributeBuilder(typeof(AssemblyCompanyAttribute).GetConstructor([typeof(string)]), new[] { "TestCompany" })], - "resourceFile")); - } + Assert.Throws(() => Regex.CompileToAssembly( + [new RegexCompilationInfo("abcd", RegexOptions.None, "abcd", "SomeNamespace", true)], + new AssemblyName("abcd"), + [new CustomAttributeBuilder(typeof(AssemblyCompanyAttribute).GetConstructor([typeof(string)]), new[] { "TestCompany" })])); - [ConditionalFact(nameof(IsDebugAndRemoteExecutorSupported))] - public void CompileToAssembly_SimpleUseInDebug() - { - RemoteExecutor.Invoke(() => + Assert.Throws(() => Regex.CompileToAssembly( + [new RegexCompilationInfo("abcd", RegexOptions.None, "abcd", "SomeNamespace", true)], + new AssemblyName("abcd"), + [new CustomAttributeBuilder(typeof(AssemblyCompanyAttribute).GetConstructor([typeof(string)]), new[] { "TestCompany" })], + "resourceFile")); + } + else if (RemoteExecutor.IsSupported) { - (RegexCompilationInfo rci, string validInput, string invalidInput)[] regexes = - [ - (new RegexCompilationInfo("abcd", RegexOptions.None, "Type1", "Namespace1", ispublic: true), "123abcd123", "123abed123"), - (new RegexCompilationInfo("(a|b|cde)+", RegexOptions.None, "Type2", "Namespace2.Sub", ispublic: true), "abcde", "cd"), - ]; + RemoteExecutor.Invoke(() => + { + (RegexCompilationInfo rci, string validInput, string invalidInput)[] regexes = + [ + (new RegexCompilationInfo("abcd", RegexOptions.None, "Type1", "Namespace1", ispublic: true), "123abcd123", "123abed123"), + (new RegexCompilationInfo("(a|b|cde)+", RegexOptions.None, "Type2", "Namespace2.Sub", ispublic: true), "abcde", "cd"), + ]; - string assemblyName = Path.GetRandomFileName(); + string assemblyName = Path.GetRandomFileName(); - string cwd = Environment.CurrentDirectory; - Environment.CurrentDirectory = TestDirectory; - try - { - Regex.CompileToAssembly(regexes.Select(r => r.rci).ToArray(), new AssemblyName(assemblyName)); - } - finally - { - Environment.CurrentDirectory = cwd; - } + string cwd = Environment.CurrentDirectory; + Environment.CurrentDirectory = TestDirectory; + try + { + Regex.CompileToAssembly(regexes.Select(r => r.rci).ToArray(), new AssemblyName(assemblyName)); + } + finally + { + Environment.CurrentDirectory = cwd; + } - string assemblyPath = Path.Combine(TestDirectory, assemblyName + ".dll"); - Assert.True(File.Exists(assemblyPath)); + string assemblyPath = Path.Combine(TestDirectory, assemblyName + ".dll"); + Assert.True(File.Exists(assemblyPath)); - // Uncomment to save the assembly to the desktop for inspection: - // File.Copy(assemblyPath, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), Path.GetFileName(assemblyPath))); - }).Dispose(); + // Uncomment to save the assembly to the desktop for inspection: + // File.Copy(assemblyPath, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), Path.GetFileName(assemblyPath))); + }).Dispose(); + } } } } diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.KnownPattern.Tests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.KnownPattern.Tests.cs index 5748fd8df3c2e5..e7fe42f1cb1658 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.KnownPattern.Tests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.KnownPattern.Tests.cs @@ -1526,7 +1526,7 @@ other is not null && (Options & ~RegexOptions.Compiled) == (other.Options & ~RegexOptions.Compiled); // Compiled doesn't affect semantics, so remove it from equality for our purposes } -#if NETCOREAPP +#if NET [OuterLoop("Takes many seconds")] [Fact] public async Task PatternsDataSet_ConstructRegexForAll_NonBacktracking() diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs index 1b06272fba64ab..234b416a9b46de 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Match.Tests.cs @@ -698,6 +698,11 @@ public static IEnumerable Match_MemberData() yield return (@"(...)(?(1)\w*|\s*)[a1 ]", "zabcaaaaaaa", RegexOptions.RightToLeft, 0, 11, true, "aaaa"); yield return (@"(...)(?(1)\w*|\s*)[a1 ]", "---- ", RegexOptions.RightToLeft, 0, 11, true, "--- "); yield return (@"(aaa)(?(1)aaa|b?)*", "aaaaaa", RegexOptions.None, 0, 6, true, "aaaaaa"); + + yield return (@"AAB|AAC", "AABAACD", RegexOptions.RightToLeft, 0, 6, true, "AAC"); + yield return (@"AAB|AA\d", "AABAACD", RegexOptions.RightToLeft, 0, 6, true, "AAB"); + yield return (@"(AB){3,}", "1234ABABABAB5678", RegexOptions.RightToLeft, 0, 16, true, "ABABABAB"); + yield return (@"(AB){1,3}", "1234ABABABAB5678", RegexOptions.RightToLeft, 0, 16, true, "ABABAB"); } // Character Class Subtraction @@ -1167,6 +1172,7 @@ public async Task Match_VaryingLengthStrings_Huge(RegexEngine engine) public static IEnumerable Match_DeepNesting_MemberData() { + foreach (RegexOptions options in new[] { RegexOptions.None, RegexOptions.IgnoreCase }) foreach (RegexEngine engine in RegexHelpers.AvailableEngines) { if (RegexHelpers.IsNonBacktracking(engine)) @@ -1175,15 +1181,15 @@ public static IEnumerable Match_DeepNesting_MemberData() continue; } - yield return new object[] { engine, 1 }; - yield return new object[] { engine, 10 }; - yield return new object[] { engine, 100 }; + yield return new object[] { engine, options, 1 }; + yield return new object[] { engine, options, 10 }; + yield return new object[] { engine, options, 100 }; } } [Theory] [MemberData(nameof(Match_DeepNesting_MemberData))] - public async Task Match_DeepNesting(RegexEngine engine, int count) + public async Task Match_DeepNesting(RegexEngine engine, RegexOptions options, int count) { const string Start = @"((?>abc|(?:def[ghi]", End = @")))"; const string Match = "defg"; @@ -1191,7 +1197,7 @@ public async Task Match_DeepNesting(RegexEngine engine, int count) string pattern = string.Concat(Enumerable.Repeat(Start, count)) + string.Concat(Enumerable.Repeat(End, count)); string input = string.Concat(Enumerable.Repeat(Match, count)); - Regex r = await RegexHelpers.GetRegexAsync(engine, pattern); + Regex r = await RegexHelpers.GetRegexAsync(engine, pattern, options); Match m = r.Match(input); Assert.True(m.Success); @@ -1321,7 +1327,7 @@ public void Match_InstanceMethods_DefaultTimeout_Throws(RegexEngine engine) }, ((int)engine).ToString(CultureInfo.InvariantCulture)).Dispose(); } -#if NET7_0_OR_GREATER +#if NET [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public void Match_InstanceMethods_DefaultTimeout_SourceGenerated_Throws() { @@ -1879,7 +1885,7 @@ public async Task Match_StartatDiffersFromBeginning(RegexEngine engine, string p Regex r = await RegexHelpers.GetRegexAsync(engine, pattern, options); Assert.Equal(expectedSuccessStartAt, r.IsMatch(input, startat)); -#if NET7_0_OR_GREATER +#if NET Assert.Equal(expectedSuccessStartAt, r.IsMatch(input.AsSpan(), startat)); #endif @@ -2063,7 +2069,7 @@ public async Task TestCharIsLowerCultureEdgeCasesAroundTurkishCharacters(RegexEn Regex r1 = await RegexHelpers.GetRegexAsync(engine, "[\u012F-\u0130]", RegexOptions.IgnoreCase); Regex r2 = await RegexHelpers.GetRegexAsync(engine, "[\u012F\u0130]", RegexOptions.IgnoreCase); Assert.Equal(r1.IsMatch("\u0130"), r2.IsMatch("\u0130")); -#if NET7_0_OR_GREATER +#if NET Assert.Equal(r1.IsMatch("\u0130".AsSpan()), r2.IsMatch("\u0130".AsSpan())); #endif @@ -2485,14 +2491,14 @@ private static void VerifyIsMatchThrows(Regex? r, string input, TimeSpan time if (r == null) { Assert.Throws(() => timeout == Regex.InfiniteMatchTimeout ? Regex.IsMatch(input, pattern, options) : Regex.IsMatch(input, pattern, options, timeout)); -#if NET7_0_OR_GREATER +#if NET Assert.Throws(() => timeout == Regex.InfiniteMatchTimeout ? Regex.IsMatch(input.AsSpan(), pattern, options) : Regex.IsMatch(input.AsSpan(), pattern, options, timeout)); #endif } else { Assert.Throws(() => r.IsMatch(input)); -#if NET7_0_OR_GREATER +#if NET Assert.Throws(() => r.IsMatch(input.AsSpan())); #endif } @@ -2507,7 +2513,7 @@ private static void VerifyIsMatch(Regex? r, string input, bool expected, TimeSpa { Assert.Equal(expected, Regex.IsMatch(input, pattern)); } -#if NET7_0_OR_GREATER +#if NET Assert.Equal(expected, timeout == Regex.InfiniteMatchTimeout ? Regex.IsMatch(input.AsSpan(), pattern, options) : Regex.IsMatch(input.AsSpan(), pattern, options, timeout)); if (options == RegexOptions.None) { @@ -2518,7 +2524,7 @@ private static void VerifyIsMatch(Regex? r, string input, bool expected, TimeSpa else { Assert.Equal(expected, r.IsMatch(input)); -#if NET7_0_OR_GREATER +#if NET Assert.Equal(expected, r.IsMatch(input.AsSpan())); #endif } diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Tests.Common.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Tests.Common.cs index 4d4f2252839ae5..b0a9b6549492bc 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Tests.Common.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/Regex.Tests.Common.cs @@ -187,7 +187,7 @@ public static async Task GetRegexesAsync(RegexEngine engine, params (st /// Set the AppContext variable REGEX_NONBACKTRACKING_MAX_AUTOMATA_SIZE to the given max value. Only used with Nonbacktracking engine. public static void SetSafeSizeThreshold(int maxSize) { -#if NET7_0_OR_GREATER +#if NET AppContext.SetData("REGEX_NONBACKTRACKING_MAX_AUTOMATA_SIZE", maxSize); #endif } @@ -195,7 +195,7 @@ public static void SetSafeSizeThreshold(int maxSize) /// Remove the AppContext variable REGEX_NONBACKTRACKING_MAX_AUTOMATA_SIZE value. Only used with Nonbacktracking engine. public static void RestoreSafeSizeThresholdToDefault() { -#if NET7_0_OR_GREATER +#if NET AppContext.SetData("REGEX_NONBACKTRACKING_MAX_AUTOMATA_SIZE", null); #endif } diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexRunnerTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexRunnerTests.cs index d4cd665e5b1af9..0f5799687011cd 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexRunnerTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexRunnerTests.cs @@ -50,7 +50,7 @@ public async Task EnsureRunmatchValueIsNulledAfterIsMatch(RegexEngine engine) MethodInfo getTextMethod = typeof(Match).GetMethod("get_Text", BindingFlags.Instance | BindingFlags.NonPublic); Assert.Null(getTextMethod.Invoke(runmatch, [])); Assert.Equal(string.Empty, runmatch.Value); -#if NET7_0_OR_GREATER +#if NET Assert.True(runmatch.ValueSpan == ReadOnlySpan.Empty); #endif } diff --git a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs index c962bc072b6fd7..4c0b02b266142e 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/RegexFindOptimizationsTests.cs @@ -88,7 +88,6 @@ public void TrailingAnchor(string pattern, int options, int expectedMode, int ex [InlineData(@"(ab){2,4}(de){4,}", 0, (int)FindNextStartingPositionMode.LeadingString_LeftToRight, "abab")] [InlineData(@"(ab){2,4}(de){4,}", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingString_RightToLeft, "de")] [InlineData(@"ab|(abc)|(abcd)", 0, (int)FindNextStartingPositionMode.LeadingString_LeftToRight, "ab")] - [InlineData(@"ab|(abc)|(abcd)", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingString_RightToLeft, "ab")] [InlineData(@"ab(?=cd)", 0, (int)FindNextStartingPositionMode.LeadingString_LeftToRight, "ab")] [InlineData(@"ab(?=cd)", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingString_RightToLeft, "ab")] [InlineData(@"\bab(?=\w)(?!=\d)c\b", 0, (int)FindNextStartingPositionMode.LeadingString_LeftToRight, "abc")] @@ -110,6 +109,7 @@ public void LeadingPrefix(string pattern, int options, int expectedMode, string [InlineData(@"a", (int)RegexOptions.IgnoreCase | (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingSet_RightToLeft, "Aa")] [InlineData(@"ab|cd|ef|gh", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingSet_RightToLeft, "bdfh")] [InlineData(@"\bab(?=\w)(?!=\d)c\b", (int)(RegexOptions.IgnoreCase | RegexOptions.RightToLeft), (int)FindNextStartingPositionMode.LeadingSet_RightToLeft, "Cc")] + [InlineData(@"ab|(abc)|(abcd)", (int)RegexOptions.RightToLeft, (int)FindNextStartingPositionMode.LeadingSet_RightToLeft, "bcd")] public void LeadingSet(string pattern, int options, int expectedMode, string expectedChars) { RegexFindOptimizations opts = ComputeOptimizations(pattern, (RegexOptions)options); diff --git a/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj b/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj index 21e101ecd6d94e..a5030bcee65616 100644 --- a/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj +++ b/src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj @@ -25,6 +25,7 @@ System.Threading.Channel<T> + @@ -44,12 +45,12 @@ System.Threading.Channel<T> - + diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.cs index 317636579a05fd..834d8ad88ed1d7 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.cs @@ -1,6 +1,10 @@ // 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.Concurrent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + namespace System.Threading.Channels { /// Provides static methods for creating channels. @@ -9,7 +13,7 @@ public static partial class Channel /// Creates an unbounded channel usable by any number of readers and writers concurrently. /// The created channel. public static Channel CreateUnbounded() => - new UnboundedChannel(runContinuationsAsynchronously: true); + new UnboundedChannel>(new(new()), runContinuationsAsynchronously: true); /// Creates an unbounded channel subject to the provided options. /// Specifies the type of data in the channel. @@ -27,7 +31,7 @@ public static Channel CreateUnbounded(UnboundedChannelOptions options) return new SingleConsumerUnboundedChannel(!options.AllowSynchronousContinuations); } - return new UnboundedChannel(!options.AllowSynchronousContinuations); + return new UnboundedChannel>(new(new()), !options.AllowSynchronousContinuations); } /// Creates a channel with the specified maximum capacity. @@ -71,5 +75,32 @@ public static Channel CreateBounded(BoundedChannelOptions options, Action< return new BoundedChannel(options.Capacity, options.FullMode, !options.AllowSynchronousContinuations, itemDropped); } + + /// Provides an for a . + private readonly struct UnboundedChannelConcurrentQueue(ConcurrentQueue queue) : IUnboundedChannelQueue + { + private readonly ConcurrentQueue _queue = queue; + + /// + public bool IsThreadSafe => true; + + /// + public void Enqueue(T item) => _queue.Enqueue(item); + + /// + public bool TryDequeue([MaybeNullWhen(false)] out T item) => _queue.TryDequeue(out item); + + /// + public bool TryPeek([MaybeNullWhen(false)] out T item) => _queue.TryPeek(out item); + + /// + public int Count => _queue.Count; + + /// + public bool IsEmpty => _queue.IsEmpty; + + /// + public IEnumerator GetEnumerator() => _queue.GetEnumerator(); + } } } diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.netcoreapp.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.netcoreapp.cs index 6c24b3e41ec7b5..c8fc9baebae7db 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.netcoreapp.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/Channel.netcoreapp.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Threading.Channels { @@ -9,13 +10,14 @@ namespace System.Threading.Channels public static partial class Channel { /// Creates an unbounded prioritized channel usable by any number of readers and writers concurrently. + /// Specifies the type of data in the channel. /// The created channel. /// /// is used to determine priority of elements. /// The next item read from the channel will be the element available in the channel with the lowest priority value. /// public static Channel CreateUnboundedPrioritized() => - new UnboundedPrioritizedChannel(runContinuationsAsynchronously: true, comparer: null); + new UnboundedChannel>(new(new()), runContinuationsAsynchronously: true); /// Creates an unbounded prioritized channel subject to the provided options. /// Specifies the type of data in the channel. @@ -30,7 +32,45 @@ public static Channel CreateUnboundedPrioritized(UnboundedPrioritizedChann { ArgumentNullException.ThrowIfNull(options); - return new UnboundedPrioritizedChannel(!options.AllowSynchronousContinuations, options.Comparer); + return new UnboundedChannel>(new(new(options.Comparer)), !options.AllowSynchronousContinuations); + } + + /// Provides an for a . + private readonly struct UnboundedChannelPriorityQueue(PriorityQueue queue) : IUnboundedChannelQueue + { + private readonly PriorityQueue _queue = queue; + + /// + public bool IsThreadSafe => false; + + /// + public void Enqueue(T item) => _queue.Enqueue(true, item); + + /// + public bool TryDequeue([MaybeNullWhen(false)] out T item) => _queue.TryDequeue(out _, out item); + + /// + public bool TryPeek([MaybeNullWhen(false)] out T item) => _queue.TryPeek(out _, out item); + + /// + public int Count => _queue.Count; + + /// + public bool IsEmpty => _queue.Count == 0; + + /// + public IEnumerator GetEnumerator() + { + List list = []; + foreach ((bool _, T Priority) item in _queue.UnorderedItems) + { + list.Add(item.Priority); + } + + list.Sort(_queue.Comparer); + + return list.GetEnumerator(); + } } } } diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/IDebugEnumerator.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/IDebugEnumerator.cs index a3d072ee9f7cb4..af2a77bb1bf775 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/IDebugEnumerator.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/IDebugEnumerator.cs @@ -11,7 +11,7 @@ internal interface IDebugEnumerable IEnumerator GetEnumerator(); } - internal sealed class DebugEnumeratorDebugView + internal class DebugEnumeratorDebugView { public DebugEnumeratorDebugView(IDebugEnumerable enumerable) { @@ -26,4 +26,6 @@ public DebugEnumeratorDebugView(IDebugEnumerable enumerable) [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public T[] Items { get; } } + + internal sealed class DebugEnumeratorDebugView(IDebugEnumerable enumerable) : DebugEnumeratorDebugView(enumerable); } diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/IUnboundedChannelQueue.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/IUnboundedChannelQueue.cs new file mode 100644 index 00000000000000..b1b65a1dffeb10 --- /dev/null +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/IUnboundedChannelQueue.cs @@ -0,0 +1,35 @@ +// 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.Diagnostics.CodeAnalysis; + +namespace System.Threading.Channels +{ + /// Representation of the queue data structure used by . + internal interface IUnboundedChannelQueue : IDebugEnumerable + { + /// Gets whether the other members are safe to use concurrently with each other and themselves. + bool IsThreadSafe { get; } + + /// Enqueues an item into the queue. + /// The item to enqueue. + void Enqueue(T item); + + /// Dequeues an item from the queue, if possible. + /// The dequeued item, or default if the queue was empty. + /// Whether an item was dequeued. + bool TryDequeue([MaybeNullWhen(false)] out T item); + + /// Peeks at the next item from the queue that would be dequeued, if possible. + /// The peeked item, or default if the queue was empty. + /// Whether an item was peeked. + bool TryPeek([MaybeNullWhen(false)] out T item); + + /// Gets the number of elements in the queue. + int Count { get; } + + /// Gets whether the queue is empty. + bool IsEmpty { get; } + } +} diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs index fb3facf83dc47e..ad7ee0e3608d3c 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedChannel.cs @@ -5,19 +5,20 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace System.Threading.Channels { /// Provides a buffered channel of unbounded capacity. [DebuggerDisplay("Items = {ItemsCountForDebugger}, Closed = {ChannelIsClosedForDebugger}")] - [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))] - internal sealed class UnboundedChannel : Channel, IDebugEnumerable + [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<,>))] + internal sealed class UnboundedChannel : Channel, IDebugEnumerable where TQueue : struct, IUnboundedChannelQueue { /// Task that indicates the channel has completed. private readonly TaskCompletionSource _completion; /// The items in the channel. - private readonly ConcurrentQueue _items = new ConcurrentQueue(); + private readonly TQueue _items; /// Readers blocked reading from the channel. private readonly Deque> _blockedReaders = new Deque>(); /// Whether to force continuations to be executed asynchronously from producer writes. @@ -29,8 +30,9 @@ internal sealed class UnboundedChannel : Channel, IDebugEnumerable private Exception? _doneWriting; /// Initialize the channel. - internal UnboundedChannel(bool runContinuationsAsynchronously) + internal UnboundedChannel(TQueue items, bool runContinuationsAsynchronously) { + _items = items; _runContinuationsAsynchronously = runContinuationsAsynchronously; _completion = new TaskCompletionSource(runContinuationsAsynchronously ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None); Reader = new UnboundedChannelReader(this); @@ -38,14 +40,14 @@ internal UnboundedChannel(bool runContinuationsAsynchronously) } [DebuggerDisplay("Items = {Count}")] - [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))] + [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<,>))] private sealed class UnboundedChannelReader : ChannelReader, IDebugEnumerable { - internal readonly UnboundedChannel _parent; + internal readonly UnboundedChannel _parent; private readonly AsyncOperation _readerSingleton; private readonly AsyncOperation _waiterSingleton; - internal UnboundedChannelReader(UnboundedChannel parent) + internal UnboundedChannelReader(UnboundedChannel parent) { _parent = parent; _readerSingleton = new AsyncOperation(parent._runContinuationsAsynchronously, pooled: true); @@ -68,8 +70,8 @@ public override ValueTask ReadAsync(CancellationToken cancellationToken) } // Dequeue an item if we can. - UnboundedChannel parent = _parent; - if (parent._items.TryDequeue(out T? item)) + UnboundedChannel parent = _parent; + if (parent._items.IsThreadSafe && parent._items.TryDequeue(out T? item)) { CompleteIfDone(parent); return new ValueTask(item); @@ -112,24 +114,60 @@ public override ValueTask ReadAsync(CancellationToken cancellationToken) public override bool TryRead([MaybeNullWhen(false)] out T item) { - UnboundedChannel parent = _parent; + UnboundedChannel parent = _parent; + return parent._items.IsThreadSafe ? + LockFree(parent, out item) : + Locked(parent, out item); - // Dequeue an item if we can - if (parent._items.TryDequeue(out item)) + static bool LockFree(UnboundedChannel parent, [MaybeNullWhen(false)] out T item) { - CompleteIfDone(parent); - return true; + if (parent._items.TryDequeue(out item)) + { + CompleteIfDone(parent); + return true; + } + + item = default; + return false; } - item = default; - return false; + static bool Locked(UnboundedChannel parent, [MaybeNullWhen(false)] out T item) + { + lock (parent.SyncObj) + { + if (parent._items.TryDequeue(out item)) + { + CompleteIfDone(parent); + return true; + } + } + + item = default; + return false; + } } - public override bool TryPeek([MaybeNullWhen(false)] out T item) => - _parent._items.TryPeek(out item); + public override bool TryPeek([MaybeNullWhen(false)] out T item) + { + UnboundedChannel parent = _parent; + return parent._items.IsThreadSafe ? + parent._items.TryPeek(out item) : + Locked(parent, out item); + + // Separated out to keep the try/finally from preventing TryPeek from being inlined + static bool Locked(UnboundedChannel parent, [MaybeNullWhen(false)] out T item) + { + lock (parent.SyncObj) + { + return parent._items.TryPeek(out item); + } + } + } - private static void CompleteIfDone(UnboundedChannel parent) + private static void CompleteIfDone(UnboundedChannel parent) { + Debug.Assert(parent._items.IsThreadSafe || Monitor.IsEntered(parent.SyncObj)); + if (parent._doneWriting != null && parent._items.IsEmpty) { // If we've now emptied the items queue and we're not getting any more, complete. @@ -144,12 +182,12 @@ public override ValueTask WaitToReadAsync(CancellationToken cancellationTo return new ValueTask(Task.FromCanceled(cancellationToken)); } - if (!_parent._items.IsEmpty) + if (_parent._items.IsThreadSafe && !_parent._items.IsEmpty) { return new ValueTask(true); } - UnboundedChannel parent = _parent; + UnboundedChannel parent = _parent; lock (parent.SyncObj) { @@ -192,15 +230,15 @@ public override ValueTask WaitToReadAsync(CancellationToken cancellationTo } [DebuggerDisplay("Items = {ItemsCountForDebugger}")] - [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))] + [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<,>))] private sealed class UnboundedChannelWriter : ChannelWriter, IDebugEnumerable { - internal readonly UnboundedChannel _parent; - internal UnboundedChannelWriter(UnboundedChannel parent) => _parent = parent; + internal readonly UnboundedChannel _parent; + internal UnboundedChannelWriter(UnboundedChannel parent) => _parent = parent; public override bool TryComplete(Exception? error) { - UnboundedChannel parent = _parent; + UnboundedChannel parent = _parent; bool completeTask; lock (parent.SyncObj) @@ -240,7 +278,7 @@ public override bool TryComplete(Exception? error) public override bool TryWrite(T item) { - UnboundedChannel parent = _parent; + UnboundedChannel parent = _parent; while (true) { AsyncOperation? blockedReader = null; @@ -321,7 +359,7 @@ public override ValueTask WriteAsync(T item, CancellationToken cancellationToken } /// Gets the object used to synchronize access to all state on this instance. - private object SyncObj => _items; + private object SyncObj => _blockedReaders; [Conditional("DEBUG")] private void AssertInvariants() diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedPriorityChannel.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedPriorityChannel.cs deleted file mode 100644 index 7af18b9413ee29..00000000000000 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/UnboundedPriorityChannel.cs +++ /dev/null @@ -1,369 +0,0 @@ -// 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.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; - -// This file is primarily a copy of UnboundedChannel, subsequently tweaked to account for differences -// between ConcurrentQueue and PriorityQueue, e.g. that PQ isn't thread safe and so fast -// paths outside of locks need to be removed, that Enqueue/Dequeue methods take priorities, etc. Any -// changes made to this or that file should largely be kept in sync. - -namespace System.Threading.Channels -{ - /// Provides a buffered channel of unbounded capacity. - [DebuggerDisplay("Items = {ItemsCountForDebugger}, Closed = {ChannelIsClosedForDebugger}")] - [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))] - internal sealed class UnboundedPrioritizedChannel : Channel, IDebugEnumerable - { - /// Task that indicates the channel has completed. - private readonly TaskCompletionSource _completion; - /// The items in the channel. - /// To avoid double storing of a potentially large struct T, the priority doubles as the element and the element is ignored. - private readonly PriorityQueue _items; - /// Readers blocked reading from the channel. - private readonly Deque> _blockedReaders = new Deque>(); - /// Whether to force continuations to be executed asynchronously from producer writes. - private readonly bool _runContinuationsAsynchronously; - - /// Readers waiting for a notification that data is available. - private AsyncOperation? _waitingReadersTail; - /// Set to non-null once Complete has been called. - private Exception? _doneWriting; - - /// Initialize the channel. - internal UnboundedPrioritizedChannel(bool runContinuationsAsynchronously, IComparer? comparer) - { - _runContinuationsAsynchronously = runContinuationsAsynchronously; - _completion = new TaskCompletionSource(runContinuationsAsynchronously ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None); - Reader = new UnboundedPrioritizedChannelReader(this); - Writer = new UnboundedPrioritizedChannelWriter(this); - _items = new PriorityQueue(comparer); - } - - [DebuggerDisplay("Items = {Count}")] - [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))] - private sealed class UnboundedPrioritizedChannelReader : ChannelReader, IDebugEnumerable - { - internal readonly UnboundedPrioritizedChannel _parent; - private readonly AsyncOperation _readerSingleton; - private readonly AsyncOperation _waiterSingleton; - - internal UnboundedPrioritizedChannelReader(UnboundedPrioritizedChannel parent) - { - _parent = parent; - _readerSingleton = new AsyncOperation(parent._runContinuationsAsynchronously, pooled: true); - _waiterSingleton = new AsyncOperation(parent._runContinuationsAsynchronously, pooled: true); - } - - public override Task Completion => _parent._completion.Task; - - public override bool CanCount => true; - - public override bool CanPeek => true; - - public override int Count => _parent._items.Count; - - public override ValueTask ReadAsync(CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - { - return ValueTask.FromCanceled(cancellationToken); - } - - // Dequeue an item if we can. - UnboundedPrioritizedChannel parent = _parent; - lock (parent.SyncObj) - { - parent.AssertInvariants(); - - // Try to dequeue again, now that we hold the lock. - if (parent._items.TryDequeue(out _, out T? item)) - { - CompleteIfDone(parent); - return new ValueTask(item); - } - - // There are no items, so if we're done writing, fail. - if (parent._doneWriting != null) - { - return ChannelUtilities.GetInvalidCompletionValueTask(parent._doneWriting); - } - - // If we're able to use the singleton reader, do so. - if (!cancellationToken.CanBeCanceled) - { - AsyncOperation singleton = _readerSingleton; - if (singleton.TryOwnAndReset()) - { - parent._blockedReaders.EnqueueTail(singleton); - return singleton.ValueTaskOfT; - } - } - - // Otherwise, create and queue a reader. - var reader = new AsyncOperation(parent._runContinuationsAsynchronously, cancellationToken); - parent._blockedReaders.EnqueueTail(reader); - return reader.ValueTaskOfT; - } - } - - public override bool TryRead([MaybeNullWhen(false)] out T item) - { - UnboundedPrioritizedChannel parent = _parent; - lock (parent.SyncObj) - { - // Dequeue an item if we can - if (parent._items.TryDequeue(out _, out item)) - { - CompleteIfDone(parent); - return true; - } - - item = default; - return false; - } - } - - public override bool TryPeek([MaybeNullWhen(false)] out T item) => - _parent._items.TryPeek(out _, out item); - - private static void CompleteIfDone(UnboundedPrioritizedChannel parent) - { - Debug.Assert(Monitor.IsEntered(parent.SyncObj)); - - if (parent._doneWriting != null && parent._items.Count == 0) - { - // If we've now emptied the items queue and we're not getting any more, complete. - ChannelUtilities.Complete(parent._completion, parent._doneWriting); - } - } - - public override ValueTask WaitToReadAsync(CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - { - return ValueTask.FromCanceled(cancellationToken); - } - - UnboundedPrioritizedChannel parent = _parent; - lock (parent.SyncObj) - { - parent.AssertInvariants(); - - // Try again to read now that we're synchronized with writers. - if (parent._items.Count != 0) - { - return new ValueTask(true); - } - - // There are no items, so if we're done writing, there's never going to be data available. - if (parent._doneWriting != null) - { - return parent._doneWriting != ChannelUtilities.s_doneWritingSentinel ? - ValueTask.FromException(parent._doneWriting) : - default; - } - - // If we're able to use the singleton waiter, do so. - if (!cancellationToken.CanBeCanceled) - { - AsyncOperation singleton = _waiterSingleton; - if (singleton.TryOwnAndReset()) - { - ChannelUtilities.QueueWaiter(ref parent._waitingReadersTail, singleton); - return singleton.ValueTaskOfT; - } - } - - // Otherwise, create and queue a waiter. - var waiter = new AsyncOperation(parent._runContinuationsAsynchronously, cancellationToken); - ChannelUtilities.QueueWaiter(ref parent._waitingReadersTail, waiter); - return waiter.ValueTaskOfT; - } - } - - /// Gets an enumerator the debugger can use to show the contents of the channel. - IEnumerator IDebugEnumerable.GetEnumerator() => _parent.GetEnumerator(); - } - - [DebuggerDisplay("Items = {ItemsCountForDebugger}")] - [DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))] - private sealed class UnboundedPrioritizedChannelWriter : ChannelWriter, IDebugEnumerable - { - internal readonly UnboundedPrioritizedChannel _parent; - internal UnboundedPrioritizedChannelWriter(UnboundedPrioritizedChannel parent) => _parent = parent; - - public override bool TryComplete(Exception? error) - { - UnboundedPrioritizedChannel parent = _parent; - bool completeTask; - - lock (parent.SyncObj) - { - parent.AssertInvariants(); - - // If we've already marked the channel as completed, bail. - if (parent._doneWriting != null) - { - return false; - } - - // Mark that we're done writing. - parent._doneWriting = error ?? ChannelUtilities.s_doneWritingSentinel; - completeTask = parent._items.Count == 0; - } - - // If there are no items in the queue, complete the channel's task, - // as no more data can possibly arrive at this point. We do this outside - // of the lock in case we'll be running synchronous completions, and we - // do it before completing blocked/waiting readers, so that when they - // wake up they'll see the task as being completed. - if (completeTask) - { - ChannelUtilities.Complete(parent._completion, error); - } - - // At this point, _blockedReaders and _waitingReaders will not be mutated: - // they're only mutated by readers while holding the lock, and only if _doneWriting is null. - // freely manipulate _blockedReaders and _waitingReaders without any concurrency concerns. - ChannelUtilities.FailOperations, T>(parent._blockedReaders, ChannelUtilities.CreateInvalidCompletionException(error)); - ChannelUtilities.WakeUpWaiters(ref parent._waitingReadersTail, result: false, error: error); - - // Successfully transitioned to completed. - return true; - } - - public override bool TryWrite(T item) - { - UnboundedPrioritizedChannel parent = _parent; - while (true) - { - AsyncOperation? blockedReader = null; - AsyncOperation? waitingReadersTail = null; - lock (parent.SyncObj) - { - // If writing has already been marked as done, fail the write. - parent.AssertInvariants(); - if (parent._doneWriting != null) - { - return false; - } - - // If there aren't any blocked readers, just add the data to the queue, - // and let any waiting readers know that they should try to read it. - // We can only complete such waiters here under the lock if they run - // continuations asynchronously (otherwise the synchronous continuations - // could be invoked under the lock). If we don't complete them here, we - // need to do so outside of the lock. - if (parent._blockedReaders.IsEmpty) - { - parent._items.Enqueue(true, item); - waitingReadersTail = parent._waitingReadersTail; - if (waitingReadersTail == null) - { - return true; - } - parent._waitingReadersTail = null; - } - else - { - // There were blocked readers. Grab one, and then complete it outside of the lock. - blockedReader = parent._blockedReaders.DequeueHead(); - } - } - - if (blockedReader != null) - { - // Complete the reader. It's possible the reader was canceled, in which - // case we loop around to try everything again. - if (blockedReader.TrySetResult(item)) - { - return true; - } - } - else - { - // Wake up all of the waiters. Since we've released the lock, it's possible - // we could cause some spurious wake-ups here, if we tell a waiter there's - // something available but all data has already been removed. It's a benign - // race condition, though, as consumers already need to account for such things. - ChannelUtilities.WakeUpWaiters(ref waitingReadersTail, result: true); - return true; - } - } - } - - public override ValueTask WaitToWriteAsync(CancellationToken cancellationToken) - { - Exception? doneWriting = _parent._doneWriting; - return - cancellationToken.IsCancellationRequested ? ValueTask.FromCanceled(cancellationToken) : - doneWriting == null ? new ValueTask(true) : // unbounded writing can always be done if we haven't completed - doneWriting != ChannelUtilities.s_doneWritingSentinel ? ValueTask.FromException(doneWriting) : - default; - } - - public override ValueTask WriteAsync(T item, CancellationToken cancellationToken) => - cancellationToken.IsCancellationRequested ? ValueTask.FromCanceled(cancellationToken) : - TryWrite(item) ? default : - ValueTask.FromException(ChannelUtilities.CreateInvalidCompletionException(_parent._doneWriting)); - - /// Gets the number of items in the channel. This should only be used by the debugger. - private int ItemsCountForDebugger => _parent._items.Count; - - /// Gets an enumerator the debugger can use to show the contents of the channel. - IEnumerator IDebugEnumerable.GetEnumerator() => _parent.GetEnumerator(); - } - - /// Gets the object used to synchronize access to all state on this instance. - private object SyncObj => _items; - - [Conditional("DEBUG")] - private void AssertInvariants() - { - Debug.Assert(SyncObj != null, "The sync obj must not be null."); - Debug.Assert(Monitor.IsEntered(SyncObj), "Invariants can only be validated while holding the lock."); - - if (_items.Count != 0) - { - if (_runContinuationsAsynchronously) - { - Debug.Assert(_blockedReaders.IsEmpty, "There's data available, so there shouldn't be any blocked readers."); - Debug.Assert(_waitingReadersTail == null, "There's data available, so there shouldn't be any waiting readers."); - } - Debug.Assert(!_completion.Task.IsCompleted, "We still have data available, so shouldn't be completed."); - } - if ((!_blockedReaders.IsEmpty || _waitingReadersTail != null) && _runContinuationsAsynchronously) - { - Debug.Assert(_items.Count == 0, "There are blocked/waiting readers, so there shouldn't be any data available."); - } - if (_completion.Task.IsCompleted) - { - Debug.Assert(_doneWriting != null, "We're completed, so we must be done writing."); - } - } - - /// Gets the number of items in the channel. This should only be used by the debugger. - private int ItemsCountForDebugger => _items.Count; - - /// Report if the channel is closed or not. This should only be used by the debugger. - private bool ChannelIsClosedForDebugger => _doneWriting != null; - - /// Gets an enumerator the debugger can use to show the contents of the channel. - public IEnumerator GetEnumerator() - { - List list = []; - foreach ((bool _, T Priority) item in _items.UnorderedItems) - { - list.Add(item.Priority); - } - - list.Sort(_items.Comparer); - - return list.GetEnumerator(); - } - } -} diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs index 6b5a4014990ef0..bab7263c2b1c76 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/ConcurrencyLimiter.cs @@ -156,8 +156,17 @@ protected override ValueTask AcquireAsyncCore(int permitCount, C Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - // Updating queue count is handled by the cancellation code - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -277,10 +286,19 @@ private void Release(int releaseCount) // Check if request was canceled if (!nextPendingRequest.TrySetResult(lease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _permitCount += nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -399,6 +417,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -413,7 +434,7 @@ public RequestRegistration(int permitCount, ConcurrencyLimiter limiter, Cancella // is going to invoke the callback synchronously, but this does not create // a deadlock because lock are reentrant if (cancellationToken.CanBeCanceled) -#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER _cancellationTokenRegistration = cancellationToken.UnsafeRegister(Cancel, this); #else _cancellationTokenRegistration = cancellationToken.Register(Cancel, this); @@ -429,7 +450,14 @@ private static void Cancel(object? state) var limiter = (ConcurrencyLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs index d09c7973b18aa7..7ed567f174a5f1 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/FixedWindowRateLimiter.cs @@ -173,7 +173,17 @@ protected override ValueTask AcquireAsyncCore(int permitCount, C Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -330,10 +340,19 @@ private void ReplenishInternal(long nowTicks) if (!nextPendingRequest.TrySetResult(SuccessfulLease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _permitCount += nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -435,6 +454,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -449,7 +471,7 @@ public RequestRegistration(int permitCount, FixedWindowRateLimiter limiter, Canc // is going to invoke the callback synchronously, but this does not create // a deadlock because lock are reentrant if (cancellationToken.CanBeCanceled) -#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER _cancellationTokenRegistration = cancellationToken.UnsafeRegister(Cancel, this); #else _cancellationTokenRegistration = cancellationToken.Register(Cancel, this); @@ -465,7 +487,14 @@ private static void Cancel(object? state) var limiter = (FixedWindowRateLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs index a179720ede33fa..16398459a4d8a8 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/SlidingWindowRateLimiter.cs @@ -185,7 +185,17 @@ protected override ValueTask AcquireAsyncCore(int permitCount, C Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -342,11 +352,20 @@ private void ReplenishInternal(long nowTicks) if (!nextPendingRequest.TrySetResult(SuccessfulLease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _permitCount += nextPendingRequest.Count; _requestsPerSegment[_currentSegmentIndex] -= nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -448,6 +467,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -462,7 +484,7 @@ public RequestRegistration(int permitCount, SlidingWindowRateLimiter limiter, Ca // is going to invoke the callback synchronously, but this does not create // a deadlock because lock are reentrant if (cancellationToken.CanBeCanceled) -#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER _cancellationTokenRegistration = cancellationToken.UnsafeRegister(Cancel, this); #else _cancellationTokenRegistration = cancellationToken.Register(Cancel, this); @@ -478,7 +500,14 @@ private static void Cancel(object? state) var limiter = (SlidingWindowRateLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs index 5ad7859792ff7f..73d78efdc680de 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs @@ -178,8 +178,17 @@ protected override ValueTask AcquireAsyncCore(int tokenCount, Ca Debug.Assert(_queueCount >= 0); if (!oldestRequest.TrySetResult(FailedLease)) { - // Updating queue count is handled by the cancellation code - _queueCount += oldestRequest.Count; + if (!oldestRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + oldestRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += oldestRequest.Count; + } } else { @@ -345,10 +354,19 @@ private void ReplenishInternal(long nowTicks) if (!nextPendingRequest.TrySetResult(SuccessfulLease)) { - // Queued item was canceled so add count back + // Queued item was canceled so add count back, permits weren't acquired _tokenCount += nextPendingRequest.Count; - // Updating queue count is handled by the cancellation code - _queueCount += nextPendingRequest.Count; + if (!nextPendingRequest.QueueCountModified) + { + // We already updated the queue count, the Cancel code is about to run or running and waiting on our lock, + // tell Cancel not to do anything + nextPendingRequest.QueueCountModified = true; + } + else + { + // Updating queue count was handled by the cancellation code, don't double count + _queueCount += nextPendingRequest.Count; + } } else { @@ -450,6 +468,9 @@ private sealed class RequestRegistration : TaskCompletionSource private readonly CancellationToken _cancellationToken; private CancellationTokenRegistration _cancellationTokenRegistration; + // Update under the limiter lock and only if the queue count was updated by the calling code + public bool QueueCountModified { get; set; } + // this field is used only by the disposal mechanics and never shared between threads private RequestRegistration? _next; @@ -464,7 +485,7 @@ public RequestRegistration(int permitCount, TokenBucketRateLimiter limiter, Canc // is going to invoke the callback synchronously, but this does not create // a deadlock because lock are reentrant if (cancellationToken.CanBeCanceled) -#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER _cancellationTokenRegistration = cancellationToken.UnsafeRegister(Cancel, this); #else _cancellationTokenRegistration = cancellationToken.Register(Cancel, this); @@ -480,7 +501,14 @@ private static void Cancel(object? state) var limiter = (TokenBucketRateLimiter)registration.Task.AsyncState!; lock (limiter.Lock) { - limiter._queueCount -= registration.Count; + // Queuing and replenishing code might modify the _queueCount, since there is no guarantee of when the cancellation + // code runs and we only want to update the _queueCount once, we set a bool (under a lock) so either method + // can update the count and not double count. + if (!registration.QueueCountModified) + { + limiter._queueCount -= registration.Count; + registration.QueueCountModified = true; + } } } } diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs index 63cdedf4b466a6..c91cff3b5423ab 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Base/DataflowBlock.cs @@ -1470,7 +1470,7 @@ public static Task OutputAvailableAsync( { // When cancellation is requested, unlink the target from the source and cancel the target. target._ctr = cancellationToken.Register( -#if NET6_0_OR_GREATER +#if NET OutputAvailableAsyncTarget.CancelAndUnlink, #else static state => OutputAvailableAsyncTarget.CancelAndUnlink(state, default), diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs index 7bfd3ecf35d952..c04ee9556003d4 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/Common.cs @@ -190,7 +190,7 @@ internal static void WireCancellationToComplete( // data, and we also want to dispose of that registration when we complete so that we don't // leak into a long-living cancellation token. CancellationTokenRegistration reg = cancellationToken.Register( -#if NET6_0_OR_GREATER +#if NET completeAction, completeState #else state => diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj index 2a1eaf2804e355..21e1af10705020 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj @@ -80,6 +80,7 @@ System.Threading.Tasks.Dataflow.WriteOnceBlock<T> + diff --git a/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj b/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj index 3278b9f2c5e19d..32d0f7c8cf6a3f 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj +++ b/src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj @@ -24,6 +24,7 @@ + diff --git a/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs b/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs index d77919070c24df..e57dff3e55ce2a 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs +++ b/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs @@ -314,7 +314,7 @@ private void LoadStream(bool loadSync) int streamLen = (int)_stream.Length; _currentPos = 0; _streamData = new byte[streamLen]; -#if NET7_0_OR_GREATER +#if NET _stream.ReadExactly(_streamData); #else int totalRead = 0; diff --git a/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs b/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs index da1c5de5f35dbe..a5042fc0242026 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs +++ b/src/libraries/System.Windows.Extensions/src/System/Media/SystemSounds.cs @@ -5,11 +5,11 @@ namespace System.Media { public static class SystemSounds { - private static volatile SystemSound? s_asterisk; - private static volatile SystemSound? s_beep; - private static volatile SystemSound? s_exclamation; - private static volatile SystemSound? s_hand; - private static volatile SystemSound? s_question; + private static SystemSound? s_asterisk; + private static SystemSound? s_beep; + private static SystemSound? s_exclamation; + private static SystemSound? s_hand; + private static SystemSound? s_question; public static SystemSound Asterisk { diff --git a/src/libraries/System.Windows.Extensions/src/System/Security/Cryptography/X509Certificates/X509Certificate2UI.cs b/src/libraries/System.Windows.Extensions/src/System/Security/Cryptography/X509Certificates/X509Certificate2UI.cs index b19e217322f07e..dfdb4660ea4991 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Security/Cryptography/X509Certificates/X509Certificate2UI.cs +++ b/src/libraries/System.Windows.Extensions/src/System/Security/Cryptography/X509Certificates/X509Certificate2UI.cs @@ -53,7 +53,7 @@ private static unsafe void DisplayX509Certificate(X509Certificate2 certificate, // Initialize view structure. Interop.CryptUI.CRYPTUI_VIEWCERTIFICATE_STRUCTW ViewInfo = default; -#if NET7_0_OR_GREATER +#if NET ViewInfo.dwSize = (uint)sizeof(Interop.CryptUI.CRYPTUI_VIEWCERTIFICATE_STRUCTW.Marshaller.Native); #else ViewInfo.dwSize = (uint)Marshal.SizeOf(); @@ -122,7 +122,7 @@ private static unsafe SafeCertStoreHandle SelectFromStore(SafeCertStoreHandle sa Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW csc = default; // Older versions of CRYPTUI do not check the size correctly, // so always force it to the oldest version of the structure. -#if NET7_0_OR_GREATER +#if NET // Declare a local for Native to enable us to get the managed byte offset // without having a null check cause a failure. Interop.CryptUI.CRYPTUI_SELECTCERTIFICATE_STRUCTW.Marshaller.Native native; diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml index 09cfe417e3812f..935f4a69d115ad 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml @@ -469,4 +469,64 @@ net8.0/System.dll net9.0/System.dll + + CP0021 + T:System.Diagnostics.Metrics.MeasurementCallback`1``0:struct + net8.0/System.Diagnostics.DiagnosticSource.dll + net9.0/System.Diagnostics.DiagnosticSource.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsDefaultMarshaller`1``0:struct + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsDefaultMarshaller`1``0:unmanaged + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller`1``0:struct + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller`1``0:T:System.Numerics.INumber{`0} + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller`1``0:unmanaged + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsNaNMarshaller`1``0:struct + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsNaNMarshaller`1``0:T:System.Numerics.IFloatingPointIeee754{`0} + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Runtime.InteropServices.Marshalling.ExceptionAsNaNMarshaller`1``0:unmanaged + net8.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + T:System.Text.Json.Serialization.JsonNumberEnumConverter`1``0:T:System.Enum + net8.0/System.Text.Json.dll + net9.0/System.Text.Json.dll + \ No newline at end of file diff --git a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml index e03170246c0a50..939342fce86a04 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.0.xml @@ -2791,4 +2791,382 @@ netstandard2.0/System.dll net9.0/System.dll + + CP0021 + M:System.Runtime.InteropServices.Marshal.CreateAggregatedObject``1(System.IntPtr,``0)``0:notnull + netstandard2.0/mscorlib.dll + net9.0/mscorlib.dll + + + CP0021 + M:System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate``1(``0)``0:notnull + netstandard2.0/mscorlib.dll + net9.0/mscorlib.dll + + + CP0021 + T:System.Collections.Concurrent.ConcurrentDictionary`2``0:notnull + netstandard2.0/mscorlib.dll + net9.0/mscorlib.dll + + + CP0021 + T:System.Collections.Generic.Dictionary`2``0:notnull + netstandard2.0/mscorlib.dll + net9.0/mscorlib.dll + + + CP0021 + T:System.Collections.ObjectModel.KeyedCollection`2``0:notnull + netstandard2.0/mscorlib.dll + net9.0/mscorlib.dll + + + CP0021 + T:System.Collections.ObjectModel.ReadOnlyDictionary`2``0:notnull + netstandard2.0/mscorlib.dll + net9.0/mscorlib.dll + + + CP0021 + T:System.Tuple`8``7:notnull + netstandard2.0/mscorlib.dll + net9.0/mscorlib.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Runtime.InteropServices.Marshal.CreateAggregatedObject``1(System.IntPtr,``0)``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate``1(``0)``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Concurrent.ConcurrentDictionary`2``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Generic.Dictionary`2``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Generic.SortedDictionary`2``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Generic.SortedList`2``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.ObjectModel.KeyedCollection`2``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.ObjectModel.ReadOnlyDictionary`2``0:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Tuple`8``7:notnull + netstandard2.0/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Concurrent.ConcurrentDictionary`2``0:notnull + netstandard2.0/System.Collections.Concurrent.dll + net9.0/System.Collections.Concurrent.dll + + + CP0021 + T:System.Collections.Generic.Dictionary`2``0:notnull + netstandard2.0/System.Collections.dll + net9.0/System.Collections.dll + + + CP0021 + T:System.Collections.Generic.SortedDictionary`2``0:notnull + netstandard2.0/System.Collections.dll + net9.0/System.Collections.dll + + + CP0021 + T:System.Collections.Generic.SortedList`2``0:notnull + netstandard2.0/System.Collections.dll + net9.0/System.Collections.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/System.Core.dll + net9.0/System.Core.dll + + + CP0021 + T:System.Collections.Generic.SortedDictionary`2``0:notnull + netstandard2.0/System.dll + net9.0/System.dll + + + CP0021 + T:System.Collections.Generic.SortedList`2``0:notnull + netstandard2.0/System.dll + net9.0/System.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Linq.dll + net9.0/System.Linq.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/System.Linq.dll + net9.0/System.Linq.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Linq.dll + net9.0/System.Linq.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/System.Linq.dll + net9.0/System.Linq.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.0/System.Linq.Parallel.dll + net9.0/System.Linq.Parallel.dll + + + CP0021 + T:System.Collections.ObjectModel.KeyedCollection`2``0:notnull + netstandard2.0/System.ObjectModel.dll + net9.0/System.ObjectModel.dll + + + CP0021 + T:System.Collections.ObjectModel.ReadOnlyDictionary`2``0:notnull + netstandard2.0/System.ObjectModel.dll + net9.0/System.ObjectModel.dll + + + CP0021 + T:System.Tuple`8``7:notnull + netstandard2.0/System.Runtime.dll + net9.0/System.Runtime.dll + + + CP0021 + M:System.Runtime.InteropServices.Marshal.CreateAggregatedObject``1(System.IntPtr,``0)``0:notnull + netstandard2.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + + + CP0021 + M:System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate``1(``0)``0:notnull + netstandard2.0/System.Runtime.InteropServices.dll + net9.0/System.Runtime.InteropServices.dll + \ No newline at end of file diff --git a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml index f7c8eb8430ef04..f0ef02d93c1a19 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml +++ b/src/libraries/apicompat/ApiCompatBaseline.netstandard2.1.xml @@ -877,4 +877,130 @@ netstandard2.1/netstandard.dll net9.0/netstandard.dll + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.Enumerable.ToDictionary``3(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToDictionary``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``2(System.Linq.ParallelQuery{``0},System.Func{``0,``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2},System.Collections.Generic.IEqualityComparer{``1})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Linq.ParallelEnumerable.ToLookup``3(System.Linq.ParallelQuery{``0},System.Func{``0,``1},System.Func{``0,``2})``1:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Runtime.InteropServices.Marshal.CreateAggregatedObject``1(System.IntPtr,``0)``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + M:System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate``1(``0)``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Concurrent.ConcurrentDictionary`2``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Generic.Dictionary`2``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Generic.SortedDictionary`2``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.Generic.SortedList`2``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.ObjectModel.KeyedCollection`2``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Collections.ObjectModel.ReadOnlyDictionary`2``0:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + + + CP0021 + T:System.Tuple`8``7:notnull + netstandard2.1/netstandard.dll + net9.0/netstandard.dll + \ No newline at end of file diff --git a/src/libraries/sendtohelix-browser.targets b/src/libraries/sendtohelix-browser.targets index 8b9a4194565772..393b4dd38f1ff2 100644 --- a/src/libraries/sendtohelix-browser.targets +++ b/src/libraries/sendtohelix-browser.targets @@ -32,7 +32,8 @@ <_ShippingPackagesPath>$([MSBuild]::NormalizeDirectory($(ArtifactsDir), 'packages', $(Configuration), 'Shipping')) - $(Scenario)- + $(Scenario)-ST- + $(Scenario)-MT- true - - - - @@ -112,10 +109,6 @@ - - - - @@ -182,7 +175,13 @@ - + <_WasmSampleZipFile Condition="'$(Scenario)' == 'WasmTestOnV8'" Include="$(TestArchiveRoot)runonly/**/*.Console.V8.*.Sample.zip" /> - <_WasmSampleZipFile Condition="'$(Scenario)' == 'WasmTestOnNodeJS'" Include="$(TestArchiveRoot)runonly/**/*.Console.Node.*.Sample.zip" /> + <_WasmSampleZipFile Condition="'$(Scenario)' == 'WasmTestOnNodeJS'" Include="$(TestArchiveRoot)runonly/**/*.Console.Node.*.Sample.zip" /> <_WasmSampleZipFile Condition="'$(Scenario)' == 'WasmTestOnChrome'" Include="$(TestArchiveRoot)runonly/**/*.Browser.*.Sample.zip" /> + - + %(Identity) $(HelixCommand) $(_workItemTimeout) diff --git a/src/libraries/sendtohelix-wasi.targets b/src/libraries/sendtohelix-wasi.targets index f89da35e17e3e8..8a1902eb378fc5 100644 --- a/src/libraries/sendtohelix-wasi.targets +++ b/src/libraries/sendtohelix-wasi.targets @@ -48,8 +48,8 @@ $(RepoRoot)src\mono\wasi\wasi-sdk\ $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasi', 'build')) - $(HelixDependenciesStagingPath)\wasi-sdk - $(HelixDependenciesStagingPath)\wasmtime + $(HelixDependenciesStagingPath)$(WorkItemPrefix)wasi-sdk + $(HelixDependenciesStagingPath)$(WorkItemPrefix)wasmtime true true @@ -104,10 +104,12 @@ + + - - diff --git a/src/libraries/sendtohelix-wasm.targets b/src/libraries/sendtohelix-wasm.targets index d9c2e3aead0845..3fce57cf9c4e1b 100644 --- a/src/libraries/sendtohelix-wasm.targets +++ b/src/libraries/sendtohelix-wasm.targets @@ -9,6 +9,14 @@ $([MSBuild]::NormalizeDirectory($(WasmProjectRoot), 'build')) + + Workloads- + NoWorkload- + $(WorkItemPrefix)NoWebcil- + $(WorkItemPrefix)ST- + $(WorkItemPrefix)MT- + + @@ -27,12 +35,6 @@ - - Workloads- - NoWorkload- - $(WorkItemPrefix)NoWebcil- - - <_WasmWorkItem Include="$(WorkItemArchiveWildCard)" Exclude="$(HelixCorrelationPayload)" /> diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 659fda6a8d7d65..7106a44c89e967 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -646,16 +646,19 @@ BuildInParallel="$(BuildTestInParallel)" /> + + + + + + + + - - :Debug>") # statically link VC runtime library - add_compile_options($<$:/W4>) # set warning level 4 - add_compile_options($<$:/WX>) # treat warnings as errors - add_compile_options($<$:/wd4324>) # 'struct_name' : structure was padded due to __declspec(align()) - add_compile_options($<$:/EHsc>) # set exception handling behavior - add_compile_options($<$:/FC>) # use full pathnames in diagnostics + add_compile_options($<$:/W4>) # set warning level 4 + add_compile_options($<$:/WX>) # treat warnings as errors + add_compile_options($<$:/wd4324>) # 'struct_name' : structure was padded due to __declspec(align()) + add_compile_options($<$:/EHsc>) # set exception handling behavior + add_compile_options($<$:/FC>) # use full pathnames in diagnostics + add_compile_options($<$:/guard:cf>) # Enable control flow guard add_link_options(/STACK:0x800000) # set stack size to 8MB (default is 1MB) + add_link_options(/guard:cf) if(CMAKE_BUILD_TYPE STREQUAL "Release") add_compile_options($<$:/Oi>) # enable intrinsics add_compile_options($<$:/GF>) # enable string pooling diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index 12d6fdb34cfc57..d97bf84a1da660 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -34,10 +34,12 @@ - <_ProvisionWasiSdkDir>$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), 'wasi', 'wasi-sdk')) - true - $(_ProvisionWasiSdkDir) + + $([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), 'wasi', 'wasi-sdk')) $([MSBuild]::EnsureTrailingSlash('$(WASI_SDK_PATH)').Replace('\', '/')) + true diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 905dc83eb08dee..076fc42815c65c 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -36,8 +36,7 @@ $(ProductVersion) $(ProductVersion) - - $(NoWarn),0419,0649,AD0001 + $(NoWarn),0419,0649 enable diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameParser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameParser.Mono.cs index 3622b4e27626ac..22a7361d9814e0 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameParser.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/TypeNameParser.Mono.cs @@ -39,32 +39,31 @@ internal unsafe ref partial struct TypeNameParser return null; } - return new TypeNameParser(typeName) + Metadata.TypeName? parsed = Metadata.TypeNameParser.Parse(typeName, throwOnError: throwOnError); + if (parsed is null) + { + return null; + } + + return new TypeNameParser() { _assemblyResolver = assemblyResolver, _typeResolver = typeResolver, _throwOnError = throwOnError, _ignoreCase = ignoreCase, _stackMark = Unsafe.AsPointer(ref stackMark) - }.Parse(); + }.Resolve(parsed); } - private static bool CheckTopLevelAssemblyQualifiedName() + private Assembly? ResolveAssembly(AssemblyName name) { - return true; - } - - private Assembly? ResolveAssembly(string assemblyName) - { - var name = new AssemblyName(assemblyName); - Assembly? assembly; if (_assemblyResolver is not null) { assembly = _assemblyResolver(name); if (assembly is null && _throwOnError) { - throw new FileNotFoundException(SR.Format(SR.FileNotFound_ResolveAssembly, assemblyName)); + throw new FileNotFoundException(SR.Format(SR.FileNotFound_ResolveAssembly, name.FullName)); } } else @@ -96,13 +95,11 @@ private static bool CheckTopLevelAssemblyQualifiedName() Justification = "TypeNameParser.GetType is marked as RequiresUnreferencedCode.")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "TypeNameParser.GetType is marked as RequiresUnreferencedCode.")] - private Type? GetType(string typeName, ReadOnlySpan nestedTypeNames, string? assemblyNameIfAny) + private Type? GetType(string escapedTypeName, ReadOnlySpan nestedTypeNames, Metadata.TypeName parsedName) { - Assembly? assembly = (assemblyNameIfAny is not null) ? ResolveAssembly(assemblyNameIfAny) : null; + Assembly? assembly = (parsedName.AssemblyName is not null) ? ResolveAssembly(parsedName.AssemblyName.ToAssemblyName()) : null; // Both the external type resolver and the default type resolvers expect escaped type names - string escapedTypeName = EscapeTypeName(typeName); - Type? type; // Resolve the top level type. @@ -153,7 +150,7 @@ private static bool CheckTopLevelAssemblyQualifiedName() if (_throwOnError) { throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveNestedType, - nestedTypeNames[i], (i > 0) ? nestedTypeNames[i - 1] : typeName)); + nestedTypeNames[i], (i > 0) ? nestedTypeNames[i - 1] : escapedTypeName)); } return null; } diff --git a/src/mono/browser/build/BrowserWasmApp.targets b/src/mono/browser/build/BrowserWasmApp.targets index aa231c45d8b7cc..d75513604304c6 100644 --- a/src/mono/browser/build/BrowserWasmApp.targets +++ b/src/mono/browser/build/BrowserWasmApp.targets @@ -260,6 +260,8 @@ $(_EmccOptimizationFlagDefault) $(EmccCompileOptimizationFlag) + -O2 + $(WasmCompileOptimizationFlag) -O2 $(WasmCompileOptimizationFlag) $(EmccLinkOptimizationFlag) @@ -406,8 +408,9 @@ - <_BitcodeLDFlags Include="@(_EmccLDFlags)" /> - <_BitcodeLDFlags Include="$(EmccExtraBitcodeLDFlags)" /> + <_BitcodeCompileFlags Include="$(WasmBitcodeCompileOptimizationFlag)" /> + <_BitcodeCompileFlags Include="@(_EmccCommonFlags)" /> + <_BitcodeCompileFlags Include="$(EmccExtraBitcodeCompilationFlags)" /> diff --git a/src/mono/browser/runtime/cancelable-promise.ts b/src/mono/browser/runtime/cancelable-promise.ts index c82cbdacb19609..6964bee80dc538 100644 --- a/src/mono/browser/runtime/cancelable-promise.ts +++ b/src/mono/browser/runtime/cancelable-promise.ts @@ -166,9 +166,7 @@ export class PromiseHolder extends ManagedObject { try { mono_assert(!this.isPosted, "Promise is already posted to managed."); this.isPosted = true; - if (WasmEnableThreads) { - forceThreadMemoryViewRefresh(); - } + forceThreadMemoryViewRefresh(); // we can unregister the GC handle just on JS side teardown_managed_proxy(this, this.gc_handle, /*skipManaged: */ true); diff --git a/src/mono/browser/runtime/corebindings.c b/src/mono/browser/runtime/corebindings.c index 485ba3189af6e2..39b25e5bff333d 100644 --- a/src/mono/browser/runtime/corebindings.c +++ b/src/mono/browser/runtime/corebindings.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,7 @@ typedef void (*background_job_cb)(void); void mono_wasm_bind_assembly_exports (char *assembly_name); void mono_wasm_assembly_get_entry_point (char *assembly_name, int auto_insert_breakpoint, MonoMethod **method_out); -void mono_wasm_get_assembly_export (char *assembly_name, char *namespace, char *classname, char *methodname, MonoMethod **method_out); +void mono_wasm_get_assembly_export (char *assembly_name, char *namespace, char *classname, char *methodname, int signature_hash, MonoMethod **method_out); #ifndef DISABLE_THREADS void mono_wasm_release_cs_owned_object_post (pthread_t target_tid, int js_handle); @@ -58,17 +59,17 @@ extern void mono_wasm_invoke_jsimport_ST (int function_handle, void *args); #endif /* DISABLE_THREADS */ // HybridGlobalization -extern void mono_wasm_change_case_invariant (const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper, int *is_exception, MonoObject** ex_result); -extern void mono_wasm_change_case (MonoString **culture, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper, int *is_exception, MonoObject** ex_result); -extern int mono_wasm_compare_string (MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *is_exception, MonoObject** ex_result); -extern mono_bool mono_wasm_starts_with (MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *is_exception, MonoObject** ex_result); -extern mono_bool mono_wasm_ends_with (MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *is_exception, MonoObject** ex_result); -extern int mono_wasm_index_of (MonoString **culture, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool fromBeginning, int *is_exception, MonoObject** ex_result); -extern int mono_wasm_get_calendar_info (MonoString **culture, int32_t calendarId, const uint16_t* result, int32_t resultLength, int *is_exception, MonoObject** ex_result); -extern int mono_wasm_get_locale_info (MonoString **locale, MonoString **culture, const uint16_t* result, int32_t resultLength, int *is_exception, MonoObject** ex_result); -extern int mono_wasm_get_culture_info (MonoString **culture, const uint16_t* result, int32_t resultLength, int *is_exception, MonoObject** ex_result); -extern int mono_wasm_get_first_day_of_week (MonoString **culture, int *is_exception, MonoObject** ex_result); -extern int mono_wasm_get_first_week_of_year (MonoString **culture, int *is_exception, MonoObject** ex_result); +extern char16_t* mono_wasm_change_case_invariant (const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper); +extern char16_t* mono_wasm_change_case (const uint16_t* culture, int32_t cultureLength, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper); +extern char16_t* mono_wasm_compare_string (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, int *resultPtr); +extern char16_t* mono_wasm_starts_with (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool *resultPtr); +extern char16_t* mono_wasm_ends_with (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool *resultPtr); +extern char16_t* mono_wasm_index_of (const uint16_t* culture, int32_t cultureLength, const uint16_t* str1, int32_t str1Length, const uint16_t* str2, int32_t str2Length, int32_t options, mono_bool fromBeginning, int *resultPtr); +extern char16_t* mono_wasm_get_calendar_info (const uint16_t* culture, int32_t cultureLength, int32_t calendarId, const uint16_t* result, int32_t resultMaxLength, int *resultLength); +extern char16_t* mono_wasm_get_culture_info (const uint16_t* culture, int32_t cultureLength, const uint16_t* result, int32_t resultMaxLength, int *resultLength); +extern char16_t* mono_wasm_get_locale_info (const uint16_t* locale, int32_t localeLength, const uint16_t* culture, int32_t cultureLength, const uint16_t* result, int32_t resultMaxLength, int *resultLength); +extern char16_t* mono_wasm_get_first_day_of_week (const uint16_t* culture, int32_t cultureLength, int *resultPtr); +extern char16_t* mono_wasm_get_first_week_of_year (const uint16_t* culture, int32_t cultureLength, int *resultPtr); void bindings_initialize_internals (void) { @@ -230,13 +231,14 @@ void mono_wasm_bind_assembly_exports (char *assembly_name) } } -void mono_wasm_get_assembly_export (char *assembly_name, char *namespace, char *classname, char *methodname, MonoMethod **method_out) +void mono_wasm_get_assembly_export (char *assembly_name, char *namespace, char *classname, char *methodname, int signature_hash, MonoMethod **method_out) { MonoError error; MonoAssembly* assembly; MonoImage *image; MonoClass *klass; MonoMethod *method=NULL; + char real_method_name_buffer[4096]; *method_out = NULL; assert (assembly_name); @@ -247,10 +249,15 @@ void mono_wasm_get_assembly_export (char *assembly_name, char *namespace, char * klass = mono_class_from_name (image, namespace, classname); assert (klass); - method = mono_class_get_method_from_name (klass, methodname, -1); + + snprintf(real_method_name_buffer, 4096, "__Wrapper_%s_%d", methodname, signature_hash); + + method = mono_class_get_method_from_name (klass, real_method_name_buffer, -1); assert (method); *method_out = method; + // This is freed by _mono_wasm_assembly_load for some reason + // free (assembly_name); free (namespace); free (classname); free (methodname); diff --git a/src/mono/browser/runtime/hybrid-globalization/calendar.ts b/src/mono/browser/runtime/hybrid-globalization/calendar.ts index d3944f514ce854..2d87d1c085cc04 100644 --- a/src/mono/browser/runtime/hybrid-globalization/calendar.ts +++ b/src/mono/browser/runtime/hybrid-globalization/calendar.ts @@ -2,23 +2,20 @@ // The .NET Foundation licenses this file to you under the MIT license. /* eslint-disable no-inner-declarations */ -import { mono_wasm_new_external_root } from "../roots"; -import { monoStringToString, stringToUTF16 } from "../strings"; -import { MonoObject, MonoObjectRef, MonoString, MonoStringRef } from "../types/internal"; -import { Int32Ptr } from "../types/emscripten"; -import { wrap_error_root, wrap_no_error_root } from "./helpers"; +import { stringToUTF16, stringToUTF16Ptr, utf16ToString } from "../strings"; +import { VoidPtrNull } from "../types/internal"; +import { Int32Ptr, VoidPtr } from "../types/emscripten"; import { INNER_SEPARATOR, OUTER_SEPARATOR, normalizeSpaces } from "./helpers"; +import { setI32 } from "../memory"; const MONTH_CODE = "MMMM"; const YEAR_CODE = "yyyy"; const DAY_CODE = "d"; // this function joins all calendar info with OUTER_SEPARATOR into one string and returns it back to managed code -export function mono_wasm_get_calendar_info (culture: MonoStringRef, calendarId: number, dst: number, dstLength: number, isException: Int32Ptr, exAddress: MonoObjectRef): number { - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(exAddress); +export function mono_wasm_get_calendar_info (culture: number, cultureLength: number, calendarId: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const locale = cultureName ? cultureName : undefined; const calendarInfo = { EnglishName: "", @@ -56,18 +53,14 @@ export function mono_wasm_get_calendar_info (culture: MonoStringRef, calendarId: calendarInfo.AbbreviatedEraNames = eraNames.abbreviatedEraNames; const result = Object.values(calendarInfo).join(OUTER_SEPARATOR); - if (result.length > dstLength) { - throw new Error(`Calendar info exceeds length of ${dstLength}.`); + if (result.length > dstMaxLength) { + throw new Error(`Calendar info exceeds length of ${dstMaxLength}.`); } stringToUTF16(dst, dst + 2 * result.length, result); - wrap_no_error_root(isException, exceptionRoot); - return result.length; + setI32(dstLength, result.length); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(isException, ex, exceptionRoot); - return -1; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + return stringToUTF16Ptr(ex.toString()); } } diff --git a/src/mono/browser/runtime/hybrid-globalization/change-case.ts b/src/mono/browser/runtime/hybrid-globalization/change-case.ts index 762eacc94c26bc..437aabb42bfcd2 100644 --- a/src/mono/browser/runtime/hybrid-globalization/change-case.ts +++ b/src/mono/browser/runtime/hybrid-globalization/change-case.ts @@ -1,16 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_new_external_root } from "../roots"; -import { monoStringToString, utf16ToStringLoop, stringToUTF16 } from "../strings"; -import { MonoObject, MonoObjectRef, MonoString, MonoStringRef } from "../types/internal"; -import { Int32Ptr } from "../types/emscripten"; -import { wrap_error_root, wrap_no_error_root } from "./helpers"; +import { utf16ToStringLoop, stringToUTF16, stringToUTF16Ptr, utf16ToString } from "../strings"; +import { VoidPtrNull } from "../types/internal"; +import { VoidPtr } from "../types/emscripten"; import { localHeapViewU16, setU16_local } from "../memory"; import { isSurrogate } from "./helpers"; -export function mono_wasm_change_case_invariant (src: number, srcLength: number, dst: number, dstLength: number, toUpper: number, is_exception: Int32Ptr, ex_address: MonoObjectRef): void { - const exceptionRoot = mono_wasm_new_external_root(ex_address); +export function mono_wasm_change_case_invariant (src: number, srcLength: number, dst: number, dstLength: number, toUpper: number): VoidPtr { try { const input = utf16ToStringLoop(src, src + 2 * srcLength); const result = toUpper ? input.toUpperCase() : input.toLowerCase(); @@ -18,8 +15,7 @@ export function mono_wasm_change_case_invariant (src: number, srcLength: number, // originally we do not support this expansion if (result.length <= dstLength) { stringToUTF16(dst, dst + 2 * dstLength, result); - wrap_no_error_root(is_exception, exceptionRoot); - return; + return VoidPtrNull; } // workaround to maintain the ICU-like behavior @@ -59,19 +55,15 @@ export function mono_wasm_change_case_invariant (src: number, srcLength: number, } } } - wrap_no_error_root(is_exception, exceptionRoot); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(is_exception, ex, exceptionRoot); - } finally { - exceptionRoot.release(); + return stringToUTF16Ptr(ex.toString()); } } -export function mono_wasm_change_case (culture: MonoStringRef, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number, is_exception: Int32Ptr, ex_address: MonoObjectRef): void { - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(ex_address); +export function mono_wasm_change_case (culture: number, cultureLength: number, src: number, srcLength: number, dst: number, dstLength: number, toUpper: number): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); if (!cultureName) throw new Error("Cannot change case, the culture name is null."); const input = utf16ToStringLoop(src, src + 2 * srcLength); @@ -79,8 +71,7 @@ export function mono_wasm_change_case (culture: MonoStringRef, src: number, srcL if (result.length <= input.length) { stringToUTF16(dst, dst + 2 * dstLength, result); - wrap_no_error_root(is_exception, exceptionRoot); - return; + return VoidPtrNull; } // workaround to maintain the ICU-like behavior const heapI16 = localHeapViewU16(); @@ -119,12 +110,9 @@ export function mono_wasm_change_case (culture: MonoStringRef, src: number, srcL } } } - wrap_no_error_root(is_exception, exceptionRoot); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(is_exception, ex, exceptionRoot); - } finally { - cultureRoot.release(); - exceptionRoot.release(); + return stringToUTF16Ptr(ex.toString()); } } diff --git a/src/mono/browser/runtime/hybrid-globalization/collations.ts b/src/mono/browser/runtime/hybrid-globalization/collations.ts index 523f63307e278c..b329b39b15d0e1 100644 --- a/src/mono/browser/runtime/hybrid-globalization/collations.ts +++ b/src/mono/browser/runtime/hybrid-globalization/collations.ts @@ -1,113 +1,106 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_new_external_root } from "../roots"; -import { monoStringToString, utf16ToString } from "../strings"; -import { MonoObject, MonoObjectRef, MonoString, MonoStringRef } from "../types/internal"; -import { Int32Ptr } from "../types/emscripten"; -import { wrap_error_root, wrap_no_error_root } from "./helpers"; +import { stringToUTF16Ptr, utf16ToString } from "../strings"; +import { VoidPtrNull } from "../types/internal"; +import { Int32Ptr, VoidPtr } from "../types/emscripten"; import { GraphemeSegmenter } from "./grapheme-segmenter"; +import { setI32 } from "../memory"; const COMPARISON_ERROR = -2; const INDEXING_ERROR = -1; let graphemeSegmenterCached: GraphemeSegmenter | null; -export function mono_wasm_compare_string (culture: MonoStringRef, str1: number, str1Length: number, str2: number, str2Length: number, options: number, is_exception: Int32Ptr, ex_address: MonoObjectRef): number { - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(ex_address); +export function mono_wasm_compare_string (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const string1 = utf16ToString(str1, (str1 + 2 * str1Length)); const string2 = utf16ToString(str2, (str2 + 2 * str2Length)); const casePicker = (options & 0x1f); const locale = cultureName ? cultureName : undefined; - wrap_no_error_root(is_exception, exceptionRoot); - return compareStrings(string1, string2, locale, casePicker); + const result = compareStrings(string1, string2, locale, casePicker); + setI32(resultPtr, result); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(is_exception, ex, exceptionRoot); - return COMPARISON_ERROR; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(resultPtr, COMPARISON_ERROR); + return stringToUTF16Ptr(ex.toString()); } } -export function mono_wasm_starts_with (culture: MonoStringRef, str1: number, str1Length: number, str2: number, str2Length: number, options: number, is_exception: Int32Ptr, ex_address: MonoObjectRef): number { - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(ex_address); +export function mono_wasm_starts_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const prefix = decodeToCleanString(str2, str2Length); // no need to look for an empty string - if (prefix.length == 0) - return 1; // true + if (prefix.length == 0) { + setI32(resultPtr, 1); // true + return VoidPtrNull; + } const source = decodeToCleanString(str1, str1Length); - if (source.length < prefix.length) - return 0; //false + if (source.length < prefix.length) { + setI32(resultPtr, 0); // false + return VoidPtrNull; + } const sourceOfPrefixLength = source.slice(0, prefix.length); const casePicker = (options & 0x1f); const locale = cultureName ? cultureName : undefined; - const result = compareStrings(sourceOfPrefixLength, prefix, locale, casePicker); - wrap_no_error_root(is_exception, exceptionRoot); - return result === 0 ? 1 : 0; // equals ? true : false + const cmpResult = compareStrings(sourceOfPrefixLength, prefix, locale, casePicker); + const result = cmpResult === 0 ? 1 : 0; // equals ? true : false + setI32(resultPtr, result); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(is_exception, ex, exceptionRoot); - return INDEXING_ERROR; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(resultPtr, INDEXING_ERROR); + return stringToUTF16Ptr(ex.toString()); } } -export function mono_wasm_ends_with (culture: MonoStringRef, str1: number, str1Length: number, str2: number, str2Length: number, options: number, is_exception: Int32Ptr, ex_address: MonoObjectRef): number { - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(ex_address); +export function mono_wasm_ends_with (culture: number, cultureLength: number, str1: number, str1Length: number, str2: number, str2Length: number, options: number, resultPtr: Int32Ptr): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const suffix = decodeToCleanString(str2, str2Length); - if (suffix.length == 0) - return 1; // true + if (suffix.length == 0) { + setI32(resultPtr, 1); // true + return VoidPtrNull; + } const source = decodeToCleanString(str1, str1Length); const diff = source.length - suffix.length; - if (diff < 0) - return 0; //false + if (diff < 0) { + setI32(resultPtr, 0); // false + return VoidPtrNull; + } const sourceOfSuffixLength = source.slice(diff, source.length); const casePicker = (options & 0x1f); const locale = cultureName ? cultureName : undefined; - const result = compareStrings(sourceOfSuffixLength, suffix, locale, casePicker); - wrap_no_error_root(is_exception, exceptionRoot); - return result === 0 ? 1 : 0; // equals ? true : false + const cmpResult = compareStrings(sourceOfSuffixLength, suffix, locale, casePicker); + const result = cmpResult === 0 ? 1 : 0; // equals ? true : false + setI32(resultPtr, result); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(is_exception, ex, exceptionRoot); - return INDEXING_ERROR; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(resultPtr, INDEXING_ERROR); + return stringToUTF16Ptr(ex.toString()); } } -export function mono_wasm_index_of (culture: MonoStringRef, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, is_exception: Int32Ptr, ex_address: MonoObjectRef): number { - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(ex_address); +export function mono_wasm_index_of (culture: number, cultureLength: number, needlePtr: number, needleLength: number, srcPtr: number, srcLength: number, options: number, fromBeginning: number, resultPtr: Int32Ptr): VoidPtr { try { const needle = utf16ToString(needlePtr, (needlePtr + 2 * needleLength)); // no need to look for an empty string if (cleanString(needle).length == 0) { - wrap_no_error_root(is_exception, exceptionRoot); - return fromBeginning ? 0 : srcLength; + setI32(resultPtr, fromBeginning ? 0 : srcLength); + return VoidPtrNull; } const source = utf16ToString(srcPtr, (srcPtr + 2 * srcLength)); // no need to look in an empty string if (cleanString(source).length == 0) { - wrap_no_error_root(is_exception, exceptionRoot); - return fromBeginning ? 0 : srcLength; + setI32(resultPtr, fromBeginning ? 0 : srcLength); + return VoidPtrNull; } - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const locale = cultureName ? cultureName : undefined; const casePicker = (options & 0x1f); let result = -1; @@ -148,14 +141,11 @@ export function mono_wasm_index_of (culture: MonoStringRef, needlePtr: number, n break; } } - wrap_no_error_root(is_exception, exceptionRoot); - return result; + setI32(resultPtr, result); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(is_exception, ex, exceptionRoot); - return INDEXING_ERROR; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(resultPtr, INDEXING_ERROR); + return stringToUTF16Ptr(ex.toString()); } function checkMatchFound (str1: string, str2: string, locale: string | undefined, casePicker: number): boolean { diff --git a/src/mono/browser/runtime/hybrid-globalization/culture-info.ts b/src/mono/browser/runtime/hybrid-globalization/culture-info.ts index 03bebd9ec65ee2..70b36296407bbb 100644 --- a/src/mono/browser/runtime/hybrid-globalization/culture-info.ts +++ b/src/mono/browser/runtime/hybrid-globalization/culture-info.ts @@ -1,18 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { wrap_error_root, wrap_no_error_root } from "./helpers"; -import { mono_wasm_new_external_root } from "../roots"; -import { monoStringToString, stringToUTF16 } from "../strings"; -import { Int32Ptr } from "../types/emscripten"; -import { MonoObject, MonoObjectRef, MonoString, MonoStringRef } from "../types/internal"; +import { setI32 } from "../memory"; +import { stringToUTF16, stringToUTF16Ptr, utf16ToString } from "../strings"; +import { Int32Ptr, VoidPtr } from "../types/emscripten"; +import { VoidPtrNull } from "../types/internal"; import { OUTER_SEPARATOR, normalizeLocale, normalizeSpaces } from "./helpers"; -export function mono_wasm_get_culture_info (culture: MonoStringRef, dst: number, dstLength: number, isException: Int32Ptr, exAddress: MonoObjectRef): number { - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(exAddress); +export function mono_wasm_get_culture_info (culture: number, cultureLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const cultureInfo = { AmDesignator: "", PmDesignator: "", @@ -26,18 +23,15 @@ export function mono_wasm_get_culture_info (culture: MonoStringRef, dst: number, cultureInfo.LongTimePattern = getLongTimePattern(canonicalLocale, designators); cultureInfo.ShortTimePattern = getShortTimePattern(cultureInfo.LongTimePattern); const result = Object.values(cultureInfo).join(OUTER_SEPARATOR); - if (result.length > dstLength) { - throw new Error(`Culture info exceeds length of ${dstLength}.`); + if (result.length > dstMaxLength) { + throw new Error(`Culture info exceeds length of ${dstMaxLength}.`); } stringToUTF16(dst, dst + 2 * result.length, result); - wrap_no_error_root(isException, exceptionRoot); - return result.length; + setI32(dstLength, result.length); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(isException, ex, exceptionRoot); - return -1; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(dstLength, -1); + return stringToUTF16Ptr(ex.toString()); } } diff --git a/src/mono/browser/runtime/hybrid-globalization/helpers.ts b/src/mono/browser/runtime/hybrid-globalization/helpers.ts index 74134c4ca3cc1d..0cd2294447226f 100644 --- a/src/mono/browser/runtime/hybrid-globalization/helpers.ts +++ b/src/mono/browser/runtime/hybrid-globalization/helpers.ts @@ -1,12 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { normalize_exception } from "../invoke-js"; -import { receiveWorkerHeapViews, setI32_unchecked } from "../memory"; -import { stringToMonoStringRoot } from "../strings"; -import { Int32Ptr } from "../types/emscripten"; -import { MonoObject, WasmRoot } from "../types/internal"; - const SURROGATE_HIGHER_START = "\uD800"; const SURROGATE_HIGHER_END = "\uDBFF"; const SURROGATE_LOWER_START = "\uDC00"; @@ -48,29 +42,3 @@ export function isSurrogate (str: string, startIdx: number): boolean { SURROGATE_LOWER_START <= str[startIdx + 1] && str[startIdx + 1] <= SURROGATE_LOWER_END; } - -function _wrap_error_flag (is_exception: Int32Ptr | null, ex: any): string { - const res = normalize_exception(ex); - if (is_exception) { - receiveWorkerHeapViews(); - setI32_unchecked(is_exception, 1); - } - return res; -} - -export function wrap_error_root (is_exception: Int32Ptr | null, ex: any, result: WasmRoot): void { - const res = _wrap_error_flag(is_exception, ex); - stringToMonoStringRoot(res, result); -} - -// TODO replace it with replace it with UTF16 char*, no GC root needed -// https://github.com/dotnet/runtime/issues/98365 -export function wrap_no_error_root (is_exception: Int32Ptr | null, result?: WasmRoot): void { - if (is_exception) { - receiveWorkerHeapViews(); - setI32_unchecked(is_exception, 0); - } - if (result) { - result.clear(); - } -} diff --git a/src/mono/browser/runtime/hybrid-globalization/locales.ts b/src/mono/browser/runtime/hybrid-globalization/locales.ts index 252dfe1badf9e2..0f04519efdfd32 100644 --- a/src/mono/browser/runtime/hybrid-globalization/locales.ts +++ b/src/mono/browser/runtime/hybrid-globalization/locales.ts @@ -1,27 +1,23 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { wrap_error_root, wrap_no_error_root } from "./helpers"; -import { mono_wasm_new_external_root } from "../roots"; -import { monoStringToString, stringToUTF16 } from "../strings"; -import { Int32Ptr } from "../types/emscripten"; -import { MonoObject, MonoObjectRef, MonoString, MonoStringRef } from "../types/internal"; +import { setI32 } from "../memory"; +import { stringToUTF16, stringToUTF16Ptr, utf16ToString } from "../strings"; +import { Int32Ptr, VoidPtr } from "../types/emscripten"; +import { VoidPtrNull } from "../types/internal"; import { OUTER_SEPARATOR, normalizeLocale } from "./helpers"; -export function mono_wasm_get_locale_info (culture: MonoStringRef, locale: MonoStringRef, dst: number, dstLength: number, isException: Int32Ptr, exAddress: MonoObjectRef): number { - const localeRoot = mono_wasm_new_external_root(locale), - cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(exAddress); +export function mono_wasm_get_locale_info (culture: number, cultureLength: number, locale: number, localeLength: number, dst: number, dstMaxLength: number, dstLength: Int32Ptr): VoidPtr { try { - const localeNameOriginal = monoStringToString(localeRoot); + const localeNameOriginal = utf16ToString(locale, (locale + 2 * localeLength)); const localeName = normalizeLocale(localeNameOriginal); if (!localeName && localeNameOriginal) { // handle non-standard or malformed locales by forwarding the locale code stringToUTF16(dst, dst + 2 * localeNameOriginal.length, localeNameOriginal); - wrap_no_error_root(isException, exceptionRoot); - return localeNameOriginal.length; + setI32(dstLength, localeNameOriginal.length); + return VoidPtrNull; } - const cultureNameOriginal = monoStringToString(cultureRoot); + const cultureNameOriginal = utf16ToString(culture, (culture + 2 * cultureLength)); const cultureName = normalizeLocale(cultureNameOriginal); if (!localeName || !cultureName) @@ -41,16 +37,16 @@ export function mono_wasm_get_locale_info (culture: MonoStringRef, locale: MonoS const language = localeParts.join("-"); languageName = new Intl.DisplayNames([cultureName], { type: "language" }).of(language); } catch (error) { - if (error instanceof RangeError && error.message === "invalid_argument") { + if (error instanceof RangeError) { // if it failed from this reason then cultureName is in a form "language-script", without region try { languageName = new Intl.DisplayNames([cultureName], { type: "language" }).of(localeName); } catch (error) { - if (error instanceof RangeError && error.message === "invalid_argument" && localeNameOriginal) { + if (error instanceof RangeError && localeNameOriginal) { // handle non-standard or malformed locales by forwarding the locale code, e.g. "xx-u-xx" stringToUTF16(dst, dst + 2 * localeNameOriginal.length, localeNameOriginal); - wrap_no_error_root(isException, exceptionRoot); - return localeNameOriginal.length; + setI32(dstLength, localeNameOriginal.length); + return VoidPtrNull; } throw error; } @@ -67,54 +63,41 @@ export function mono_wasm_get_locale_info (culture: MonoStringRef, locale: MonoS if (!result) throw new Error(`Locale info for locale=${localeName} is null or empty.`); - if (result.length > dstLength) - throw new Error(`Locale info for locale=${localeName} exceeds length of ${dstLength}.`); + if (result.length > dstMaxLength) + throw new Error(`Locale info for locale=${localeName} exceeds length of ${dstMaxLength}.`); stringToUTF16(dst, dst + 2 * result.length, result); - wrap_no_error_root(isException, exceptionRoot); - return result.length; + setI32(dstLength, result.length); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(isException, ex, exceptionRoot); - return -1; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(dstLength, -1); + return stringToUTF16Ptr(ex.toString()); } } -export function mono_wasm_get_first_day_of_week (culture: MonoStringRef, isException: Int32Ptr, exAddress: MonoObjectRef): number { - - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(exAddress); +export function mono_wasm_get_first_day_of_week (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const canonicalLocale = normalizeLocale(cultureName); - wrap_no_error_root(isException, exceptionRoot); - return getFirstDayOfWeek(canonicalLocale); + const result = getFirstDayOfWeek(canonicalLocale); + setI32(resultPtr, result); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(isException, ex, exceptionRoot); - return -1; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(resultPtr, -1); + return stringToUTF16Ptr(ex.toString()); } } -export function mono_wasm_get_first_week_of_year (culture: MonoStringRef, isException: Int32Ptr, exAddress: MonoObjectRef): number { - - const cultureRoot = mono_wasm_new_external_root(culture), - exceptionRoot = mono_wasm_new_external_root(exAddress); +export function mono_wasm_get_first_week_of_year (culture: number, cultureLength: number, resultPtr: Int32Ptr): VoidPtr { try { - const cultureName = monoStringToString(cultureRoot); + const cultureName = utf16ToString(culture, (culture + 2 * cultureLength)); const canonicalLocale = normalizeLocale(cultureName); - wrap_no_error_root(isException, exceptionRoot); - return getFirstWeekOfYear(canonicalLocale); + const result = getFirstWeekOfYear(canonicalLocale); + setI32(resultPtr, result); + return VoidPtrNull; } catch (ex: any) { - wrap_error_root(isException, ex, exceptionRoot); - return -1; - } finally { - cultureRoot.release(); - exceptionRoot.release(); + setI32(resultPtr, -1); + return stringToUTF16Ptr(ex.toString()); } } @@ -130,8 +113,8 @@ function getFirstDayOfWeek (locale: string) { if (saturdayLocales.includes(locale)) { return 6; } - const sundayLanguages = ["zh", "th", "pt", "mr", "ml", "ko", "kn", "ja", "id", "hi", "he", "gu", "fil", "bn", "am", "ar"]; - const sundayLocales = ["ta-SG", "ta-IN", "sw-KE", "ms-SG", "fr-CA", "es-MX", "en-US", "en-ZW", "en-ZA", "en-WS", "en-VI", "en-UM", "en-TT", "en-SG", "en-PR", "en-PK", "en-PH", "en-MT", "en-MO", "en-MH", "en-KE", "en-JM", "en-IN", "en-IL", "en-HK", "en-GU", "en-DM", "en-CA", "en-BZ", "en-BW", "en-BS", "en-AU", "en-AS", "en-AG"]; + const sundayLanguages = ["th", "pt", "mr", "ml", "ko", "kn", "ja", "id", "hi", "he", "gu", "fil", "bn", "am", "ar", "te"]; + const sundayLocales = ["ta-SG", "ta-IN", "sw-KE", "ms-SG", "fr-CA", "es-MX", "en-US", "en-ZW", "en-ZA", "en-WS", "en-VI", "en-UM", "en-TT", "en-SG", "en-PR", "en-PK", "en-PH", "en-MT", "en-MO", "en-MH", "en-KE", "en-JM", "en-IN", "en-IL", "en-HK", "en-GU", "en-DM", "en-CA", "en-BZ", "en-BW", "en-BS", "en-AS", "en-AG", "zh-Hans-HK", "zh-SG", "zh-HK", "zh-TW"]; // "en-AU" is Monday in chrome, so firefox should be in line const localeLang = locale.split("-")[0]; if (sundayLanguages.includes(localeLang) || sundayLocales.includes(locale)) { return 0; @@ -151,8 +134,8 @@ function getFirstWeekOfYear (locale: string) { } // Firefox does not support it rn but we can make a temporary workaround for it, // that should be removed when it starts being supported: - const firstFourDayWeekLocales = ["pt-PT", "fr-CH", "fr-FR", "fr-BE", "es-ES", "en-SE", "en-NL", "en-JE", "en-IM", "en-IE", "en-GI", "en-GG", "en-GB", "en-FJ", "en-FI", "en-DK", "en-DE", "en-CH", "en-BE", "en-AT", "el-GR"]; - const firstFourDayWeekLanguages = ["sv", "sk", "ru", "pl", "nl", "no", "lt", "it", "hu", "fi", "et", "de", "da", "cs", "ca", "bg"]; + const firstFourDayWeekLocales = ["pt-PT", "fr-CH", "fr-FR", "fr-BE", "es-ES", "en-SE", "en-NL", "en-JE", "en-IM", "en-IE", "en-GI", "en-GG", "en-GB", "en-FJ", "en-FI", "en-DK", "en-DE", "en-CH", "en-BE", "en-AT", "el-GR", "nl-BE", "nl-NL"]; + const firstFourDayWeekLanguages = ["sv", "sk", "ru", "pl", "no", "nb", "lt", "it", "hu", "fi", "et", "de", "da", "cs", "ca", "bg"]; const localeLang = locale.split("-")[0]; if (firstFourDayWeekLocales.includes(locale) || firstFourDayWeekLanguages.includes(localeLang)) { return 2; diff --git a/src/mono/browser/runtime/loader/run.ts b/src/mono/browser/runtime/loader/run.ts index 5c5010a2a5356f..0bd2dd60d80852 100644 --- a/src/mono/browser/runtime/loader/run.ts +++ b/src/mono/browser/runtime/loader/run.ts @@ -158,6 +158,10 @@ export class HostBuilder implements DotnetHostBuilder { interpreterPgo: value, interpreterPgoSaveDelay: autoSaveDelay }); + if (monoConfig.runtimeOptions) + monoConfig.runtimeOptions.push("--interp-pgo-recording"); + else + monoConfig.runtimeOptions = ["--interp-pgo-recording"]; return this; } catch (err) { mono_exit(1, err); @@ -268,9 +272,10 @@ export class HostBuilder implements DotnetHostBuilder { withRuntimeOptions (runtimeOptions: string[]): DotnetHostBuilder { try { mono_assert(runtimeOptions && Array.isArray(runtimeOptions), "must be array of strings"); - deep_merge_config(monoConfig, { - runtimeOptions - }); + if (monoConfig.runtimeOptions) + monoConfig.runtimeOptions.push(...runtimeOptions); + else + monoConfig.runtimeOptions = runtimeOptions; return this; } catch (err) { mono_exit(1, err); diff --git a/src/mono/browser/runtime/marshal.ts b/src/mono/browser/runtime/marshal.ts index c0ece106f53b2a..b26a94926f88e7 100644 --- a/src/mono/browser/runtime/marshal.ts +++ b/src/mono/browser/runtime/marshal.ts @@ -65,9 +65,7 @@ const enum JSBindingHeaderOffsets { } export function alloc_stack_frame (size: number): JSMarshalerArguments { - if (WasmEnableThreads) { - forceThreadMemoryViewRefresh(); - } + forceThreadMemoryViewRefresh(); const bytes = JavaScriptMarshalerArgSize * size; const args = Module.stackAlloc(bytes) as any; _zero_region(args, bytes); @@ -145,7 +143,7 @@ export function get_signature_arg2_type (sig: JSMarshalerType): MarshalerType { export function get_signature_arg3_type (sig: JSMarshalerType): MarshalerType { mono_assert(sig, "Null sig"); - return getU8(sig + JSBindingTypeOffsets.Arg2MarshalerType); + return getU8(sig + JSBindingTypeOffsets.Arg3MarshalerType); } export function get_signature_argument_count (signature: JSFunctionSignature): number { diff --git a/src/mono/browser/runtime/memory.ts b/src/mono/browser/runtime/memory.ts index 5a0ac71d3b3295..52b5b581a5bd71 100644 --- a/src/mono/browser/runtime/memory.ts +++ b/src/mono/browser/runtime/memory.ts @@ -447,8 +447,8 @@ export function copyBytes (srcPtr: VoidPtr, dstPtr: VoidPtr, bytes: number): voi // on non-MT build, this will be a no-op trimmed by rollup export function receiveWorkerHeapViews () { if (!WasmEnableThreads) return; - const memory = runtimeHelpers.getMemory(); - if (memory.buffer !== Module.HEAPU8.buffer) { + const wasmMemory = runtimeHelpers.getMemory(); + if (wasmMemory.buffer !== Module.HEAPU8.buffer) { runtimeHelpers.updateMemoryViews(); } } @@ -484,5 +484,7 @@ export function forceThreadMemoryViewRefresh () { This only works because their implementation does not skip doing work even when you ask to grow by 0 pages. */ wasmMemory.grow(0); - runtimeHelpers.updateMemoryViews(); + if (wasmMemory.buffer !== Module.HEAPU8.buffer) { + runtimeHelpers.updateMemoryViews(); + } } diff --git a/src/mono/browser/runtime/runtime.c b/src/mono/browser/runtime/runtime.c index 2132dd9906d597..8ddcdbce138637 100644 --- a/src/mono/browser/runtime/runtime.c +++ b/src/mono/browser/runtime/runtime.c @@ -65,6 +65,7 @@ int mono_wasm_enable_gc = 1; /* Missing from public headers */ +char *mono_fixup_symbol_name (char *key); void mono_icall_table_init (void); void mono_wasm_enable_debugging (int); void mono_ee_interp_init (const char *opts); @@ -213,13 +214,8 @@ get_native_to_interp (MonoMethod *method, void *extra_arg) assert (strlen (name) < 100); snprintf (key, sizeof(key), "%s_%s_%s", name, class_name, method_name); - len = strlen (key); - for (int i = 0; i < len; ++i) { - if (key [i] == '.') - key [i] = '_'; - } - - addr = wasm_dl_get_native_to_interp (key, extra_arg); + char* fixedName = mono_fixup_symbol_name(key); + addr = wasm_dl_get_native_to_interp (fixedName, extra_arg); MONO_EXIT_GC_UNSAFE; return addr; } diff --git a/src/mono/browser/runtime/scheduling.ts b/src/mono/browser/runtime/scheduling.ts index 0be8cb19a72336..62c02961c5ce49 100644 --- a/src/mono/browser/runtime/scheduling.ts +++ b/src/mono/browser/runtime/scheduling.ts @@ -79,9 +79,7 @@ export function mono_wasm_schedule_timer (shortestDueTimeMs: number): void { function mono_wasm_schedule_timer_tick () { if (WasmEnableThreads) return; Module.maybeExit(); - if (WasmEnableThreads) { - forceThreadMemoryViewRefresh(); - } + forceThreadMemoryViewRefresh(); if (!loaderHelpers.is_runtime_running()) { return; } diff --git a/src/mono/browser/runtime/web-socket.ts b/src/mono/browser/runtime/web-socket.ts index d97cc76cefe4a6..b328943ceaa6de 100644 --- a/src/mono/browser/runtime/web-socket.ts +++ b/src/mono/browser/runtime/web-socket.ts @@ -78,9 +78,7 @@ export function ws_wasm_create (uri: string, sub_protocols: string[] | null, rec try { if (ws[wasm_ws_is_aborted]) return; if (!loaderHelpers.is_runtime_running()) return; - if (WasmEnableThreads) { - forceThreadMemoryViewRefresh(); - } + forceThreadMemoryViewRefresh(); open_promise_control.resolve(ws); prevent_timer_throttling(); } catch (error: any) { @@ -91,9 +89,7 @@ export function ws_wasm_create (uri: string, sub_protocols: string[] | null, rec try { if (ws[wasm_ws_is_aborted]) return; if (!loaderHelpers.is_runtime_running()) return; - if (WasmEnableThreads) { - forceThreadMemoryViewRefresh(); - } + forceThreadMemoryViewRefresh(); web_socket_on_message(ws, ev); prevent_timer_throttling(); } catch (error: any) { @@ -105,9 +101,7 @@ export function ws_wasm_create (uri: string, sub_protocols: string[] | null, rec ws.removeEventListener("message", local_on_message); if (ws[wasm_ws_is_aborted]) return; if (!loaderHelpers.is_runtime_running()) return; - if (WasmEnableThreads) { - forceThreadMemoryViewRefresh(); - } + forceThreadMemoryViewRefresh(); ws[wasm_ws_close_received] = true; ws["close_status"] = ev.code; @@ -137,9 +131,7 @@ export function ws_wasm_create (uri: string, sub_protocols: string[] | null, rec try { if (ws[wasm_ws_is_aborted]) return; if (!loaderHelpers.is_runtime_running()) return; - if (WasmEnableThreads) { - forceThreadMemoryViewRefresh(); - } + forceThreadMemoryViewRefresh(); ws.removeEventListener("message", local_on_message); const message = ev.message ? "WebSocket error: " + ev.message diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 8b57badb1a2e38..0d855362d99211 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -401,11 +401,11 @@ <_MonoCMakeArgs Include="-DCMAKE_SYSTEM_VARIANT=maccatalyst" /> <_MonoCPPFLAGS Include="-Wno-overriding-t-option" /> - <_MonoCFlags Condition="'$(TargetArchitecture)' == 'arm64'" Include="-target arm64-apple-ios14.2-macabi" /> - <_MonoCFlags Condition="'$(TargetArchitecture)' == 'x64'" Include="-target x86_64-apple-ios13.5-macabi" /> + <_MonoCFlags Condition="'$(TargetArchitecture)' == 'arm64'" Include="-target arm64-apple-ios$(MacCatalystVersionMin)-macabi" /> + <_MonoCFlags Condition="'$(TargetArchitecture)' == 'x64'" Include="-target x86_64-apple-ios$(MacCatalystVersionMin)-macabi" /> <_MonoCFLAGS Condition="'$(TargetArchitecture)' == 'arm64'" Include="-arch arm64" /> - <_MonoCXXFlags Condition="'$(TargetArchitecture)' == 'arm64'" Include="-target arm64-apple-ios14.2-macabi" /> - <_MonoCXXFlags Condition="'$(TargetArchitecture)' == 'x64'" Include="-target x86_64-apple-ios13.5-macabi" /> + <_MonoCXXFlags Condition="'$(TargetArchitecture)' == 'arm64'" Include="-target arm64-apple-ios$(MacCatalystVersionMin)-macabi" /> + <_MonoCXXFlags Condition="'$(TargetArchitecture)' == 'x64'" Include="-target x86_64-apple-ios$(MacCatalystVersionMin)-macabi" /> <_MonoCXXFLAGS Condition="'$(TargetArchitecture)' == 'arm64'" Include="-arch arm64" /> <_MonoBuildEnv Condition="'$(BuildArchitecture)' == 'arm64'" Include="arch -arch arm64" /> @@ -797,7 +797,7 @@ - + diff --git a/src/mono/sample/Directory.Build.props b/src/mono/sample/Directory.Build.props index 8780899630286b..2d5011ce41f881 100644 --- a/src/mono/sample/Directory.Build.props +++ b/src/mono/sample/Directory.Build.props @@ -5,14 +5,22 @@ true + - $HARNESS_RUNNER - $XHARNESS_OUT + $HARNESS_RUNNER + $XHARNESS_OUT + $XHARNESS_COMMAND + $XHARNESS_ARGS - - %HARNESS_RUNNER% - %XHARNESS_OUT% + %HARNESS_RUNNER% + %XHARNESS_OUT% + %XHARNESS_COMMAND% + %XHARNESS_ARGS% diff --git a/src/mono/sample/wasm/DefaultBrowserSample.targets b/src/mono/sample/wasm/DefaultBrowserSample.targets index d34e280cf19c6d..af224ce9c48af3 100644 --- a/src/mono/sample/wasm/DefaultBrowserSample.targets +++ b/src/mono/sample/wasm/DefaultBrowserSample.targets @@ -7,7 +7,7 @@ -1 true $(WasmXHarnessArgs) --web-server-use-cop - $(ExecXHarnessCmd) wasm test-browser --app=. --browser=Chrome $(XHarnessBrowserPathArg) $(WasmXHarnessArgs) --html-file=index.html --output-directory=$(XHarnessOutput) -- $(MSBuildProjectName).dll + $(ExecXHarnessVar) wasm $(XHarnessCommandVar) --app=. $(XHarnessBrowserPathArg) $(WasmXHarnessArgsVar) $(WasmXHarnessArgs) --html-file=index.html --output-directory=$(XHarnessOutputVar) -- $(MSBuildProjectName).dll true $(TestArchiveRoot)chromeonly/ $(TestArchiveTestsRoot)$(OSPlatformConfig)/ diff --git a/src/mono/sample/wasm/browser-bench/main.js b/src/mono/sample/wasm/browser-bench/main.js index 0f1a6530491250..71e4a677ddcc7e 100644 --- a/src/mono/sample/wasm/browser-bench/main.js +++ b/src/mono/sample/wasm/browser-bench/main.js @@ -225,11 +225,6 @@ try { // console to see statistics on how much code it generated and whether any new opcodes // are causing traces to fail to compile .withRuntimeOptions(["--jiterpreter-stats-enabled"]) - // We enable interpreter PGO so that you can exercise it in local tests, i.e. - // run browser-bench one, then refresh the tab to measure the performance improvement - // on the second run of browser-bench. The overall speed of the benchmarks won't - // improve much, but the time spent generating code during the run will go down - .withInterpreterPgo(true, 30) .withElementOnExit() .withExitCodeLogging() .create(); diff --git a/src/mono/sample/wasm/browser-frame/browser-frame.diff b/src/mono/sample/wasm/browser-frame/browser-frame.diff index 72795bed439422..a709abb5d609e2 100644 --- a/src/mono/sample/wasm/browser-frame/browser-frame.diff +++ b/src/mono/sample/wasm/browser-frame/browser-frame.diff @@ -1,15 +1,15 @@ diff -ru browser-frame/Program.cs browser-frame/Program.cs --- a/browser-frame/Program.cs 2024-03-07 09:00:37 +++ b/browser-frame/Program.cs 2024-03-05 15:38:42 -@@ -1,6 +1,8 @@ - using System; +@@ -3,6 +3,8 @@ using System.Runtime.InteropServices.JavaScript; + using System.Threading.Tasks; +BrowserBench.FrameApp.ReachedManaged(); + Console.WriteLine("Hello, Browser!"); - public partial class MyClass + if (args.Length == 1 && args[0] == "start") diff -ru browser-frame/wwwroot/index.html browser-frame/wwwroot/index.html --- a/browser-frame/wwwroot/index.html 2024-03-07 09:00:37 +++ b/browser-frame/wwwroot/index.html 2024-03-05 15:38:42 diff --git a/src/mono/sample/wasm/console-node/Wasm.Console.Node.Sample.csproj b/src/mono/sample/wasm/console-node/Wasm.Console.Node.Sample.csproj index 7234698ff22837..995e1d3650e2ca 100644 --- a/src/mono/sample/wasm/console-node/Wasm.Console.Node.Sample.csproj +++ b/src/mono/sample/wasm/console-node/Wasm.Console.Node.Sample.csproj @@ -6,7 +6,7 @@ true 2 - $(ExecXHarnessCmd) wasm test --app=. --engine=NodeJS --engine-arg=--stack-trace-limit=1000 --js-file=main.mjs --output-directory=$(XHarnessOutput) --expected-exit-code $(ExpectedExitCode) + $(ExecXHarnessVar) wasm test --app=. --engine=NodeJS --engine-arg=--stack-trace-limit=1000 --js-file=main.mjs --output-directory=$(XHarnessOutputVar) --expected-exit-code $(ExpectedExitCode) diff --git a/src/mono/sample/wasm/console-v8/Wasm.Console.V8.Sample.csproj b/src/mono/sample/wasm/console-v8/Wasm.Console.V8.Sample.csproj index 13ed38bfe63e4c..09e9f7bf1a0d2d 100644 --- a/src/mono/sample/wasm/console-v8/Wasm.Console.V8.Sample.csproj +++ b/src/mono/sample/wasm/console-v8/Wasm.Console.V8.Sample.csproj @@ -5,7 +5,7 @@ true true - $(ExecXHarnessCmd) wasm test --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --engine-arg=--module --js-file=main.mjs --output-directory=$(XHarnessOutput) -- --run $(MSBuildProjectName).dll + $(ExecXHarnessVar) wasm test --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --engine-arg=--module --js-file=main.mjs --output-directory=$(XHarnessOutputVar) -- --run $(MSBuildProjectName).dll diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets index 37d6d40d1f172e..cad25a76067295 100644 --- a/src/mono/wasi/build/WasiApp.targets +++ b/src/mono/wasi/build/WasiApp.targets @@ -148,6 +148,8 @@ $(_WasiClangOptimizationFlagDefault) $(WasiClangCompileOptimizationFlag) + -O2 + $(WasiClangCompileOptimizationFlag) -O2 $(WasiClangCompileOptimizationFlag) $(WasiClangLinkOptimizationFlag) @@ -265,8 +267,9 @@ - <_BitcodeLDFlags Include="@(_WasiClangLDFlags)" /> - <_BitcodeLDFlags Include="$(WasiClangExtraBitcodeLDFlags)" /> + <_BitcodeCompileFlags Include="@(WasiBitcodeCompileOptimizationFlag)" /> + <_BitcodeCompileFlags Include="@(_WasiClangCommonFlags)" /> + <_BitcodeCompileFlags Include="$(WasiClangExtraBitcodeCompileFlags)" /> diff --git a/src/mono/wasi/wasi-sdk-version.txt b/src/mono/wasi/wasi-sdk-version.txt index aabe6ec3909c9d..2bd5a0a98a36cc 100644 --- a/src/mono/wasi/wasi-sdk-version.txt +++ b/src/mono/wasi/wasi-sdk-version.txt @@ -1 +1 @@ -21 +22 diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj index bd03a1a0e79b44..59d2137cf97237 100644 --- a/src/mono/wasi/wasi.proj +++ b/src/mono/wasi/wasi.proj @@ -202,10 +202,10 @@ cmake $(MSBuildThisFileDirectory)runtime cmake -G Ninja $(MSBuildThisFileDirectory)runtime + $(CMakeBuildRuntimeConfigureCmd) --no-warn-unused-cli -DCMAKE_TOOLCHAIN_FILE="$([MSBuild]::NormalizePath('$(WASI_SDK_PATH)', 'share/cmake/wasi-sdk.cmake'))" $(CMakeBuildRuntimeConfigureCmd) -DWASI_SDK_PREFIX=$(WASI_SDK_PATH) $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_SYSROOT=$(WASI_SDK_PATH)share/wasi-sysroot $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_CXX_FLAGS="--sysroot=$(WASI_SDK_PATH)share/wasi-sysroot" - $(CMakeBuildRuntimeConfigureCmd) -DCMAKE_TOOLCHAIN_FILE=$(WASI_SDK_PATH)share/cmake/wasi-sdk.cmake $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_WASICC_FLAGS="$(CMakeConfigurationWasiFlags)" $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_LINK_FLAGS="$(CMakeConfigurationLinkFlags)" diff --git a/src/mono/wasi/wasmtime-version.txt b/src/mono/wasi/wasmtime-version.txt index 0062ac971805f7..e021724948e02e 100644 --- a/src/mono/wasi/wasmtime-version.txt +++ b/src/mono/wasi/wasmtime-version.txt @@ -1 +1 @@ -5.0.0 +19.0.2 diff --git a/src/mono/wasm/Wasm.Build.Tests/AspNetCore/SignalRClientTests.cs b/src/mono/wasm/Wasm.Build.Tests/AspNetCore/SignalRClientTests.cs new file mode 100644 index 00000000000000..85f538fac1c20b --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/AspNetCore/SignalRClientTests.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading.Tasks; +using Xunit.Abstractions; +using Xunit; + +#nullable enable + +namespace Wasm.Build.Tests.AspNetCore; + +public class SignalRClientTests : SignalRTestsBase +{ + public SignalRClientTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) + { + } + + [ConditionalTheory(typeof(BuildTestBase), nameof(IsWorkloadWithMultiThreadingForDefaultFramework))] + [InlineData("Debug", "LongPolling")] + [InlineData("Release", "LongPolling")] + [InlineData("Debug", "WebSockets")] + [InlineData("Release", "WebSockets")] + public async Task SignalRPassMessageWasmBrowser(string config, string transport) => + await SignalRPassMessage("wasmclient", config, transport); +} diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs index da9c7764f2d1f2..46c8f2ce132870 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs @@ -205,7 +205,7 @@ public async Task BlazorRunTest(string runArgs, onConsoleMessage: OnConsoleMessage, onServerMessage: runOptions.OnServerMessage, onError: OnErrorMessage, - modifyBrowserUrl: browserUrl => browserUrl + runOptions.BrowserPath + runOptions.QueryString); + modifyBrowserUrl: browserUrl => new Uri(new Uri(browserUrl), runOptions.BrowserPath + runOptions.QueryString).ToString()); _testOutput.WriteLine("Waiting for page to load"); await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded, new () { Timeout = 1 * 60 * 1000 }); diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/SignalRClientTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/SignalRClientTests.cs new file mode 100644 index 00000000000000..cf4f938bc1885d --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/SignalRClientTests.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +using System.Threading.Tasks; +using Xunit.Abstractions; +using Xunit; + +#nullable enable + +namespace Wasm.Build.Tests.Blazor; + +public class SignalRClientTests : SignalRTestsBase +{ + public SignalRClientTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) + { + } + + [ConditionalTheory(typeof(BuildTestBase), nameof(IsWorkloadWithMultiThreadingForDefaultFramework))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/100445")] // to be fixed by: "https://github.com/dotnet/aspnetcore/issues/54365" + [InlineData("Debug", "LongPolling")] + [InlineData("Release", "LongPolling")] + [InlineData("Debug", "WebSockets")] + [InlineData("Release", "WebSockets")] + public async Task SignalRPassMessageBlazor(string config, string transport) => + await SignalRPassMessage("blazorclient", config, transport); +} + diff --git a/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs b/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs index 6772c540962c9c..b37deb5781b290 100644 --- a/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs +++ b/src/mono/wasm/Wasm.Build.Tests/BrowserRunner.cs @@ -109,11 +109,17 @@ public async Task SpawnBrowserAsync( // codespaces: ignore certificate error -> Microsoft.Playwright.PlaywrightException : net::ERR_CERT_AUTHORITY_INVALID string[] chromeArgs = new[] { $"--explicitly-allowed-ports={url.Port}", "--ignore-certificate-errors" }; _testOutput.WriteLine($"Launching chrome ('{s_chromePath.Value}') via playwright with args = {string.Join(',', chromeArgs)}"); - return Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions{ + Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions{ ExecutablePath = s_chromePath.Value, Headless = headless, Args = chromeArgs }); + Browser.Disconnected += (sender, e) => + { + Browser = null; + _testOutput.WriteLine("Browser has been disconnected"); + }; + return Browser; } // FIXME: options @@ -196,8 +202,21 @@ public async Task WaitForProcessExitAsync(TimeSpan timeout) public async ValueTask DisposeAsync() { - if (Browser is not null) - await Browser.DisposeAsync(); - Playwright?.Dispose(); + try + { + if (Browser is not null) + { + await Browser.DisposeAsync(); + Browser = null; + } + } + catch (PlaywrightException ex) + { + _testOutput.WriteLine($"PlaywrightException occurred during DisposeAsync: {ex.Message}"); + } + finally + { + Playwright?.Dispose(); + } } } diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/TestUtils.cs b/src/mono/wasm/Wasm.Build.Tests/Common/TestUtils.cs index 97aa019d454302..fdf88fecc9ee0f 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Common/TestUtils.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Common/TestUtils.cs @@ -91,7 +91,9 @@ public static void AssertEqual(object expected, object actual, string label) $"[{label}]\n"); } - private static readonly char[] s_charsToReplace = new[] { '.', '-', '+' }; + private static readonly char[] s_charsToReplace = new[] { '.', '-', '+', '<', '>' }; + // Keep synced with FixupSymbolName from src/tasks/Common/Utils.cs + // and with mono_fixup_symbol_name from src/mono/mono/metadata/native-library.c public static string FixupSymbolName(string name) { UTF8Encoding utf8 = new(); diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs index c8cca6cd0774e7..555cfa73fad176 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs @@ -136,5 +136,36 @@ public static int Main() string cryptoInitMsg = "MONO_WASM: Initializing Crypto WebWorker"; Assert.DoesNotContain(cryptoInitMsg, output); } + + [Theory] + [BuildAndRun(aot: false)] + [BuildAndRun(aot: true)] + public void ProjectWithNativeLibrary(BuildArgs buildArgs, RunHost host, string id) + { + string projectName = $"AppUsingNativeLibrary-a"; + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, extraItems: "\n"); + + if (!_buildContext.TryGetBuildFor(buildArgs, out BuildProduct? _)) + { + InitPaths(id); + if (Directory.Exists(_projectDir)) + Directory.Delete(_projectDir, recursive: true); + + Utils.DirectoryCopy(Path.Combine(BuildEnvironment.TestAssetsPath, "AppUsingNativeLib"), _projectDir); + File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "native-libs", "native-lib.o"), Path.Combine(_projectDir, "native-lib.o")); + } + + BuildProject(buildArgs, + id: id, + new BuildProjectOptions(DotnetWasmFromRuntimePack: false)); + + string output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 0, + test: output => {}, + host: host, id: id); + + Assert.Contains("print_line: 100", output); + Assert.Contains("from pinvoke: 142", output); + } } } diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index 8c0442a1b0d680..0daa8d0984920e 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -884,5 +884,31 @@ public void EnsureWasmAbiRulesAreFollowedInAOT(BuildArgs buildArgs, RunHost host [BuildAndRun(host: RunHost.Chrome, aot: false)] public void EnsureWasmAbiRulesAreFollowedInInterpreter(BuildArgs buildArgs, RunHost host, string id) => EnsureWasmAbiRulesAreFollowed(buildArgs, host, id); + + [Theory] + [BuildAndRun(host: RunHost.Chrome, aot: false)] + public void UCOWithSpecialCharacters(BuildArgs buildArgs, RunHost host, string id) + { + var extraProperties = "true"; + var extraItems = @""; + + buildArgs = ExpandBuildArgs(buildArgs, + extraItems: extraItems, + extraProperties: extraProperties); + + (string libraryDir, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => + { + File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "Wasm.Buid.Tests.Programs", "UnmanagedCallback.cs"), Path.Combine(_projectDir!, "Program.cs")); + File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "native-libs", "local.c"), Path.Combine(_projectDir!, "local.c")); + }, + Publish: true, + DotnetWasmFromRuntimePack: false)); + + var runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); + Assert.Contains("ManagedFunc returned 42", runOutput); + } } } diff --git a/src/mono/wasm/Wasm.Build.Tests/SignalRTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/SignalRTestsBase.cs new file mode 100644 index 00000000000000..183d984b39b481 --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/SignalRTestsBase.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Collections.Generic; +using Wasm.Build.Tests.TestAppScenarios; +using Xunit.Abstractions; +using Xunit; +#nullable enable + +namespace Wasm.Build.Tests; + +public class SignalRTestsBase : AppTestBase +{ + public SignalRTestsBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) + { + } + + protected async Task SignalRPassMessage(string staticWebAssetBasePath, string config, string transport) + { + CopyTestAsset("WasmOnAspNetCore", "SignalRClientTests", "AspNetCoreServer"); + PublishProject(config, runtimeType: RuntimeVariant.MultiThreaded, assertAppBundle: false); + + var result = await RunSdkStyleAppForBuild(new( + Configuration: config, + ServerEnvironment: new Dictionary { ["ASPNETCORE_ENVIRONMENT"] = "Development" }, + BrowserPath: staticWebAssetBasePath, + BrowserQueryString: new Dictionary { ["transport"] = transport, ["message"] = "ping" } )); + + string testOutput = string.Join("\n", result.TestOutput) ?? ""; + Assert.NotEmpty(testOutput); + // check sending and receiving threadId + string threadIdUsedForSending = GetThreadOfAction(testOutput, @"SignalRPassMessages was sent by CurrentManagedThreadId=(\d+)", "signalR message was sent"); + string threadIdUsedForReceiving = GetThreadOfAction(testOutput, @"ReceiveMessage from server on CurrentManagedThreadId=(\d+)", "signalR message was received"); + string consoleOutput = string.Join("\n", result.ConsoleOutput); + Assert.True("1" != threadIdUsedForSending || "1" != threadIdUsedForReceiving, + $"Expected to send/receive with signalR in non-UI threads, instead only CurrentManagedThreadId=1 was used. ConsoleOutput: {consoleOutput}."); + } + + private string GetThreadOfAction(string testOutput, string pattern, string actionDescription) + { + Match match = Regex.Match(testOutput, pattern); + Assert.True(match.Success, $"Expected to find a log that {actionDescription}. TestOutput: {testOutput}."); + return match.Groups[1].Value ?? ""; + } +} diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index d3e2e506b477a4..b1927711236c8c 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -20,7 +20,25 @@ public WasmTemplateTests(ITestOutputHelper output, SharedBuildPerTestClassFixtur { } - private void UpdateProgramCS() + private string StringReplaceWithAssert(string oldContent, string oldValue, string newValue) + { + string newContent = oldContent.Replace(oldValue, newValue); + if (oldValue != newValue && oldContent == newContent) + throw new XunitException($"Replacing '{oldValue}' with '{newValue}' did not change the content '{oldContent}'"); + + return newContent; + } + + private void UpdateBrowserProgramCs() + { + var path = Path.Combine(_projectDir!, "Program.cs"); + string text = File.ReadAllText(path); + text = StringReplaceWithAssert(text, "while(true)", $"int i = 0;{Environment.NewLine}while(i++ < 10)"); + text = StringReplaceWithAssert(text, "partial class StopwatchSample", $"return 42;{Environment.NewLine}partial class StopwatchSample"); + File.WriteAllText(path, text); + } + + private void UpdateConsoleProgramCs() { string programText = """ Console.WriteLine("Hello, Console!"); @@ -30,25 +48,36 @@ private void UpdateProgramCS() """; var path = Path.Combine(_projectDir!, "Program.cs"); string text = File.ReadAllText(path); - text = text.Replace(@"Console.WriteLine(""Hello, Console!"");", programText); - text = text.Replace("return 0;", "return 42;"); + text = StringReplaceWithAssert(text, @"Console.WriteLine(""Hello, Console!"");", programText); + text = StringReplaceWithAssert(text, "return 0;", "return 42;"); File.WriteAllText(path, text); } private void UpdateBrowserMainJs(string targetFramework, string runtimeAssetsRelativePath = DefaultRuntimeAssetsRelativePath) { - base.UpdateBrowserMainJs((mainJsContent) => { - // .withExitOnUnhandledError() is available only only >net7.0 - mainJsContent = mainJsContent.Replace(".create()", + base.UpdateBrowserMainJs( + (mainJsContent) => + { + // .withExitOnUnhandledError() is available only only >net7.0 + mainJsContent = StringReplaceWithAssert( + mainJsContent, + ".create()", (targetFramework == "net8.0" || targetFramework == "net9.0") ? ".withConsoleForwarding().withElementOnExit().withExitCodeLogging().withExitOnUnhandledError().create()" - : ".withConsoleForwarding().withElementOnExit().withExitCodeLogging().create()"); + : ".withConsoleForwarding().withElementOnExit().withExitCodeLogging().create()" + ); - mainJsContent = mainJsContent.Replace("runMain()", "dotnet.run()"); - mainJsContent = mainJsContent.Replace("from './_framework/dotnet.js'", $"from '{runtimeAssetsRelativePath}dotnet.js'"); + // dotnet.run() is already used in <= net8.0 + if (targetFramework != "net8.0") + mainJsContent = StringReplaceWithAssert(mainJsContent, "runMain()", "dotnet.run()"); - return mainJsContent; - }, targetFramework, runtimeAssetsRelativePath); + mainJsContent = StringReplaceWithAssert(mainJsContent, "from './_framework/dotnet.js'", $"from '{runtimeAssetsRelativePath}dotnet.js'"); + + return mainJsContent; + }, + targetFramework, + runtimeAssetsRelativePath + ); } private void UpdateConsoleMainJs() @@ -56,8 +85,7 @@ private void UpdateConsoleMainJs() string mainJsPath = Path.Combine(_projectDir!, "main.mjs"); string mainJsContent = File.ReadAllText(mainJsPath); - mainJsContent = mainJsContent - .Replace(".create()", ".withConsoleForwarding().create()"); + mainJsContent = StringReplaceWithAssert(mainJsContent, ".create()", ".withConsoleForwarding().create()"); File.WriteAllText(mainJsPath, mainJsContent); } @@ -73,8 +101,7 @@ private void UpdateMainJsEnvironmentVariables(params (string key, string value)[ js.Append($".withEnvironmentVariable(\"{variable.key}\", \"{variable.value}\")"); } - mainJsContent = mainJsContent - .Replace(".create()", js.ToString() + ".create()"); + mainJsContent = StringReplaceWithAssert(mainJsContent, ".create()", js.ToString() + ".create()"); File.WriteAllText(mainJsPath, mainJsContent); } @@ -88,6 +115,7 @@ public void BrowserBuildThenPublish(string config) string projectFile = CreateWasmTemplateProject(id, "wasmbrowser"); string projectName = Path.GetFileNameWithoutExtension(projectFile); + UpdateBrowserProgramCs(); UpdateBrowserMainJs(DefaultTargetFramework); var buildArgs = new BuildArgs(projectName, config, false, id, null); @@ -96,10 +124,10 @@ public void BrowserBuildThenPublish(string config) atTheEnd: """ - - <_LinkedOutFile Include="$(IntermediateOutputPath)\linked\*.dll" /> - - + + <_LinkedOutFile Include="$(IntermediateOutputPath)\linked\*.dll" /> + + """ ); @@ -212,7 +240,7 @@ private void ConsoleBuildAndRun(string config, bool relinking, string extraNewAr string projectFile = CreateWasmTemplateProject(id, "wasmconsole", extraNewArgs, addFrameworkArg: addFrameworkArg); string projectName = Path.GetFileNameWithoutExtension(projectFile); - UpdateProgramCS(); + UpdateConsoleProgramCs(); UpdateConsoleMainJs(); if (relinking) AddItemsPropertiesToProject(projectFile, "true"); @@ -277,6 +305,7 @@ private async Task BrowserRunTwiceWithAndThenWithoutBuildAsync(string config, st string id = $"browser_{config}_{GetRandomId()}"; string projectFile = CreateWasmTemplateProject(id, "wasmbrowser"); + UpdateBrowserProgramCs(); UpdateBrowserMainJs(DefaultTargetFramework); if (!string.IsNullOrEmpty(extraProperties)) @@ -310,7 +339,7 @@ private Task ConsoleRunWithAndThenWithoutBuildAsync(string config, string extraP string id = $"console_{config}_{GetRandomId()}"; string projectFile = CreateWasmTemplateProject(id, "wasmconsole"); - UpdateProgramCS(); + UpdateConsoleProgramCs(); UpdateConsoleMainJs(); if (!string.IsNullOrEmpty(extraProperties)) @@ -374,7 +403,7 @@ public void ConsolePublishAndRun(string config, bool aot, bool relinking) string projectFile = CreateWasmTemplateProject(id, "wasmconsole"); string projectName = Path.GetFileNameWithoutExtension(projectFile); - UpdateProgramCS(); + UpdateConsoleProgramCs(); UpdateConsoleMainJs(); if (aot) @@ -436,6 +465,9 @@ public async Task BrowserBuildAndRun(string extraNewArgs, string targetFramework string id = $"browser_{config}_{GetRandomId()}"; CreateWasmTemplateProject(id, "wasmbrowser", extraNewArgs, addFrameworkArg: extraNewArgs.Length == 0); + if (targetFramework != "net8.0") + UpdateBrowserProgramCs(); + UpdateBrowserMainJs(targetFramework, runtimeAssetsRelativePath); new DotNetCommand(s_buildEnv, _testOutput) @@ -518,7 +550,7 @@ public void Test_WasmStripILAfterAOT(string stripILAfterAOT, bool expectILStripp string projectDirectory = Path.GetDirectoryName(projectFile)!; bool aot = true; - UpdateProgramCS(); + UpdateConsoleProgramCs(); UpdateConsoleMainJs(); string extraProperties = "true"; diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs index 5d028cc238909a..4ce41342917778 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs @@ -25,7 +25,7 @@ public AppSettingsTests(ITestOutputHelper output, SharedBuildPerTestClassFixture [InlineData("Production")] public async Task LoadAppSettingsBasedOnApplicationEnvironment(string applicationEnvironment) { - CopyTestAsset("WasmBasicTestApp", "AppSettingsTests"); + CopyTestAsset("WasmBasicTestApp", "AppSettingsTests", "App"); PublishProject("Debug"); var result = await RunSdkStyleAppForPublish(new( diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs index 01a1afe96c0bbb..9b228c65faaa44 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs @@ -23,7 +23,7 @@ protected AppTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture b protected string Id { get; set; } protected string LogPath { get; set; } - protected void CopyTestAsset(string assetName, string generatedProjectNamePrefix = null) + protected void CopyTestAsset(string assetName, string generatedProjectNamePrefix = null, string? projectDirSuffix = null) { Id = $"{generatedProjectNamePrefix ?? assetName}_{GetRandomId()}"; InitBlazorWasmProjectDir(Id); @@ -31,27 +31,21 @@ protected void CopyTestAsset(string assetName, string generatedProjectNamePrefix LogPath = Path.Combine(s_buildEnv.LogRootPath, Id); Utils.DirectoryCopy(Path.Combine(BuildEnvironment.TestAssetsPath, assetName), Path.Combine(_projectDir!)); - switch(assetName) + if (!string.IsNullOrEmpty(projectDirSuffix)) { - case "WasmBasicTestApp": - // WasmBasicTestApp consists of App + Library projects - _projectDir = Path.Combine(_projectDir!, "App"); - break; - case "BlazorHostedApp": - // BlazorHostedApp consists of BlazorHosted.Client and BlazorHosted.Server projects - _projectDir = Path.Combine(_projectDir!, "BlazorHosted.Server"); - break; + _projectDir = Path.Combine(_projectDir, projectDirSuffix); } } protected void BlazorHostedBuild( string config, string assetName, + string projectDirSuffix, string clientDirRelativeToProjectDir = "", string? generatedProjectNamePrefix = null, RuntimeVariant runtimeType = RuntimeVariant.SingleThreaded) { - CopyTestAsset(assetName, generatedProjectNamePrefix); + CopyTestAsset(assetName, generatedProjectNamePrefix, projectDirSuffix); string frameworkDir = FindBlazorHostedBinFrameworkDir(config, forPublish: false, clientDirRelativeToProjectDir: clientDirRelativeToProjectDir); @@ -76,9 +70,17 @@ protected void BuildProject( result.EnsureSuccessful(); } - protected void PublishProject(string configuration, params string[] extraArgs) + protected void PublishProject( + string configuration, + RuntimeVariant runtimeType = RuntimeVariant.SingleThreaded, + bool assertAppBundle = true, + params string[] extraArgs) { - (CommandResult result, _) = BlazorPublish(new BlazorBuildOptions(Id, configuration), extraArgs); + (CommandResult result, _) = BlazorPublish(new BlazorBuildOptions( + Id: Id, + Config: configuration, + RuntimeType: runtimeType, + AssertAppBundle: assertAppBundle), extraArgs); result.EnsureSuccessful(); } @@ -99,12 +101,11 @@ private async Task RunSdkStyleApp(RunOptions options, BlazorRunHost h query.Add("test", options.TestScenario); var queryString = query.Any() ? "?" + string.Join("&", query.Select(kvp => $"{kvp.Key}={kvp.Value}")) : ""; - var tcs = new TaskCompletionSource(); List testOutput = new(); List consoleOutput = new(); List serverOutput = new(); - Regex exitRegex = new Regex("(WASM EXIT (?[0-9]+)$)|(Program terminated with exit\\((?[0-9]+)\\))"); + Regex exitRegex = new Regex("WASM EXIT (?[0-9]+)$"); BlazorRunOptions blazorRunOptions = new( CheckCounter: false, @@ -114,7 +115,8 @@ private async Task RunSdkStyleApp(RunOptions options, BlazorRunHost h OnServerMessage: OnServerMessage, BrowserPath: options.BrowserPath, QueryString: queryString, - Host: host); + Host: host, + ExtraArgs: options.ExtraArgs); await BlazorRunTest(blazorRunOptions); @@ -171,7 +173,8 @@ protected record RunOptions( Dictionary ServerEnvironment = null, Action OnConsoleMessage = null, Action OnServerMessage = null, - int? ExpectedExitCode = 0 + int? ExpectedExitCode = 0, + string? ExtraArgs = null ); protected record RunResult( diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DebugLevelTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DebugLevelTests.cs index 1bbe8691d80db3..ee69b34819bbdc 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DebugLevelTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DebugLevelTests.cs @@ -33,7 +33,7 @@ private void AssertDebugLevel(RunResult result, int value) [InlineData("Release")] public async Task BuildWithDefaultLevel(string configuration) { - CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_BuildWithDefaultLevel_{configuration}"); + CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_BuildWithDefaultLevel_{configuration}", "App"); BuildProject(configuration); var result = await RunSdkStyleAppForBuild(new( @@ -50,7 +50,7 @@ public async Task BuildWithDefaultLevel(string configuration) [InlineData("Release", 0)] public async Task BuildWithExplicitValue(string configuration, int debugLevel) { - CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_BuildWithExplicitValue_{configuration}"); + CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_BuildWithExplicitValue_{configuration}", "App"); BuildProject(configuration: configuration, extraArgs: $"-p:WasmDebugLevel={debugLevel}"); var result = await RunSdkStyleAppForBuild(new( @@ -65,7 +65,7 @@ public async Task BuildWithExplicitValue(string configuration, int debugLevel) [InlineData("Release")] public async Task PublishWithDefaultLevel(string configuration) { - CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_PublishWithDefaultLevel_{configuration}"); + CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_PublishWithDefaultLevel_{configuration}", "App"); PublishProject(configuration); var result = await RunSdkStyleAppForPublish(new( @@ -82,8 +82,8 @@ public async Task PublishWithDefaultLevel(string configuration) [InlineData("Release", -1)] public async Task PublishWithExplicitValue(string configuration, int debugLevel) { - CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_PublishWithExplicitValue_{configuration}"); - PublishProject(configuration, $"-p:WasmDebugLevel={debugLevel}"); + CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_PublishWithExplicitValue_{configuration}", "App"); + PublishProject(configuration, RuntimeVariant.SingleThreaded, assertAppBundle: true, $"-p:WasmDebugLevel={debugLevel}"); var result = await RunSdkStyleAppForPublish(new( Configuration: configuration, @@ -97,8 +97,8 @@ public async Task PublishWithExplicitValue(string configuration, int debugLevel) [InlineData("Release")] public async Task PublishWithDefaultLevelAndPdbs(string configuration) { - CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_PublishWithDefaultLevelAndPdbs_{configuration}"); - PublishProject(configuration, $"-p:CopyOutputSymbolsToPublishDirectory=true"); + CopyTestAsset("WasmBasicTestApp", $"DebugLevelTests_PublishWithDefaultLevelAndPdbs_{configuration}", "App"); + PublishProject(configuration, RuntimeVariant.SingleThreaded, assertAppBundle: true, $"-p:CopyOutputSymbolsToPublishDirectory=true"); var result = await RunSdkStyleAppForPublish(new( Configuration: configuration, diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/InterpPgoTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/InterpPgoTests.cs similarity index 65% rename from src/mono/wasm/Wasm.Build.Tests/Templates/InterpPgoTests.cs rename to src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/InterpPgoTests.cs index 4fe88ee8daca3d..24e052f96d3fb4 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/InterpPgoTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/InterpPgoTests.cs @@ -13,9 +13,9 @@ #nullable enable -namespace Wasm.Build.Templates.Tests; +namespace Wasm.Build.Tests.TestAppScenarios; -public class InterpPgoTests : WasmTemplateTestBase +public class InterpPgoTests : AppTestBase { public InterpPgoTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) @@ -32,41 +32,11 @@ public async Task FirstRunGeneratesTableAndSecondRunLoadsIt(string config) // Invoking it too many times makes the test meaningfully slower. const int iterationCount = 70; - string id = $"browser_{config}_{GetRandomId()}"; _testOutput.WriteLine("/// Creating project"); - string projectFile = CreateWasmTemplateProject(id, "wasmbrowser", extraProperties: "0"); - - _testOutput.WriteLine("/// Updating JS"); - UpdateBrowserMainJs((js) => { - // We need to capture INTERNAL so we can explicitly save the PGO table - js = js.Replace( - "const { setModuleImports, getAssemblyExports, getConfig, runMain } = await dotnet", - "const { setModuleImports, getAssemblyExports, getConfig, runMain, INTERNAL } = await dotnet" - ); - // Enable interpreter PGO + interpreter PGO logging + console output capturing - js = js.Replace( - ".create()", - ".withConsoleForwarding().withElementOnExit().withExitCodeLogging().withExitOnUnhandledError().withRuntimeOptions(['--interp-pgo-logging']).withInterpreterPgo(true).create()" - ); - js = js.Replace("runMain()", "dotnet.run()"); - // Call Greeting in a loop to exercise enough code to cause something to tier, - // then call INTERNAL.interp_pgo_save_data() to save the interp PGO table - js = js.Replace( - "const text = exports.MyClass.Greeting();", - "console.log(`WASM debug level ${getConfig().debugLevel}`);\n" + - "let text = '';\n" + - $"for (let i = 0; i < {iterationCount}; i++) {{ text = exports.MyClass.Greeting(); }};\n" + - "await INTERNAL.interp_pgo_save_data();" - ); - return js; - }, DefaultTargetFramework); + CopyTestAsset("WasmBasicTestApp", "InterpPgoTest", "App"); _testOutput.WriteLine("/// Building"); - - new DotNetCommand(s_buildEnv, _testOutput) - .WithWorkingDirectory(_projectDir!) - .Execute($"build -c {config} -bl:{Path.Combine(s_buildEnv.LogRootPath, $"{id}.binlog")}") - .EnsureSuccessful(); + BuildProject(config, extraArgs: "-p:WasmDebugLevel=0"); _testOutput.WriteLine("/// Starting server"); @@ -75,7 +45,11 @@ public async Task FirstRunGeneratesTableAndSecondRunLoadsIt(string config) using var runCommand = new RunCommand(s_buildEnv, _testOutput) .WithWorkingDirectory(_projectDir!); await using var runner = new BrowserRunner(_testOutput); - var url = await runner.StartServerAndGetUrlAsync(runCommand, $"run --no-silent -c {config} --no-build --project \"{projectFile}\" --forward-console"); + var url = await runner.StartServerAndGetUrlAsync(runCommand, $"run --no-silent -c {config} --no-build --project \"{_projectDir!}\" --forward-console"); + url = $"{url}?test=InterpPgoTest&iterationCount={iterationCount}"; + + _testOutput.WriteLine($"/// Spawning browser at URL {url}"); + IBrowser browser = await runner.SpawnBrowserAsync(url); IBrowserContext context = await browser.NewContextAsync(); @@ -83,11 +57,11 @@ public async Task FirstRunGeneratesTableAndSecondRunLoadsIt(string config) { _testOutput.WriteLine("/// First run"); var page = await runner.RunAsync(context, url); - await runner.WaitForExitMessageAsync(TimeSpan.FromSeconds(30)); + await runner.WaitForExitMessageAsync(TimeSpan.FromSeconds(6 * 30)); lock (runner.OutputLines) output = string.Join(Environment.NewLine, runner.OutputLines); - Assert.Contains("Hello, Browser!", output); + Assert.Contains("Hello, World!", output); // Verify that no PGO table was located in cache Assert.Contains("Failed to load interp_pgo table", output); // Verify that the table was saved after the app ran @@ -107,7 +81,7 @@ public async Task FirstRunGeneratesTableAndSecondRunLoadsIt(string config) lock (runner.OutputLines) output = string.Join(Environment.NewLine, runner.OutputLines); - Assert.Contains("Hello, Browser!", output); + Assert.Contains("Hello, World!", output); // Verify that table data was loaded from cache // if this breaks, it could be caused by change in config which affects the config hash and the cache storage hash key Assert.Contains(" bytes of interp_pgo data (table size == ", output); diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs index cf16a0536a38da..038951e1822e68 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs @@ -23,7 +23,7 @@ public LazyLoadingTests(ITestOutputHelper output, SharedBuildPerTestClassFixture [Fact] public async Task LoadLazyAssemblyBeforeItIsNeeded() { - CopyTestAsset("WasmBasicTestApp", "LazyLoadingTests"); + CopyTestAsset("WasmBasicTestApp", "LazyLoadingTests", "App"); PublishProject("Debug"); var result = await RunSdkStyleAppForPublish(new(Configuration: "Debug", TestScenario: "LazyLoadingTest")); @@ -33,7 +33,7 @@ public async Task LoadLazyAssemblyBeforeItIsNeeded() [Fact] public async Task FailOnMissingLazyAssembly() { - CopyTestAsset("WasmBasicTestApp", "LazyLoadingTests"); + CopyTestAsset("WasmBasicTestApp", "LazyLoadingTests", "App"); PublishProject("Debug"); var result = await RunSdkStyleAppForPublish(new( diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs index e985ad23d89a0b..c4380ed755a591 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs @@ -26,7 +26,7 @@ public LibraryInitializerTests(ITestOutputHelper output, SharedBuildPerTestClass [Fact] public async Task LoadLibraryInitializer() { - CopyTestAsset("WasmBasicTestApp", "LibraryInitializerTests_LoadLibraryInitializer"); + CopyTestAsset("WasmBasicTestApp", "LibraryInitializerTests_LoadLibraryInitializer", "App"); PublishProject("Debug"); var result = await RunSdkStyleAppForPublish(new(Configuration: "Debug", TestScenario: "LibraryInitializerTest")); @@ -39,7 +39,7 @@ public async Task LoadLibraryInitializer() [Fact] public async Task AbortStartupOnError() { - CopyTestAsset("WasmBasicTestApp", "LibraryInitializerTests_AbortStartupOnError"); + CopyTestAsset("WasmBasicTestApp", "LibraryInitializerTests_AbortStartupOnError", "App"); PublishProject("Debug"); var result = await RunSdkStyleAppForPublish(new( diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs index 4dc20e7358aa5b..532751a4ac5347 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs @@ -25,7 +25,7 @@ public ModuleConfigTests(ITestOutputHelper output, SharedBuildPerTestClassFixtur [InlineData(true)] public async Task DownloadProgressFinishes(bool failAssemblyDownload) { - CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_DownloadProgressFinishes_{failAssemblyDownload}"); + CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_DownloadProgressFinishes_{failAssemblyDownload}", "App"); PublishProject("Debug"); var result = await RunSdkStyleAppForPublish(new( @@ -58,7 +58,7 @@ public async Task DownloadProgressFinishes(bool failAssemblyDownload) [Fact] public async Task OutErrOverrideWorks() { - CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_OutErrOverrideWorks"); + CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_OutErrOverrideWorks", "App"); PublishProject("Debug"); var result = await RunSdkStyleAppForPublish(new( diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs index 2088e1522ad73b..517f34255f9969 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs @@ -26,7 +26,7 @@ public SatelliteLoadingTests(ITestOutputHelper output, SharedBuildPerTestClassFi [Fact] public async Task LoadSatelliteAssembly() { - CopyTestAsset("WasmBasicTestApp", "SatelliteLoadingTests"); + CopyTestAsset("WasmBasicTestApp", "SatelliteLoadingTests", "App"); BuildProject("Debug"); var result = await RunSdkStyleAppForBuild(new(Configuration: "Debug", TestScenario: "SatelliteAssembliesTest")); diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SignalRClientTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SignalRClientTests.cs deleted file mode 100644 index 1b09272b487931..00000000000000 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SignalRClientTests.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Microsoft.Playwright; -using Xunit.Abstractions; -using Xunit; - -#nullable enable - -namespace Wasm.Build.Tests.TestAppScenarios; - -public class SignalRClientTests : AppTestBase -{ - public SignalRClientTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) - : base(output, buildContext) - { - } - - [ConditionalTheory(typeof(BuildTestBase), nameof(IsWorkloadWithMultiThreadingForDefaultFramework))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/100445")] // to be fixed by: "https://github.com/dotnet/aspnetcore/issues/54365" - [InlineData("Debug", "LongPolling")] - [InlineData("Release", "LongPolling")] - [InlineData("Debug", "WebSockets")] - [InlineData("Release", "WebSockets")] - public async Task SignalRPassMessages(string config, string transport) - { - BlazorHostedBuild(config, - assetName: "BlazorHostedApp", - clientDirRelativeToProjectDir: "../BlazorHosted.Client", - generatedProjectNamePrefix: "SignalRClientTests", - runtimeType: RuntimeVariant.MultiThreaded); - - List consoleOutput = new(); - List serverOutput = new(); - - var result = await RunSdkStyleAppForBuild(new( - Configuration: config, - // We are using build (not publish), - // we need to instruct static web assets to use manifest file, - // because wwwroot in bin doesn't contain all files (for build) - ServerEnvironment: new Dictionary { ["ASPNETCORE_ENVIRONMENT"] = "Development" }, - BrowserPath: "/chat", - BrowserQueryString: new Dictionary { ["transport"] = transport, ["message"] = "ping" }, - OnServerMessage: (msg) => serverOutput.Add(msg), - OnConsoleMessage: async (page, msg) => - { - consoleOutput.Add(msg.Text); - if (msg.Text.Contains("TestOutput ->")) - _testOutput.WriteLine(msg.Text); - - // prevent timeouts with [Long Running Test] on error - if (msg.Text.ToLowerInvariant().Contains("error")) - { - Console.WriteLine(msg.Text); - Console.WriteLine(_testOutput); - throw new Exception(msg.Text); - } - - if (msg.Text.Contains("Finished GetQueryParameters")) - await SaveClickButtonAsync(page, "button#connectButton"); - - if (msg.Text.Contains("SignalR connected")) - await SaveClickButtonAsync(page, "button#subscribeButton"); - - if (msg.Text.Contains("Subscribed to ReceiveMessage")) - await SaveClickButtonAsync(page, "button#sendMessageButton"); - - if (msg.Text.Contains("ReceiveMessage from server")) - await SaveClickButtonAsync(page, "button#exitProgramButton"); - } - )); - - string output = _testOutput.ToString() ?? ""; - Assert.NotEmpty(output); - // check sending and receiving threadId - string threadIdUsedForSending = GetThreadOfAction(output, @"SignalRPassMessages was sent by CurrentManagedThreadId=(\d+)", "signalR message was sent"); - string threadIdUsedForReceiving = GetThreadOfAction(output, @"ReceiveMessage from server on CurrentManagedThreadId=(\d+)", "signalR message was received"); - Assert.True("1" != threadIdUsedForSending || "1" != threadIdUsedForReceiving, - $"Expected to send/receive with signalR in non-UI threads, instead only CurrentManagedThreadId=1 was used. TestOutput: {output}."); - } - - private string GetThreadOfAction(string testOutput, string pattern, string actionDescription) - { - Match match = Regex.Match(testOutput, pattern); - Assert.True(match.Success, $"Expected to find a log that {actionDescription}. TestOutput: {testOutput}."); - return match.Groups[1].Value ?? ""; - } - - private async Task SaveClickButtonAsync(IPage page, string selector) - { - await page.WaitForSelectorAsync(selector); - await page.ClickAsync(selector); - } -} diff --git a/src/mono/wasm/build/WasmApp.Common.targets b/src/mono/wasm/build/WasmApp.Common.targets index 7e4c7d343417fd..501a98264538c3 100644 --- a/src/mono/wasm/build/WasmApp.Common.targets +++ b/src/mono/wasm/build/WasmApp.Common.targets @@ -44,6 +44,8 @@ - $(EmccLinkOptimizationFlag) - Optimization flag to use for the link step - $(EmccCompileOptimizationFlag) - Optimization flag to use for compiling native files + - $(WasmBitcodeCompileOptimizationFlag) + - Optimization flag to use for compiling bitcode files - $(EmccFlags) - Emcc flags used for both compiling native files, and linking - $(EmccExtraLDFlags) - Extra emcc flags for linking @@ -295,6 +297,11 @@ <_WasmShouldAOT Condition="'$(_WasmShouldAOT)' == ''">false + + <_ExistingNativeLibrary Include="@(NativeLibrary->Exists())" /> + + + @@ -800,11 +807,11 @@ - + diff --git a/src/mono/wasm/templates/templates/browser/Program.cs b/src/mono/wasm/templates/templates/browser/Program.cs index ecf115b0e71284..a9726e67fd6aca 100644 --- a/src/mono/wasm/templates/templates/browser/Program.cs +++ b/src/mono/wasm/templates/templates/browser/Program.cs @@ -1,18 +1,55 @@ using System; +using System.Diagnostics; using System.Runtime.InteropServices.JavaScript; +using System.Threading.Tasks; Console.WriteLine("Hello, Browser!"); -public partial class MyClass +if (args.Length == 1 && args[0] == "start") + StopwatchSample.Start(); + +while(true) +{ + StopwatchSample.Render(); + await Task.Delay(1000); +} + +partial class StopwatchSample { + private static Stopwatch stopwatch = new(); + + public static void Start() => stopwatch.Start(); + public static void Render() => SetInnerText("#time", stopwatch.Elapsed.ToString(@"mm\:ss")); + + [JSImport("dom.setInnerText", "main.js")] + internal static partial void SetInnerText(string selector, string content); + [JSExport] - internal static string Greeting() + internal static bool Toggle() { - var text = $"Hello, World! Greetings from {GetHRef()}"; - Console.WriteLine(text); - return text; + if (stopwatch.IsRunning) + { + stopwatch.Stop(); + return false; + } + else + { + stopwatch.Start(); + return true; + } } - [JSImport("window.location.href", "main.js")] - internal static partial string GetHRef(); + [JSExport] + internal static void Reset() + { + if (stopwatch.IsRunning) + stopwatch.Restart(); + else + stopwatch.Reset(); + + Render(); + } + + [JSExport] + internal static bool IsRunning() => stopwatch.IsRunning; } diff --git a/src/mono/wasm/templates/templates/browser/wwwroot/index.html b/src/mono/wasm/templates/templates/browser/wwwroot/index.html index 417803bf38d934..287d8b5319216a 100644 --- a/src/mono/wasm/templates/templates/browser/wwwroot/index.html +++ b/src/mono/wasm/templates/templates/browser/wwwroot/index.html @@ -11,7 +11,14 @@ - +

Stopwatch

+

+ Time elapsed in .NET is loading... +

+

+ + +

diff --git a/src/mono/wasm/templates/templates/browser/wwwroot/main.js b/src/mono/wasm/templates/templates/browser/wwwroot/main.js index afcf21e4e6510d..82c86ed196b4ef 100644 --- a/src/mono/wasm/templates/templates/browser/wwwroot/main.js +++ b/src/mono/wasm/templates/templates/browser/wwwroot/main.js @@ -4,24 +4,29 @@ import { dotnet } from './_framework/dotnet.js' const { setModuleImports, getAssemblyExports, getConfig, runMain } = await dotnet - .withDiagnosticTracing(false) - .withApplicationArgumentsFromQuery() + .withApplicationArguments("start") .create(); setModuleImports('main.js', { - window: { - location: { - href: () => globalThis.window.location.href - } + dom: { + setInnerText: (selector, time) => document.querySelector(selector).innerText = time } }); const config = getConfig(); const exports = await getAssemblyExports(config.mainAssemblyName); -const text = exports.MyClass.Greeting(); -console.log(text); -document.getElementById('out').innerHTML = text; +document.getElementById('reset').addEventListener('click', e => { + exports.StopwatchSample.Reset(); + e.preventDefault(); +}); + +const pauseButton = document.getElementById('pause'); +pauseButton.addEventListener('click', e => { + const isRunning = exports.StopwatchSample.Toggle(); + pauseButton.innerText = isRunning ? 'Pause' : 'Start'; + e.preventDefault(); +}); // run the C# Main() method and keep the runtime process running and executing further API calls await runMain(); \ No newline at end of file diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Helper.cs b/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Helper.cs deleted file mode 100644 index 38ead1438099f3..00000000000000 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Helper.cs +++ /dev/null @@ -1,42 +0,0 @@ -// 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.Specialized; -using Microsoft.AspNetCore.Http.Connections; - -namespace BlazorHosted.Client; - -public static class Helper -{ - public static string GetValue(NameValueCollection parameters, string key) - { - var values = parameters.GetValues(key); - if (values == null || values.Length == 0) - { - throw new Exception($"Parameter '{key}' is required in the query string"); - } - if (values.Length > 1) - { - throw new Exception($"Parameter '{key}' should be unique in the query string"); - } - return values[0]; - } - - public static HttpTransportType StringToTransportType(string transport) - { - switch (transport.ToLowerInvariant()) - { - case "longpolling": - return HttpTransportType.LongPolling; - case "websockets": - return HttpTransportType.WebSockets; - default: - throw new Exception($"{transport} is invalid transport type"); - } - } - - public static void TestOutputWriteLine(string message) - { - Console.WriteLine("TestOutput -> " + message); - } -} diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Pages/Chat.razor b/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Pages/Chat.razor deleted file mode 100644 index f90aa96c87b92b..00000000000000 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Pages/Chat.razor +++ /dev/null @@ -1,116 +0,0 @@ -@page "/chat" -@using Microsoft.AspNetCore.SignalR -@using Microsoft.AspNetCore.SignalR.Client -@using Microsoft.AspNetCore.Http.Connections; -@using System.Web; -@inject NavigationManager NavigationManager -@inject IJSRuntime JSRuntime - -

Chat Room

- - - - - -
- @foreach (var chatMessage in chatMessages) - { -

@chatMessage

- } -
- -@code { - private string _hubUrl = string.Empty; - private HubConnection? _hubConnection; - private string message = string.Empty; - private string transport = string.Empty; - private List chatMessages = new List(); - private string wrongQueryError = "Query string with parameters 'message' and 'transport' are required"; - - // remove when https://github.com/dotnet/runtime/issues/96546 is fixed - // log that rendering is about to start in case we hit the issue before OnAfterRender is called - protected override bool ShouldRender() - { - bool shouldRender = base.ShouldRender(); - Helper.TestOutputWriteLine($"ShouldRender = {shouldRender}"); - return shouldRender; - } - - protected override void OnAfterRender(bool firstRender) - { - if (firstRender) - { - Helper.TestOutputWriteLine($"OnAfterRender on CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); - GetQueryParameters(); - } - base.OnAfterRender(firstRender); - } - - private void GetQueryParameters() - { - var uri = new Uri(NavigationManager.Uri); - if (string.IsNullOrEmpty(uri.Query)) - { - throw new Exception(wrongQueryError); - } - var parameters = HttpUtility.ParseQueryString(uri.Query); - if (parameters == null) - { - throw new Exception(wrongQueryError); - } - transport = Helper.GetValue(parameters, "transport"); - message = $"{transport} {Helper.GetValue(parameters, "message")}" ; - Helper.TestOutputWriteLine($"Finished GetQueryParameters on CurrentManagedThreadId={Environment.CurrentManagedThreadId}."); - } - - private async Task Connect() - { - _hubUrl = NavigationManager.BaseUri + "chathub"; - HttpTransportType httpTransportType = Helper.StringToTransportType(transport); - _hubConnection = new HubConnectionBuilder() - .WithUrl(_hubUrl, options => - { - options.Transports = httpTransportType; - }) - .Build(); - - await _hubConnection.StartAsync(); - Helper.TestOutputWriteLine($"SignalR connected by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); - } - - private void Subscribe() - { - _hubConnection.On("ReceiveMessage", (message) => - { - Helper.TestOutputWriteLine($"Message = [{message}]. ReceiveMessage from server on CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); - chatMessages.Add(message); - }); - Helper.TestOutputWriteLine($"Subscribed to ReceiveMessage by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); - } - - private async Task SignalRPassMessages() => - await Task.Run(async () => - { - await _hubConnection.SendAsync( "SendMessage", message, Environment.CurrentManagedThreadId); - Helper.TestOutputWriteLine($"SignalRPassMessages was sent by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); - }); - - private async Task SendExitSignal() - { - await DisposeHubConnection(); - // exit the client - Helper.TestOutputWriteLine($"SendExitSignal by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); - await JSRuntime.InvokeVoidAsync("eval", "setTimeout(() => { getDotnetRuntime(0).exit(0); }, 50);"); - } - - private async Task DisposeHubConnection() - { - if (_hubConnection != null) - { - _hubConnection.Remove("ReceiveMessage"); - await _hubConnection.DisposeAsync(); - _hubConnection = null; - } - Helper.TestOutputWriteLine($"SignalR disconnected by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); - } -} diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/wwwroot/favicon.ico b/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/wwwroot/favicon.ico deleted file mode 100644 index 63e859b476eff5..00000000000000 Binary files a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/wwwroot/favicon.ico and /dev/null differ diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/Program.cs b/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/Program.cs deleted file mode 100644 index fea18a9250cc15..00000000000000 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/Program.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Extensions.Configuration; -using System; -using Microsoft.Extensions.Logging; -using BlazorHosted.Server.Hubs; - -var builder = WebApplication.CreateBuilder(args); - -builder.Services.AddControllersWithViews(); -builder.Services.AddRazorPages(); -builder.Services.AddSignalR(options => -{ - options.KeepAliveInterval = TimeSpan.Zero; // minimize keep-alive messages -}); - -var app = builder.Build(); - -// Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) -{ - app.UseWebAssemblyDebugging(); -} -else -{ - app.UseExceptionHandler("/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); -} - -// Add headers to enable SharedArrayBuffer -app.Use(async (context, next) => -{ - var response = context.Response; - response.Headers.Append("Cross-Origin-Opener-Policy", "same-origin"); - response.Headers.Append("Cross-Origin-Embedder-Policy", "require-corp"); - - await next(); -}); -app.UseBlazorFrameworkFiles(); -app.UseStaticFiles(); - -app.UseRouting(); - -app.MapRazorPages(); -app.MapControllers(); -app.MapFallbackToFile("index.html"); - -app.MapHub("/chathub"); - -app.Run(); diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/appsettings.json b/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/appsettings.json deleted file mode 100644 index 75b7c2aa1ecedb..00000000000000 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} \ No newline at end of file diff --git a/src/mono/wasm/testassets/Wasm.Buid.Tests.Programs/UnmanagedCallback.cs b/src/mono/wasm/testassets/Wasm.Buid.Tests.Programs/UnmanagedCallback.cs new file mode 100644 index 00000000000000..2157909c3d5fc6 --- /dev/null +++ b/src/mono/wasm/testassets/Wasm.Buid.Tests.Programs/UnmanagedCallback.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.InteropServices; + +public unsafe partial class Test +{ + public unsafe static int Main(string[] args) + { + ((IntPtr)(delegate* unmanaged)&Interop.Managed8\u4F60Func).ToString(); + + Console.WriteLine($"main: {args.Length}"); + Interop.UnmanagedFunc(); + return 42; + } +} + +file partial class Interop +{ + [UnmanagedCallersOnly(EntryPoint = "ManagedFunc")] + public static int Managed8\u4F60Func(int number) + { + // called from UnmanagedFunc + Console.WriteLine($"Managed8\u4F60Func({number}) -> 42"); + return 42; + } + + [DllImport("local", EntryPoint = "UnmanagedFunc")] + public static extern void UnmanagedFunc(); // calls ManagedFunc +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/InterpPgoTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/InterpPgoTest.cs new file mode 100644 index 00000000000000..6d093133b3771c --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/InterpPgoTest.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using System.Text.Json; +using System.Runtime.InteropServices.JavaScript; + +public partial class InterpPgoTest +{ + [JSImport("window.location.href", "main.js")] + internal static partial string GetHRef(); + + [JSExport] + internal static string Greeting() + { + var text = $"Hello, World! Greetings from {GetHRef()}"; + Console.WriteLine(text); + return text; + } +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js index 5aeeb024096d56..3eb9e50aedeb32 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js @@ -37,7 +37,7 @@ switch (testCase) { let alreadyFailed = []; dotnet.withDiagnosticTracing(true).withResourceLoader((type, name, defaultUri, integrity, behavior) => { if (type === "dotnetjs") { - // loadBootResource could return string with unqualified name of resource. + // loadBootResource could return string with unqualified name of resource. // It assumes that we resolve it with document.baseURI // we test it here return `_framework/${name}`; @@ -78,9 +78,15 @@ switch (testCase) { }, }); break; + case "InterpPgoTest": + dotnet + .withConsoleForwarding() + .withRuntimeOptions(['--interp-pgo-logging']) + .withInterpreterPgo(true); + break; } -const { getAssemblyExports, getConfig, INTERNAL } = await dotnet.create(); +const { setModuleImports, getAssemblyExports, getConfig, INTERNAL } = await dotnet.create(); const config = getConfig(); const exports = await getAssemblyExports(config.mainAssemblyName); const assemblyExtension = config.resources.assembly['System.Private.CoreLib.wasm'] !== undefined ? ".wasm" : ".dll"; @@ -116,6 +122,21 @@ try { testOutput("WasmDebugLevel: " + config.debugLevel); exit(0); break; + case "InterpPgoTest": + setModuleImports('main.js', { + window: { + location: { + href: () => globalThis.window.location.href + } + } + }); + const iterationCount = params.get("iterationCount") ?? 70; + for (let i = 0; i < iterationCount; i++) { + exports.InterpPgoTest.Greeting(); + }; + await INTERNAL.interp_pgo_save_data(); + exit(0); + break; default: console.error(`Unknown test case: ${testCase}`); exit(3); diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/BlazorHosted.Server.csproj b/src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/AspNetCoreServer.csproj similarity index 63% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/BlazorHosted.Server.csproj rename to src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/AspNetCoreServer.csproj index db0b51cd370081..9b556e8a965da2 100644 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/BlazorHosted.Server.csproj +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/AspNetCoreServer.csproj @@ -4,6 +4,7 @@ net9.0 enable enable + true CA2007 @@ -13,7 +14,9 @@
- + + + diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/ChatHub.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/ChatHub.cs similarity index 93% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/ChatHub.cs rename to src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/ChatHub.cs index 8b2e77807c6fbc..2a1267d102c2fd 100644 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Server/ChatHub.cs +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/ChatHub.cs @@ -3,7 +3,8 @@ using Microsoft.AspNetCore.SignalR; -namespace BlazorHosted.Server.Hubs; +namespace Server; + public class ChatHub : Hub { public async Task SendMessage(string message, int sendingThreadId) diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/Program.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/Program.cs new file mode 100644 index 00000000000000..b22b8ded516a02 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/AspNetCoreServer/Program.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http.Connections; +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.FileProviders; +using Microsoft.AspNetCore.StaticFiles; +using Server; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddSignalR(); +var app = builder.Build(); + +// Add headers to enable SharedArrayBuffer +app.Use(async (context, next) => +{ + var response = context.Response; + response.Headers.Append("Cross-Origin-Opener-Policy", "same-origin"); + response.Headers.Append("Cross-Origin-Embedder-Policy", "require-corp"); + + await next(); +}); + +app.UseDefaultFiles(); + +var provider = new FileExtensionContentTypeProvider(); +provider.Mappings[".dll"] = "application/octet-stream"; +provider.Mappings[".pdb"] = "application/octet-stream"; +provider.Mappings[".dat"] = "application/octet-stream"; +app.UseStaticFiles(new StaticFileOptions +{ + ContentTypeProvider = provider, +}); + +ConfigureClientApp(app, "wasmclient"); +ConfigureClientApp(app, "blazorclient"); + +app.Run(); + + +static void ConfigureClientApp(WebApplication app, string clientAppPath) +{ + app.MapWhen( + ctx => ctx.Request.Path.StartsWithSegments($"/{clientAppPath}", out var rest), + clientApp => + { + clientApp + .UseBlazorFrameworkFiles($"/{clientAppPath}") + .UsePathBase($"/{clientAppPath}") + .UseRouting() + .UseEndpoints(endpoints => + { + endpoints.MapHub("/chathub"); + endpoints.MapFallbackToFile($"{clientAppPath}/index.html"); + }); + } + ); +} diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/App.razor b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/App.razor similarity index 100% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/App.razor rename to src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/App.razor diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/BlazorHosted.Client.csproj b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/BlazorClient.csproj similarity index 67% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/BlazorHosted.Client.csproj rename to src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/BlazorClient.csproj index 237c5cf2d75acd..5c974a459386c2 100644 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/BlazorHosted.Client.csproj +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/BlazorClient.csproj @@ -7,13 +7,16 @@ true CS8604;CS4014 + blazorclient - - - - + + + + + + diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Layout/MainLayout.razor b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Layout/MainLayout.razor similarity index 100% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Layout/MainLayout.razor rename to src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Layout/MainLayout.razor diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Pages/Chat.razor b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Pages/Chat.razor new file mode 100644 index 00000000000000..6009840f502213 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Pages/Chat.razor @@ -0,0 +1,34 @@ +@page "/" +@inject NavigationManager NavigationManager + +

Chat Room

+@code { + private SignalRTest signalRTest = new(); + + // remove when https://github.com/dotnet/runtime/issues/96546 is fixed + // log that rendering is about to start in case we hit the issue before OnAfterRender is called + protected override bool ShouldRender() + { + bool shouldRender = base.ShouldRender(); + TestOutput.WriteLine($"ShouldRender = {shouldRender}"); + return shouldRender; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + TestOutput.WriteLine($"SignalRTest is started on CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); + try + { + int result = await signalRTest.Run(NavigationManager.BaseUri, NavigationManager.Uri); + TestOutput.WriteLine($"SignalRTest finished with code {result}. WASM EXIT {result}"); + } + catch (Exception ex) + { + TestOutput.WriteLine($"SignalRTest failed with exception {ex}. WASM EXIT -1"); + } + } + base.OnAfterRenderAsync(firstRender); + } +} diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Program.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Program.cs similarity index 95% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Program.cs rename to src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Program.cs index 67a2fb06d6a1e1..bcc0dff43d9868 100644 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/Program.cs +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Program.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using BlazorHosted.Client; +using BlazorClient; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/_Imports.razor b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/_Imports.razor similarity index 72% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/_Imports.razor rename to src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/_Imports.razor index d39afd384f8990..1c193c143df2ce 100644 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/_Imports.razor +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/_Imports.razor @@ -2,5 +2,6 @@ @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.JSInterop -@using BlazorHosted.Client -@using BlazorHosted.Client.Layout \ No newline at end of file +@using BlazorClient +@using BlazorClient.Layout +@using Shared \ No newline at end of file diff --git a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/wwwroot/index.html b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/wwwroot/index.html similarity index 62% rename from src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/wwwroot/index.html rename to src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/wwwroot/index.html index 56dd2027fdf839..f911682fdf48bb 100644 --- a/src/mono/wasm/testassets/BlazorHostedApp/BlazorHosted.Client/wwwroot/index.html +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/wwwroot/index.html @@ -5,7 +5,7 @@ BlazorHosted - + @@ -16,14 +16,7 @@ Reload 🗙 - - + diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/QueryParser.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/QueryParser.cs new file mode 100644 index 00000000000000..b863fa4ed54914 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/QueryParser.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Specialized; + +namespace Shared; + +public static class QueryParser +{ + public static string GetValue(NameValueCollection parameters, string key) + { + var values = parameters.GetValues(key); + if (values == null || values.Length == 0) + { + throw new Exception($"Parameter '{key}' is required in the query string"); + } + if (values.Length > 1) + { + throw new Exception($"Parameter '{key}' should be unique in the query string"); + } + return values[0]; + } +} diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/Shared.csproj b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/Shared.csproj new file mode 100644 index 00000000000000..5980a8781983ac --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/Shared.csproj @@ -0,0 +1,19 @@ + + + + net9.0 + Library + true + enable + CA2007 + + + + + + + + + + + diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/SignalRTest.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/SignalRTest.cs new file mode 100644 index 00000000000000..5b4253646413b5 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/SignalRTest.cs @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Specialized; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http.Connections; +using Microsoft.AspNetCore.SignalR.Client; +using System.Web; + +namespace Shared; + +public class SignalRTest +{ + private TaskCompletionSource? tcs; + private HubConnection? _hubConnection; + private string transport = string.Empty; + private string message = string.Empty; + private string wrongQueryError = "Query string with parameters 'message' and 'transport' is required"; + + public async Task Run(string origin, string fullUrl) + { + tcs = new TaskCompletionSource(); + GetQueryParameters(fullUrl); + await Connect(origin); + await SignalRPassMessages(); + + int delayInMin = 2; + await Task.WhenAny( + tcs!.Task, + Task.Delay(TimeSpan.FromMinutes(delayInMin))); + + if (!tcs!.Task.IsCompleted) + throw new TimeoutException($"Test timed out after waiting {delayInMin} minutes for process to exit."); + return tcs.Task.Result; + + } + + private void SetResult(int value) => tcs?.SetResult(value); + + private void GetQueryParameters(string url) + { + var uri = new Uri(url); + if (string.IsNullOrEmpty(uri.Query)) + { + throw new Exception(wrongQueryError); + } + var parameters = HttpUtility.ParseQueryString(uri.Query); + if (parameters == null) + { + throw new Exception(wrongQueryError); + } + transport = QueryParser.GetValue(parameters, "transport"); + message = $"{transport} {QueryParser.GetValue(parameters, "message")}" ; + TestOutput.WriteLine($"Finished GetQueryParameters on CurrentManagedThreadId={Environment.CurrentManagedThreadId}."); + } + + private async Task Connect(string baseUri) + { + string hubUrl = new Uri(new Uri(baseUri), "chathub").ToString(); + Console.WriteLine($"hubUrl: {hubUrl}"); + HttpTransportType httpTransportType = StringToTransportType(transport); + _hubConnection = new HubConnectionBuilder() + .WithUrl(hubUrl, options => + { + options.Transports = httpTransportType; + }) + .Build(); + + _hubConnection.On("ReceiveMessage", async (message) => + { + TestOutput.WriteLine($"Message = [{message}]. ReceiveMessage from server on CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); + await DisposeHubConnection(); + SetResult(0); + }); + TestOutput.WriteLine($"Subscribed to ReceiveMessage by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); + + await _hubConnection.StartAsync(); + TestOutput.WriteLine($"SignalR connected by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); + } + + private static HttpTransportType StringToTransportType(string transport) + { + switch (transport.ToLowerInvariant()) + { + case "longpolling": + return HttpTransportType.LongPolling; + case "websockets": + return HttpTransportType.WebSockets; + default: + throw new Exception($"{transport} is invalid transport type"); + } + } + + private async Task SignalRPassMessages() => + await Task.Run(async () => + { + if (_hubConnection == null) + throw new Exception("Cannot send messages before establishing hub connection"); + await _hubConnection!.SendAsync("SendMessage", message, Environment.CurrentManagedThreadId); + TestOutput.WriteLine($"SignalRPassMessages was sent by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); + }); + + private async Task DisposeHubConnection() + { + if (_hubConnection != null) + { + _hubConnection.Remove("ReceiveMessage"); + await _hubConnection.DisposeAsync(); + _hubConnection = null; + } + TestOutput.WriteLine($"SignalR disconnected by CurrentManagedThreadId={Environment.CurrentManagedThreadId}"); + } +} diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/TestOutput.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/TestOutput.cs new file mode 100644 index 00000000000000..3cb92a24277c28 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/Shared/TestOutput.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Shared; + +public static class TestOutput +{ + public static void WriteLine(string message) + { + Console.WriteLine("TestOutput -> " + message); + } + + public static void WriteLine(object message) + { + Console.Write("TestOutput -> "); + Console.WriteLine(message); + } +} diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/Program.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/Program.cs new file mode 100644 index 00000000000000..88bed62c360863 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/Program.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading.Tasks; +using Shared; + +public partial class Program +{ + public static async Task Main(string[] args) + { + if (args.Length < 2) + throw new Exception("Expected url origin and href passed as arguments"); + + SignalRTest test = new(); + Console.WriteLine($"arg0: {args[0]}, arg1: {args[1]}"); + int result = await test.Run(origin: args[0], fullUrl: args[1]); + if (result != 0) + throw new Exception($"WasmBrowser finished with non-success code: {result}"); + } +} diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/TestOutput.cs b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/TestOutput.cs new file mode 100644 index 00000000000000..5755b753b5e492 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/TestOutput.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +public static class TestOutput +{ + public static void WriteLine(string message) + { + Console.WriteLine("TestOutput -> " + message); + } + + public static void WriteLine(object message) + { + Console.Write("TestOutput -> "); + Console.WriteLine(message); + } +} diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/WasmBrowserClient.csproj b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/WasmBrowserClient.csproj new file mode 100644 index 00000000000000..a74e1246d8bddf --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/WasmBrowserClient.csproj @@ -0,0 +1,17 @@ + + + net9.0 + browser-wasm + Exe + true + enable + + CA1050;CA2007;CA1861;IL2104 + true + wasmclient + + + + + + diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/wwwroot/index.html b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/wwwroot/index.html new file mode 100644 index 00000000000000..86bc345d2e23ad --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/wwwroot/index.html @@ -0,0 +1,17 @@ + + + + + + + WasmBrowser + + + + + + + + + + \ No newline at end of file diff --git a/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/wwwroot/main.js b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/wwwroot/main.js new file mode 100644 index 00000000000000..f182fd9eff9919 --- /dev/null +++ b/src/mono/wasm/testassets/WasmOnAspNetCore/WasmBrowserClient/wwwroot/main.js @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +import { dotnet, exit } from './_framework/dotnet.js' + +try { + const dotnetRuntime = await dotnet + .withElementOnExit() + .withExitCodeLogging() + .withExitOnUnhandledError() + .create(); + const config = dotnetRuntime.getConfig(); + var url = window.location.origin + window.location.pathname; + await dotnetRuntime.runMainAndExit(config.mainAssemblyName, [url, window.location.href]); + +} +catch (err) { + exit(2, err); +} \ No newline at end of file diff --git a/src/mono/wasm/testassets/native-libs/local.c b/src/mono/wasm/testassets/native-libs/local.c new file mode 100644 index 00000000000000..4d7a660513c1fb --- /dev/null +++ b/src/mono/wasm/testassets/native-libs/local.c @@ -0,0 +1,10 @@ +#include +int ManagedFunc(int number); + +void UnmanagedFunc() +{ + int ret = 0; + printf("UnmanagedFunc calling ManagedFunc\n"); + ret = ManagedFunc(123); + printf("ManagedFunc returned %d\n", ret); +} \ No newline at end of file diff --git a/src/native/containers/containers.cmake b/src/native/containers/containers.cmake index 16c41eab5619f8..4749dceea2dd9a 100644 --- a/src/native/containers/containers.cmake +++ b/src/native/containers/containers.cmake @@ -13,6 +13,8 @@ list(APPEND SHARED_CONTAINER_SOURCES # dn-simdhash-string-ptr.c # dn-simdhash-u32-ptr.c # dn-simdhash-ptr-ptr.c + # dn-simdhash-ght-compatible.c + # dn-simdhash-ptrpair-ptr.c ) list(APPEND SHARED_CONTAINER_HEADERS diff --git a/src/native/containers/dn-simdhash-arch.h b/src/native/containers/dn-simdhash-arch.h index d99288e3476ac3..22f3902eafa804 100644 --- a/src/native/containers/dn-simdhash-arch.h +++ b/src/native/containers/dn-simdhash-arch.h @@ -92,15 +92,10 @@ build_search_vector (uint8_t needle) // returns an index in range 0-13 on match, 14-32 if no match static DN_FORCEINLINE(uint32_t) -find_first_matching_suffix ( +find_first_matching_suffix_simd ( dn_simdhash_search_vector needle, // Only used by the vectorized implementations; discarded by scalar. - dn_simdhash_suffixes haystack, - // HACK: Pass the address of haystack.values directly, for scalar fallback. - // Without this, clang makes a full unaligned copy of haystack before calling us. - // Discarded by the vectorized implementations. - uint8_t haystack_values[DN_SIMDHASH_VECTOR_WIDTH], - uint32_t count + dn_simdhash_suffixes haystack ) { #if defined(__wasm_simd128__) return ctz(wasm_i8x16_bitmask(wasm_i8x16_eq(needle.vec, haystack.vec))); @@ -123,37 +118,8 @@ find_first_matching_suffix ( msb.b[1] = vaddv_u8(vget_high_u8(masked.vec)); return ctz(msb.u); #else - // HACK: We can't put this in a common helper function without introducing a temporary - // unaligned copy-from-table-to-stack in wasm-without-simd -#define ITER(offset) \ - if (needle == haystack_values[offset]) \ - return offset; - - // It is safe to unroll this without bounds checks - // One would expect this to blow out the branch predictor, but in my testing - // it's significantly faster when there is no match, and slightly faster - // for cases where there is a match. - // Looping from 0-count is slower than this in my testing, even though it's - // going to check fewer suffixes most of the time - probably due to the - // comparison against count for each suffix. - // FIXME: If we move this into the specialization header, we can limit the - // number of unrolled iterations to the number of keys in the bucket. - ITER(0); - ITER(1); - ITER(2); - ITER(3); - ITER(4); - ITER(5); - ITER(6); - ITER(7); - ITER(8); - ITER(9); - ITER(10); - ITER(11); - ITER(12); - ITER(13); -#undef ITER - return 32; + dn_simdhash_assert(!"Scalar fallback should be in use here"); + return 32; #endif } @@ -194,17 +160,12 @@ build_search_vector (uint8_t needle) // returns an index in range 0-13 on match, 14-32 if no match static DN_FORCEINLINE(uint32_t) -find_first_matching_suffix_internal ( - __m128i needle, __m128i haystack, - uint32_t count +find_first_matching_suffix_simd ( + dn_simdhash_search_vector needle, dn_simdhash_suffixes haystack ) { - return ctz(_mm_movemask_epi8(_mm_cmpeq_epi8(needle, haystack))); + return ctz(_mm_movemask_epi8(_mm_cmpeq_epi8(needle.m128, haystack.m128))); } -// use a macro to discard haystack_values, otherwise MSVC's codegen is worse -#define find_first_matching_suffix(needle, haystack, haystack_values, count) \ - find_first_matching_suffix_internal(needle.m128, haystack.m128, count) - #else // unknown compiler and/or unknown non-simd arch #define DN_SIMDHASH_USE_SCALAR_FALLBACK 1 @@ -228,22 +189,6 @@ build_search_vector (uint8_t needle) return needle; } -// returns an index in range 0-14 on match, 32 if no match -static DN_FORCEINLINE(uint32_t) -find_first_matching_suffix ( - dn_simdhash_search_vector needle, dn_simdhash_suffixes haystack, - uint8_t haystack_values[DN_SIMDHASH_VECTOR_WIDTH], uint32_t count -) { - // TODO: It might be profitable to hand-unroll this loop, but right now doing so - // hits a bug in clang and generates really bad WASM. - // HACK: We can't put this in a common helper function without introducing a temporary - // unaligned copy-from-table-to-stack in wasm-without-simd - for (uint32_t i = 0; i < count; i++) - if (needle == haystack_values[i]) - return i; - return 32; -} - #endif // end of clang/gcc or msvc or fallback #endif // __DN_SIMDHASH_ARCH_H__ diff --git a/src/native/containers/dn-simdhash-ght-compatible.c b/src/native/containers/dn-simdhash-ght-compatible.c index 330f2a14f7385a..eced9aac478c89 100644 --- a/src/native/containers/dn-simdhash-ght-compatible.c +++ b/src/native/containers/dn-simdhash-ght-compatible.c @@ -80,7 +80,6 @@ dn_simdhash_ght_replaced (dn_simdhash_ght_data data, void * old_key, void * new_ #define DN_SIMDHASH_NO_DEFAULT_NEW 1 #include "dn-simdhash-specialization.h" -#include "dn-simdhash-ght-compatible.h" dn_simdhash_ght_t * dn_simdhash_ght_new ( diff --git a/src/native/containers/dn-simdhash-ght-compatible.h b/src/native/containers/dn-simdhash-ght-compatible.h index b99d67477ccc5b..4474f02346d3b6 100644 --- a/src/native/containers/dn-simdhash-ght-compatible.h +++ b/src/native/containers/dn-simdhash-ght-compatible.h @@ -1,3 +1,8 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +typedef dn_simdhash_t dn_simdhash_ght_t; + typedef void (*dn_simdhash_ght_destroy_func) (void * data); typedef unsigned int (*dn_simdhash_ght_hash_func) (const void * key); typedef int32_t (*dn_simdhash_ght_equal_func) (const void * a, const void * b); diff --git a/src/native/containers/dn-simdhash-ptrpair-ptr.c b/src/native/containers/dn-simdhash-ptrpair-ptr.c new file mode 100644 index 00000000000000..d377647b6636ac --- /dev/null +++ b/src/native/containers/dn-simdhash-ptrpair-ptr.c @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include +#include "dn-simdhash.h" + +#include "dn-simdhash-utils.h" + +typedef struct dn_ptrpair_t { + void *first; + void *second; +} dn_ptrpair_t; + +static inline uint32_t +dn_ptrpair_t_hash (dn_ptrpair_t key) +{ + return (MurmurHash3_32_ptr(key.first, 0) ^ MurmurHash3_32_ptr(key.second, 1)); +} + +static inline uint8_t +dn_ptrpair_t_equals (dn_ptrpair_t lhs, dn_ptrpair_t rhs) +{ + return (lhs.first == rhs.first) && (lhs.second == rhs.second); +} + +#define DN_SIMDHASH_T dn_simdhash_ptrpair_ptr +#define DN_SIMDHASH_KEY_T dn_ptrpair_t +#define DN_SIMDHASH_VALUE_T void * +#define DN_SIMDHASH_KEY_HASHER(hash, key) dn_ptrpair_t_hash(key) +#define DN_SIMDHASH_KEY_EQUALS(hash, lhs, rhs) dn_ptrpair_t_equals(lhs, rhs) +#if SIZEOF_VOID_P == 8 +// 192 bytes holds 12 16-byte blocks, so 11 keys and one suffix table +#define DN_SIMDHASH_BUCKET_CAPACITY 11 +#else +// 128 bytes holds 16 8-byte blocks, so 14 keys and one suffix table +#define DN_SIMDHASH_BUCKET_CAPACITY 14 +#endif + +#include "dn-simdhash-specialization.h" diff --git a/src/native/containers/dn-simdhash-specialization.h b/src/native/containers/dn-simdhash-specialization.h index 093ffaf20a7a4e..7c5d9b2ecdb1b5 100644 --- a/src/native/containers/dn-simdhash-specialization.h +++ b/src/native/containers/dn-simdhash-specialization.h @@ -95,6 +95,48 @@ dn_simdhash_meta_t DN_SIMDHASH_T_META = { sizeof(DN_SIMDHASH_INSTANCE_DATA_T), }; +static DN_FORCEINLINE(uint32_t) +find_first_matching_suffix_scalar ( + uint8_t needle, + uint8_t haystack[DN_SIMDHASH_VECTOR_WIDTH] +) { + uint32_t result = 32; + // ITERs for indices beyond our specialization's bucket capacity will be + // constant-false and not check the specific bucket slot +#define ITER(offset) \ + { \ + /* Avoid MSVC C4127 by computing this separately in a temp local */ \ + uint8_t in_bounds = (offset < DN_SIMDHASH_BUCKET_CAPACITY); \ + if (in_bounds && (needle == haystack[offset])) \ + result = offset; \ + } + + // It is safe to unroll this without bounds checks + // Looping from 0-count is slower than this in my testing, even though it's + // going to check fewer suffixes most of the time - probably due to the + // comparison against count for each suffix. + // Scanning in reverse and conditionally modifying result allows clang to + // emit a chain of 'select' operations per slot on wasm, which produces + // smaller code that seems to be much faster than a chain of + // 'if (...) return' for successful matches, and only slightly slower + // for failed matches + ITER(13); + ITER(12); + ITER(11); + ITER(10); + ITER(9); + ITER(8); + ITER(7); + ITER(6); + ITER(5); + ITER(4); + ITER(3); + ITER(2); + ITER(1); + ITER(0); +#undef ITER + return result; +} static DN_FORCEINLINE(void) check_self (DN_SIMDHASH_T_PTR self) @@ -152,7 +194,12 @@ DN_SIMDHASH_SCAN_BUCKET_INTERNAL (DN_SIMDHASH_T_PTR hash, bucket_t *restrict buc overflow_count = dn_simdhash_extract_lane(bucket_suffixes, DN_SIMDHASH_CASCADED_SLOT); // We could early-out here when count==0, but it doesn't appear to meaningfully improve // search performance to do so, and might actually worsen it - uint32_t index = find_first_matching_suffix(search_vector, bucket_suffixes, bucket_suffixes.values, count); +#ifdef DN_SIMDHASH_USE_SCALAR_FALLBACK + uint32_t index = find_first_matching_suffix_scalar(search_vector, bucket->suffixes.values); +#else + uint32_t index = find_first_matching_suffix_simd(search_vector, bucket_suffixes); +#endif +#undef bucket_suffixes for (; index < count; index++) { // FIXME: Could be profitable to manually hoist the data load outside of the loop, // if not out of SCAN_BUCKET_INTERNAL entirely. Clang appears to do LICM on it. @@ -164,8 +211,6 @@ DN_SIMDHASH_SCAN_BUCKET_INTERNAL (DN_SIMDHASH_T_PTR hash, bucket_t *restrict buc return index; } -#undef bucket_suffixes - if (overflow_count) return DN_SIMDHASH_SCAN_BUCKET_OVERFLOWED; else @@ -173,13 +218,13 @@ DN_SIMDHASH_SCAN_BUCKET_INTERNAL (DN_SIMDHASH_T_PTR hash, bucket_t *restrict buc } // Helper macros so that we can optimize and change scan logic more easily -#define BEGIN_SCAN_BUCKETS(initial_index, bucket_index, bucket_address) \ +#define BEGIN_SCAN_BUCKETS(buffers, initial_index, bucket_index, bucket_address) \ { \ uint32_t bucket_index = initial_index, scan_buckets_length = buffers.buckets_length; \ bucket_t *restrict bucket_address = address_of_bucket(buffers, bucket_index); \ do { -#define END_SCAN_BUCKETS(initial_index, bucket_index, bucket_address) \ +#define END_SCAN_BUCKETS(buffers, initial_index, bucket_index, bucket_address) \ bucket_index++; \ bucket_address++; \ /* Wrap around if we hit the last bucket. */ \ @@ -211,7 +256,7 @@ DN_SIMDHASH_SCAN_BUCKET_INTERNAL (DN_SIMDHASH_T_PTR hash, bucket_t *restrict buc static void adjust_cascaded_counts (dn_simdhash_buffers_t buffers, uint32_t first_bucket_index, uint32_t last_bucket_index, uint8_t increase) { - BEGIN_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + BEGIN_SCAN_BUCKETS(buffers, first_bucket_index, bucket_index, bucket_address) if (bucket_index == last_bucket_index) break; @@ -224,26 +269,25 @@ adjust_cascaded_counts (dn_simdhash_buffers_t buffers, uint32_t first_bucket_ind dn_simdhash_bucket_set_cascaded_count(bucket_address->suffixes, cascaded_count - 1); } } - END_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + END_SCAN_BUCKETS(buffers, first_bucket_index, bucket_index, bucket_address) } -static DN_SIMDHASH_VALUE_T * +static DN_FORCEINLINE(DN_SIMDHASH_VALUE_T *) DN_SIMDHASH_FIND_VALUE_INTERNAL (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, uint32_t key_hash) { - dn_simdhash_buffers_t buffers = hash->buffers; uint8_t suffix = dn_simdhash_select_suffix(key_hash); - uint32_t first_bucket_index = dn_simdhash_select_bucket_index(buffers, key_hash); + uint32_t first_bucket_index = dn_simdhash_select_bucket_index(hash->buffers, key_hash); dn_simdhash_search_vector search_vector = build_search_vector(suffix); - BEGIN_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + BEGIN_SCAN_BUCKETS(hash->buffers, first_bucket_index, bucket_index, bucket_address) int index_in_bucket = DN_SIMDHASH_SCAN_BUCKET_INTERNAL(hash, bucket_address, key, search_vector); if (index_in_bucket >= 0) { uint32_t value_slot_index = (bucket_index * DN_SIMDHASH_BUCKET_CAPACITY) + index_in_bucket; - return address_of_value(buffers, value_slot_index); + return address_of_value(hash->buffers, value_slot_index); } else if (index_in_bucket == DN_SIMDHASH_SCAN_BUCKET_NO_OVERFLOW) { return NULL; } - END_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + END_SCAN_BUCKETS(hash->buffers, first_bucket_index, bucket_index, bucket_address) return NULL; } @@ -288,12 +332,11 @@ DN_SIMDHASH_TRY_INSERT_INTERNAL (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, return DN_SIMDHASH_INSERT_NEED_TO_GROW; } - dn_simdhash_buffers_t buffers = hash->buffers; uint8_t suffix = dn_simdhash_select_suffix(key_hash); uint32_t first_bucket_index = dn_simdhash_select_bucket_index(hash->buffers, key_hash); dn_simdhash_search_vector search_vector = build_search_vector(suffix); - BEGIN_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + BEGIN_SCAN_BUCKETS(hash->buffers, first_bucket_index, bucket_index, bucket_address) // If necessary, check the current bucket for the key if (mode != DN_SIMDHASH_INSERT_MODE_REHASHING) { int index_in_bucket = DN_SIMDHASH_SCAN_BUCKET_INTERNAL(hash, bucket_address, key, search_vector); @@ -325,19 +368,19 @@ DN_SIMDHASH_TRY_INSERT_INTERNAL (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, *key_slot_address = key; // Now store the value, it's in a different cache line uint32_t value_slot_index = (bucket_index * DN_SIMDHASH_BUCKET_CAPACITY) + new_index; - DN_SIMDHASH_VALUE_T *restrict value_slot_address = address_of_value(buffers, value_slot_index); + DN_SIMDHASH_VALUE_T *restrict value_slot_address = address_of_value(hash->buffers, value_slot_index); *value_slot_address = value; // printf("Inserted [%zd, %zd] in bucket %d at index %d\n", key, value, bucket_index, new_index); // If we cascaded out of our original target bucket, scan through our probe path // and increase the cascade counters. We have to wait until now to do that, because // during the process of getting here we may end up finding a duplicate, which would // leave the cascade counters in a corrupted state - adjust_cascaded_counts(buffers, first_bucket_index, bucket_index, 1); + adjust_cascaded_counts(hash->buffers, first_bucket_index, bucket_index, 1); return DN_SIMDHASH_INSERT_OK_ADDED_NEW; } // The current bucket is full, so try the next bucket. - END_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + END_SCAN_BUCKETS(hash->buffers, first_bucket_index, bucket_index, bucket_address) return DN_SIMDHASH_INSERT_NEED_TO_GROW; } @@ -362,10 +405,9 @@ DN_SIMDHASH_REHASH_INTERNAL (DN_SIMDHASH_T_PTR hash, dn_simdhash_buffers_t old_b static void DN_SIMDHASH_DESTROY_ALL (DN_SIMDHASH_T_PTR hash) { - dn_simdhash_buffers_t buffers = hash->buffers; - BEGIN_SCAN_PAIRS(buffers, key_address, value_address) + BEGIN_SCAN_PAIRS(hash->buffers, key_address, value_address) DN_SIMDHASH_ON_REMOVE(DN_SIMDHASH_GET_DATA(hash), *key_address, *value_address); - END_SCAN_PAIRS(buffers, key_address, value_address) + END_SCAN_PAIRS(hash->buffers, key_address, value_address) } #endif @@ -385,14 +427,6 @@ dn_simdhash_vtable_t DN_SIMDHASH_T_VTABLE = { DN_SIMDHASH_T_PTR DN_SIMDHASH_NEW (uint32_t capacity, dn_allocator_t *allocator) { - // If this isn't satisfied, the generic code will allocate incorrectly sized buffers - // HACK: Use static_assert because for some reason assert produces unused variable warnings only on CI - struct silence_nuisance_msvc_warning { bucket_t a, b; }; - static_assert( - sizeof(struct silence_nuisance_msvc_warning) == (sizeof(bucket_t) * 2), - "Inconsistent spacing/sizing for bucket_t" - ); - return dn_simdhash_new_internal(&DN_SIMDHASH_T_META, DN_SIMDHASH_T_VTABLE, capacity, allocator); } #endif @@ -475,12 +509,11 @@ DN_SIMDHASH_TRY_REMOVE_WITH_HASH (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, { check_self(hash); - dn_simdhash_buffers_t buffers = hash->buffers; uint8_t suffix = dn_simdhash_select_suffix(key_hash); - uint32_t first_bucket_index = dn_simdhash_select_bucket_index(buffers, key_hash); + uint32_t first_bucket_index = dn_simdhash_select_bucket_index(hash->buffers, key_hash); dn_simdhash_search_vector search_vector = build_search_vector(suffix); - BEGIN_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + BEGIN_SCAN_BUCKETS(hash->buffers, first_bucket_index, bucket_index, bucket_address) int index_in_bucket = DN_SIMDHASH_SCAN_BUCKET_INTERNAL(hash, bucket_address, key, search_vector); if (index_in_bucket >= 0) { // We found the item. Replace it with the last item in the bucket, then erase @@ -490,8 +523,8 @@ DN_SIMDHASH_TRY_REMOVE_WITH_HASH (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, uint32_t value_slot_index = (bucket_index * DN_SIMDHASH_BUCKET_CAPACITY) + index_in_bucket, replacement_value_slot_index = (bucket_index * DN_SIMDHASH_BUCKET_CAPACITY) + replacement_index_in_bucket; - DN_SIMDHASH_VALUE_T *value_address = address_of_value(buffers, value_slot_index); - DN_SIMDHASH_VALUE_T *replacement_address = address_of_value(buffers, replacement_value_slot_index); + DN_SIMDHASH_VALUE_T *value_address = address_of_value(hash->buffers, value_slot_index); + DN_SIMDHASH_VALUE_T *replacement_address = address_of_value(hash->buffers, replacement_value_slot_index); DN_SIMDHASH_KEY_T *key_address = &bucket_address->keys[index_in_bucket]; DN_SIMDHASH_KEY_T *replacement_key_address = &bucket_address->keys[replacement_index_in_bucket]; @@ -529,7 +562,7 @@ DN_SIMDHASH_TRY_REMOVE_WITH_HASH (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, // to go through all the buckets we visited on the way here and reduce // their cascade counters (if possible), to maintain better scan performance. if (bucket_index != first_bucket_index) - adjust_cascaded_counts(buffers, first_bucket_index, bucket_index, 0); + adjust_cascaded_counts(hash->buffers, first_bucket_index, bucket_index, 0); #if DN_SIMDHASH_HAS_REMOVE_HANDLER // We've finished removing the item, so we're in a consistent state and can notify @@ -539,7 +572,7 @@ DN_SIMDHASH_TRY_REMOVE_WITH_HASH (DN_SIMDHASH_T_PTR hash, DN_SIMDHASH_KEY_T key, return 1; } else if (index_in_bucket == DN_SIMDHASH_SCAN_BUCKET_NO_OVERFLOW) return 0; - END_SCAN_BUCKETS(first_bucket_index, bucket_index, bucket_address) + END_SCAN_BUCKETS(hash->buffers, first_bucket_index, bucket_index, bucket_address) return 0; } diff --git a/src/native/containers/dn-simdhash-specializations.h b/src/native/containers/dn-simdhash-specializations.h index 4966c7575d19a0..9533edfc5f3d1f 100644 --- a/src/native/containers/dn-simdhash-specializations.h +++ b/src/native/containers/dn-simdhash-specializations.h @@ -59,4 +59,19 @@ typedef struct dn_simdhash_str_key dn_simdhash_str_key; #include "dn-simdhash-ght-compatible.h" + +typedef struct dn_ptrpair_t { + void *first, *second; +} dn_ptrpair_t; + +#define DN_SIMDHASH_T dn_simdhash_ptrpair_ptr +#define DN_SIMDHASH_KEY_T dn_ptrpair_t +#define DN_SIMDHASH_VALUE_T void * + +#include "dn-simdhash-specialization-declarations.h" + +#undef DN_SIMDHASH_T +#undef DN_SIMDHASH_KEY_T +#undef DN_SIMDHASH_VALUE_T + #endif diff --git a/src/native/containers/dn-simdhash.c b/src/native/containers/dn-simdhash.c index 03d4d2bf3951aa..d1e2b6e330b6ef 100644 --- a/src/native/containers/dn-simdhash.c +++ b/src/native/containers/dn-simdhash.c @@ -119,8 +119,7 @@ dn_simdhash_clear (dn_simdhash_t *hash) if (hash->vtable.destroy_all) hash->vtable.destroy_all(hash); hash->count = 0; - // TODO: Scan through buckets sequentially and only erase ones with data in them - // Maybe skip erasing the key slots too? + // TODO: Implement a fast clear algorithm that scans buckets and only clears ones w/nonzero count memset(hash->buffers.buckets, 0, hash->buffers.buckets_length * hash->meta->bucket_size_bytes); // Skip this for performance; memset is especially slow in wasm // memset(hash->buffers.values, 0, hash->buffers.values_length * hash->meta->value_size); @@ -140,6 +139,19 @@ dn_simdhash_count (dn_simdhash_t *hash) return hash->count; } +uint32_t +dn_simdhash_overflow_count (dn_simdhash_t *hash) +{ + assert(hash); + uint32_t result = 0; + for (uint32_t bucket_index = 0; bucket_index < hash->buffers.buckets_length; bucket_index++) { + uint8_t *suffixes = ((uint8_t *)hash->buffers.buckets) + (bucket_index * hash->meta->bucket_size_bytes); + uint8_t cascade_count = suffixes[DN_SIMDHASH_CASCADED_SLOT]; + result += cascade_count; + } + return result; +} + void dn_simdhash_ensure_capacity (dn_simdhash_t *hash, uint32_t capacity) { diff --git a/src/native/containers/dn-simdhash.h b/src/native/containers/dn-simdhash.h index 2a26083ec7df1c..a2d6e87c9045fe 100644 --- a/src/native/containers/dn-simdhash.h +++ b/src/native/containers/dn-simdhash.h @@ -108,12 +108,9 @@ dn_simdhash_select_suffix (uint32_t key_hash) return (key_hash >> 24) | DN_SIMDHASH_SUFFIX_SALT; } -static DN_FORCEINLINE(uint32_t) -dn_simdhash_select_bucket_index (dn_simdhash_buffers_t buffers, uint32_t key_hash) -{ - // This relies on bucket count being a power of two. - return key_hash & (buffers.buckets_length - 1); -} +// This relies on bucket count being a power of two. +#define dn_simdhash_select_bucket_index(buffers, key_hash) \ + ((key_hash) & ((buffers).buckets_length - 1)) // Creates a simdhash with the provided configuration metadata, vtable, size, and allocator. @@ -147,6 +144,11 @@ dn_simdhash_capacity (dn_simdhash_t *hash); uint32_t dn_simdhash_count (dn_simdhash_t *hash); +// Returns the estimated number of items that have overflowed out of a bucket. +// WARNING: This is expensive to calculate. +uint32_t +dn_simdhash_overflow_count (dn_simdhash_t *hash); + // Automatically resizes the table if it is too small to hold the requested number // of items. Will not shrink the table if it is already bigger. void diff --git a/src/native/containers/simdhash-benchmark/Makefile b/src/native/containers/simdhash-benchmark/Makefile index 7aa316ba1555b6..6349d1c96538b5 100644 --- a/src/native/containers/simdhash-benchmark/Makefile +++ b/src/native/containers/simdhash-benchmark/Makefile @@ -2,25 +2,32 @@ dn_deps := $(wildcard ../*.c) $(wildcard ../*.h) benchmark_deps := $(wildcard ./*.c) $(wildcard ./*.h) +# I don't know why this is necessary +nodejs_path := $(shell which node) benchmark_sources := ../dn-simdhash.c ../dn-vector.c ./benchmark.c ../dn-simdhash-u32-ptr.c ../dn-simdhash-string-ptr.c ./ghashtable.c ./all-measurements.c common_options := -g -O3 -DNO_CONFIG_H -lm -DNDEBUG +ifeq ($(SIMD), 0) + wasm_options := -mbulk-memory +else + wasm_options := -mbulk-memory -msimd128 +endif benchmark-native: $(dn_deps) $(benchmark_deps) clang $(benchmark_sources) $(common_options) -DSIZEOF_VOID_P=8 benchmark-wasm: $(dn_deps) $(benchmark_deps) - ~/Projects/emscripten/emcc $(benchmark_sources) $(common_options) -DSIZEOF_VOID_P=4 -mbulk-memory -msimd128 + ~/Projects/emscripten/emcc $(benchmark_sources) $(common_options) $(wasm_options) -DSIZEOF_VOID_P=4 disassemble-benchmark: benchmark-native benchmark-wasm objdump -d ./a.out > ./a.dis ~/wabt/bin/wasm2wat ./a.out.wasm > ./a.wat run-native: benchmark-native - ./a.out + ./a.out $(FILTER) run-wasm: benchmark-wasm - node ./a.out.js + $(nodejs_path) ./a.out.js $(FILTER) default_target: disassemble-benchmark diff --git a/src/native/containers/simdhash-benchmark/all-measurements.c b/src/native/containers/simdhash-benchmark/all-measurements.c index 2d04bbd4270120..ac3356e69712b0 100644 --- a/src/native/containers/simdhash-benchmark/all-measurements.c +++ b/src/native/containers/simdhash-benchmark/all-measurements.c @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#define _CRT_RAND_S + #include #include #include diff --git a/src/native/containers/simdhash-benchmark/all-measurements.h b/src/native/containers/simdhash-benchmark/all-measurements.h index 2e49927337a34f..e6646f203e49e9 100644 --- a/src/native/containers/simdhash-benchmark/all-measurements.h +++ b/src/native/containers/simdhash-benchmark/all-measurements.h @@ -6,27 +6,57 @@ #ifndef MEASUREMENTS_IMPLEMENTATION #define MEASUREMENTS_IMPLEMENTATION 1 -// If this is too large and libc's rand() is low quality (i.e. MSVC), -// initializing the data will take forever -#define INNER_COUNT 1024 * 16 +#define INNER_COUNT 1024 * 32 #define BASELINE_SIZE 20480 static dn_simdhash_u32_ptr_t *random_u32s_hash; static dn_vector_t *sequential_u32s, *random_u32s, *random_unused_u32s; +// rand() isn't guaranteed to give 32 random bits on all targets, so +// use xoshiro seeded with 4 known integers +// We want to use the same random sequence on every benchmark run, otherwise +// execution times could vary +uint64_t rol64(uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +static uint64_t rng_state[4] = { + 0x6ED11324ABA9232Cul, + 0x1F0C07E6522724A6ul, + 0x293F7FDA2AF571D4ul, + 0x5804EC9FFD70112Aul, +}; + +uint64_t xoshiro256ss() { + uint64_t const result = rol64(rng_state[1] * 5, 7) * 9; + uint64_t const t = rng_state[1] << 17; + + rng_state[2] ^= rng_state[0]; + rng_state[3] ^= rng_state[1]; + rng_state[1] ^= rng_state[2]; + rng_state[0] ^= rng_state[3]; + + rng_state[2] ^= t; + rng_state[3] = rol64(rng_state[3], 45); + + return result; +} + +static uint32_t random_uint () { + return (uint32_t)(xoshiro256ss() & 0xFFFFFFFFu); +} + static void init_data () { random_u32s_hash = dn_simdhash_u32_ptr_new(INNER_COUNT, NULL); sequential_u32s = dn_vector_alloc(sizeof(uint32_t)); random_u32s = dn_vector_alloc(sizeof(uint32_t)); random_unused_u32s = dn_vector_alloc(sizeof(uint32_t)); - // For consistent data between runs - srand(1); for (uint32_t i = 0; i < INNER_COUNT; i++) { dn_vector_push_back(sequential_u32s, i); retry: { - uint32_t key = (uint32_t)(rand() & 0xFFFFFFFFu); + uint32_t key = random_uint(); if (!dn_simdhash_u32_ptr_try_add(random_u32s_hash, key, NULL)) goto retry; @@ -36,7 +66,7 @@ retry: { for (uint32_t i = 0; i < INNER_COUNT; i++) { retry2: { - uint32_t key = (uint32_t)(rand() & 0xFFFFFFFFu); + uint32_t key = random_uint(); if (!dn_simdhash_u32_ptr_try_add(random_u32s_hash, key, NULL)) goto retry2; diff --git a/src/native/containers/simdhash-benchmark/run-benchmark.ps1 b/src/native/containers/simdhash-benchmark/run-benchmark.ps1 index 536ba40cd9144f..9417d16c505cbf 100755 --- a/src/native/containers/simdhash-benchmark/run-benchmark.ps1 +++ b/src/native/containers/simdhash-benchmark/run-benchmark.ps1 @@ -1,2 +1,2 @@ -cl /GS- /O2 /std:c17 ./*.c ../dn-simdhash-u32-ptr.c ../dn-simdhash.c ../dn-vector.c ../dn-simdhash-string-ptr.c /DNO_CONFIG_H /DSIZEOF_VOID_P=8 /Fe:all-measurements.exe +cl /GS- /O2 /std:c17 ./*.c ../dn-simdhash-u32-ptr.c ../dn-simdhash.c ../dn-vector.c ../dn-simdhash-string-ptr.c /DNO_CONFIG_H /DSIZEOF_VOID_P=8 /DNDEBUG /Fe:all-measurements.exe ./all-measurements.exe diff --git a/src/native/corehost/apphost/static/singlefilehost.def b/src/native/corehost/apphost/static/singlefilehost.def index e1208056b83201..9d193783f950e1 100644 --- a/src/native/corehost/apphost/static/singlefilehost.def +++ b/src/native/corehost/apphost/static/singlefilehost.def @@ -18,3 +18,6 @@ g_dacTable = s_dacGlobals ; Used by profilers MetaDataGetDispenser + +; cDAC contract descriptor +DotNetRuntimeContractDescriptor diff --git a/src/native/corehost/apphost/static/singlefilehost_freebsdexports.src b/src/native/corehost/apphost/static/singlefilehost_freebsdexports.src index 1f9c5178218555..da5cab866d93fc 100644 --- a/src/native/corehost/apphost/static/singlefilehost_freebsdexports.src +++ b/src/native/corehost/apphost/static/singlefilehost_freebsdexports.src @@ -10,6 +10,9 @@ g_dacTable ; Used by profilers MetaDataGetDispenser +; cDAC contract descriptor +DotNetRuntimeContractDescriptor + ; FreeBSD needs to reexport these __progname environ diff --git a/src/native/corehost/apphost/static/singlefilehost_unixexports.src b/src/native/corehost/apphost/static/singlefilehost_unixexports.src index 18d5697e84580e..23c60f6b8b162c 100644 --- a/src/native/corehost/apphost/static/singlefilehost_unixexports.src +++ b/src/native/corehost/apphost/static/singlefilehost_unixexports.src @@ -9,3 +9,6 @@ g_dacTable ; Used by profilers MetaDataGetDispenser + +; cDAC contract descriptor +DotNetRuntimeContractDescriptor diff --git a/src/native/corehost/bundle/extractor.cpp b/src/native/corehost/bundle/extractor.cpp index fc0659e82dc32d..ab2c53295055b9 100644 --- a/src/native/corehost/bundle/extractor.cpp +++ b/src/native/corehost/bundle/extractor.cpp @@ -219,7 +219,7 @@ void extractor_t::commit_dir() // Retry the move operation with some wait in between the attempts. This is to workaround for possible file locking // caused by AV software. Basically the extraction process above writes a bunch of executable files to disk // and some AV software may decide to scan them on write. If this happens the files will be locked which blocks - // our ablity to move them. + // our ability to move them. bool extracted_by_concurrent_process = false; bool extracted_by_current_process = diff --git a/src/native/eventpipe/ds-eventpipe-protocol.c b/src/native/eventpipe/ds-eventpipe-protocol.c index d4248e71fe551d..b359102ee0d35a 100644 --- a/src/native/eventpipe/ds-eventpipe-protocol.c +++ b/src/native/eventpipe/ds-eventpipe-protocol.c @@ -46,6 +46,13 @@ eventpipe_collect_tracing_command_try_parse_rundown_requested ( uint32_t *buffer_len, bool *rundown_requested); +static +bool +eventpipe_collect_tracing_command_try_parse_rundown_keyword ( + uint8_t **buffer, + uint32_t *buffer_len, + uint64_t *rundown_keyword); + static bool eventpipe_collect_tracing_command_try_parse_stackwalk_requested ( @@ -78,6 +85,12 @@ eventpipe_collect_tracing3_command_try_parse_payload ( uint8_t *buffer, uint16_t buffer_len); +static +uint8_t * +eventpipe_collect_tracing4_command_try_parse_payload ( + uint8_t *buffer, + uint16_t buffer_len); + static bool eventpipe_protocol_helper_stop_tracing ( @@ -150,6 +163,21 @@ eventpipe_collect_tracing_command_try_parse_rundown_requested ( return ds_ipc_message_try_parse_bool (buffer, buffer_len, rundown_requested); } +static +inline +bool +eventpipe_collect_tracing_command_try_parse_rundown_keyword ( + uint8_t **buffer, + uint32_t *buffer_len, + uint64_t *rundown_keyword) +{ + EP_ASSERT (buffer != NULL); + EP_ASSERT (buffer_len != NULL); + EP_ASSERT (rundown_keyword != NULL); + + return ds_ipc_message_try_parse_uint64_t (buffer, buffer_len, rundown_keyword); +} + static inline bool @@ -299,6 +327,7 @@ eventpipe_collect_tracing_command_try_parse_payload ( ep_raise_error (); instance->rundown_requested = true; instance->stackwalk_requested = true; + instance->rundown_keyword = ep_default_rundown_keyword; ep_on_exit: return (uint8_t *)instance; @@ -330,6 +359,9 @@ eventpipe_collect_tracing2_command_try_parse_payload ( !eventpipe_collect_tracing_command_try_parse_rundown_requested (&buffer_cursor, &buffer_cursor_len, &instance->rundown_requested) || !eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs)) ep_raise_error (); + + instance->rundown_keyword = instance->rundown_requested ? ep_default_rundown_keyword : 0; + instance->stackwalk_requested = true; ep_on_exit: @@ -364,6 +396,42 @@ eventpipe_collect_tracing3_command_try_parse_payload ( !eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs)) ep_raise_error (); + instance->rundown_keyword = instance->rundown_requested ? ep_default_rundown_keyword : 0; + +ep_on_exit: + return (uint8_t *)instance; + +ep_on_error: + ds_eventpipe_collect_tracing_command_payload_free (instance); + instance = NULL; + ep_exit_error_handler (); +} + +static +uint8_t * +eventpipe_collect_tracing4_command_try_parse_payload ( + uint8_t *buffer, + uint16_t buffer_len) +{ + EP_ASSERT (buffer != NULL); + + uint8_t * buffer_cursor = buffer; + uint32_t buffer_cursor_len = buffer_len; + + EventPipeCollectTracingCommandPayload *instance = ds_eventpipe_collect_tracing_command_payload_alloc (); + ep_raise_error_if_nok (instance != NULL); + + instance->incoming_buffer = buffer; + + if (!eventpipe_collect_tracing_command_try_parse_circular_buffer_size (&buffer_cursor, &buffer_cursor_len, &instance->circular_buffer_size_in_mb ) || + !eventpipe_collect_tracing_command_try_parse_serialization_format (&buffer_cursor, &buffer_cursor_len, &instance->serialization_format) || + !eventpipe_collect_tracing_command_try_parse_rundown_keyword (&buffer_cursor, &buffer_cursor_len, &instance->rundown_keyword) || + !eventpipe_collect_tracing_command_try_parse_stackwalk_requested (&buffer_cursor, &buffer_cursor_len, &instance->stackwalk_requested) || + !eventpipe_collect_tracing_command_try_parse_config (&buffer_cursor, &buffer_cursor_len, &instance->provider_configs)) + ep_raise_error (); + + instance->rundown_requested = instance->rundown_keyword != 0; + ep_on_exit: return (uint8_t *)instance; @@ -471,7 +539,7 @@ eventpipe_protocol_helper_collect_tracing ( dn_vector_size (payload->provider_configs), EP_SESSION_TYPE_IPCSTREAM, payload->serialization_format, - payload->rundown_requested, + payload->rundown_keyword, payload->stackwalk_requested, ds_ipc_stream_get_stream_ref (stream), NULL, @@ -544,6 +612,10 @@ ds_eventpipe_protocol_helper_handle_ipc_message ( payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing3_command_try_parse_payload); result = eventpipe_protocol_helper_collect_tracing (payload, stream); break; + case EP_COMMANDID_COLLECT_TRACING_4: + payload = (EventPipeCollectTracingCommandPayload *)ds_ipc_message_try_parse_payload (message, eventpipe_collect_tracing4_command_try_parse_payload); + result = eventpipe_protocol_helper_collect_tracing (payload, stream); + break; case EP_COMMANDID_STOP_TRACING: result = eventpipe_protocol_helper_stop_tracing (message, stream); break; diff --git a/src/native/eventpipe/ds-eventpipe-protocol.h b/src/native/eventpipe/ds-eventpipe-protocol.h index 7a3c4ebd41ff33..14496068a109b9 100644 --- a/src/native/eventpipe/ds-eventpipe-protocol.h +++ b/src/native/eventpipe/ds-eventpipe-protocol.h @@ -20,6 +20,7 @@ // Command = 0x0202 // Command = 0x0203 // Command = 0x0204 +// Command = 0x0205 #if defined(DS_INLINE_GETTER_SETTER) || defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER) struct _EventPipeCollectTracingCommandPayload { #else @@ -40,6 +41,7 @@ struct _EventPipeCollectTracingCommandPayload_Internal { EventPipeSerializationFormat serialization_format; bool rundown_requested; bool stackwalk_requested; + uint64_t rundown_keyword; }; #if !defined(DS_INLINE_GETTER_SETTER) && !defined(DS_IMPL_EVENTPIPE_PROTOCOL_GETTER_SETTER) diff --git a/src/native/eventpipe/ds-types.h b/src/native/eventpipe/ds-types.h index 16d57f4cb7e897..a7596da6052a33 100644 --- a/src/native/eventpipe/ds-types.h +++ b/src/native/eventpipe/ds-types.h @@ -104,6 +104,7 @@ typedef enum { EP_COMMANDID_COLLECT_TRACING = 0x02, EP_COMMANDID_COLLECT_TRACING_2 = 0x03, EP_COMMANDID_COLLECT_TRACING_3 = 0x04, + EP_COMMANDID_COLLECT_TRACING_4 = 0x05, // future } EventPipeCommandId; diff --git a/src/native/eventpipe/ep-session.c b/src/native/eventpipe/ep-session.c index a91dd108c2e997..c79d3972cd5587 100644 --- a/src/native/eventpipe/ep-session.c +++ b/src/native/eventpipe/ep-session.c @@ -133,7 +133,7 @@ ep_session_alloc ( IpcStream *stream, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, bool stackwalk_requested, uint32_t circular_buffer_size_in_mb, const EventPipeProviderConfiguration *providers, @@ -164,7 +164,7 @@ ep_session_alloc ( instance->rundown_enabled = 0; instance->session_type = session_type; instance->format = format; - instance->rundown_requested = rundown_requested; + instance->rundown_keyword = rundown_keyword; instance->synchronous_callback = sync_callback; instance->callback_additional_data = callback_additional_data; @@ -317,17 +317,7 @@ ep_session_enable_rundown (EventPipeSession *session) ep_requires_lock_held (); bool result = false; - - //! This is CoreCLR specific keywords for native ETW events (ending up in event pipe). - //! The keywords below seems to correspond to: - //! GCKeyword (0x00000001) - //! LoaderKeyword (0x00000008) - //! JitKeyword (0x00000010) - //! NgenKeyword (0x00000020) - //! unused_keyword (0x00000100) - //! JittedMethodILToNativeMapKeyword (0x00020000) - //! ThreadTransferKeyword (0x80000000) - const uint64_t keywords = 0x80020139; + const uint64_t keywords = ep_session_get_rundown_keyword (session); const EventPipeEventLevel verbose_logging_level = EP_EVENT_LEVEL_VERBOSE; EventPipeProviderConfiguration rundown_provider; diff --git a/src/native/eventpipe/ep-session.h b/src/native/eventpipe/ep-session.h index 944b38c8e5d3d5..646c4ab566c083 100644 --- a/src/native/eventpipe/ep-session.h +++ b/src/native/eventpipe/ep-session.h @@ -53,7 +53,7 @@ struct _EventPipeSession_Internal { // irrelevant. EventPipeSerializationFormat format; // For determininig if a particular session needs rundown events. - bool rundown_requested; + uint64_t rundown_keyword; // Note - access to this field is NOT synchronized // This functionality is a workaround because we couldn't safely enable/disable the session where we wanted to due to lock-leveling. // we expect to remove it in the future once that limitation is resolved other scenarios are discouraged from using this given that @@ -79,7 +79,7 @@ EP_DEFINE_GETTER(EventPipeSession *, session, uint32_t, index) EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeSessionProviderList *, providers) EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeBufferManager *, buffer_manager) EP_DEFINE_GETTER_REF(EventPipeSession *, session, volatile uint32_t *, rundown_enabled) -EP_DEFINE_GETTER(EventPipeSession *, session, bool, rundown_requested) +EP_DEFINE_GETTER(EventPipeSession *, session, uint64_t, rundown_keyword) EP_DEFINE_GETTER(EventPipeSession *, session, ep_timestamp_t, session_start_time) EP_DEFINE_GETTER(EventPipeSession *, session, ep_timestamp_t, session_start_timestamp) EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeFile *, file) @@ -92,7 +92,7 @@ ep_session_alloc ( IpcStream *stream, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, bool stackwalk_requested, uint32_t circular_buffer_size_in_mb, const EventPipeProviderConfiguration *providers, diff --git a/src/native/eventpipe/ep.c b/src/native/eventpipe/ep.c index 7313fcb856dcd4..b65326a16bcfa1 100644 --- a/src/native/eventpipe/ep.c +++ b/src/native/eventpipe/ep.c @@ -15,6 +15,17 @@ #include "ep-session.h" #include "ep-sample-profiler.h" +//! This is CoreCLR specific keywords for native ETW events (ending up in event pipe). +//! The keywords below seems to correspond to: +//! GCKeyword (0x00000001) +//! LoaderKeyword (0x00000008) +//! JitKeyword (0x00000010) +//! NgenKeyword (0x00000020) +//! unused_keyword (0x00000100) +//! JittedMethodILToNativeMapKeyword (0x00020000) +//! ThreadTransferKeyword (0x80000000) +uint64_t ep_default_rundown_keyword = 0x80020139; + static bool _ep_can_start_threads = false; static dn_vector_t *_ep_deferred_enable_session_ids = NULL; @@ -494,7 +505,7 @@ enable ( options->stream, options->session_type, options->format, - options->rundown_requested, + options->rundown_keyword, options->stackwalk_requested, options->circular_buffer_size_in_mb, options->providers, @@ -589,7 +600,7 @@ disable_holding_lock ( ep_session_disable (session); // WriteAllBuffersToFile, and remove providers. // Do rundown before fully stopping the session unless rundown wasn't requested - if (ep_session_get_rundown_requested (session) && _ep_can_start_threads) { + if ((ep_session_get_rundown_keyword (session) != 0) && _ep_can_start_threads) { ep_session_enable_rundown (session); // Set Rundown provider. EventPipeThread *const thread = ep_thread_get_or_create (); if (thread != NULL) { @@ -908,7 +919,7 @@ enable_default_session_via_env_variables (void) ep_config, ep_rt_config_value_get_output_streaming () ? EP_SESSION_TYPE_FILESTREAM : EP_SESSION_TYPE_FILE, EP_SERIALIZATION_FORMAT_NETTRACE_V4, - true, + ep_default_rundown_keyword, NULL, NULL, NULL); @@ -959,7 +970,7 @@ ep_enable ( uint32_t providers_len, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, IpcStream *stream, EventPipeSessionSynchronousCallback sync_callback, void *callback_additional_data) @@ -975,7 +986,7 @@ ep_enable ( providers_len, session_type, format, - rundown_requested, + rundown_keyword, true, // stackwalk_requested stream, sync_callback, @@ -995,7 +1006,7 @@ ep_enable_2 ( const ep_char8_t *providers_config, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, IpcStream *stream, EventPipeSessionSynchronousCallback sync_callback, void *callback_additional_data) @@ -1073,7 +1084,7 @@ ep_enable_2 ( providers_len, session_type, format, - rundown_requested, + rundown_keyword, stream, sync_callback, callback_additional_data); @@ -1105,7 +1116,7 @@ ep_session_options_init ( uint32_t providers_len, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, bool stackwalk_requested, IpcStream* stream, EventPipeSessionSynchronousCallback sync_callback, @@ -1119,7 +1130,7 @@ ep_session_options_init ( options->providers_len = providers_len; options->session_type = session_type; options->format = format; - options->rundown_requested = rundown_requested; + options->rundown_keyword = rundown_keyword; options->stackwalk_requested = stackwalk_requested; options->stream = stream; options->sync_callback = sync_callback; diff --git a/src/native/eventpipe/ep.h b/src/native/eventpipe/ep.h index b7b31d04cdb036..fd8c019121c1e3 100644 --- a/src/native/eventpipe/ep.h +++ b/src/native/eventpipe/ep.h @@ -13,6 +13,12 @@ extern volatile EventPipeSession *_ep_sessions [EP_MAX_NUMBER_OF_SESSIONS]; extern volatile uint32_t _ep_number_of_sessions; extern volatile uint64_t _ep_allow_write; +/* + * Global constants + */ + +extern uint64_t ep_default_rundown_keyword; + /* * Globals and volatile access functions. */ @@ -119,7 +125,7 @@ typedef struct EventPipeSessionOptions { uint32_t providers_len; EventPipeSessionType session_type; EventPipeSerializationFormat format; - bool rundown_requested; + uint64_t rundown_keyword; bool stackwalk_requested; } EventPipeSessionOptions; @@ -132,7 +138,7 @@ ep_session_options_init ( uint32_t providers_len, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, bool stackwalk_requested, IpcStream *stream, EventPipeSessionSynchronousCallback sync_callback, @@ -164,7 +170,7 @@ ep_enable ( uint32_t providers_len, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, IpcStream *stream, EventPipeSessionSynchronousCallback sync_callback, void *callback_additional_data); @@ -176,7 +182,7 @@ ep_enable_2 ( const ep_char8_t *providers, EventPipeSessionType session_type, EventPipeSerializationFormat format, - bool rundown_requested, + uint64_t rundown_keyword, IpcStream *stream, EventPipeSessionSynchronousCallback sync_callback, void *callback_additional_data); diff --git a/src/native/libs/Common/pal_error_common.h b/src/native/libs/Common/pal_error_common.h index e9de2b793e4086..7541132da7b188 100644 --- a/src/native/libs/Common/pal_error_common.h +++ b/src/native/libs/Common/pal_error_common.h @@ -336,6 +336,8 @@ inline static int32_t ConvertErrorPlatformToPal(int32_t platformErrno) case EWOULDBLOCK: return Error_EWOULDBLOCK; #endif + default: + break; // fall through to error } return Error_ENONSTANDARD; @@ -528,6 +530,8 @@ inline static int32_t ConvertErrorPalToPlatform(int32_t error) case Error_ENONSTANDARD: break; // fall through to assert + default: + break; // fall through to assert } // We should not use this function to round-trip platform -> pal diff --git a/src/native/libs/System.Globalization.Native/pal_localeNumberData.c b/src/native/libs/System.Globalization.Native/pal_localeNumberData.c index 1cc0e55d188b17..837006eee9bf68 100644 --- a/src/native/libs/System.Globalization.Native/pal_localeNumberData.c +++ b/src/native/libs/System.Globalization.Native/pal_localeNumberData.c @@ -72,6 +72,8 @@ static char* NormalizeNumericPattern(const UChar* srcPattern, int isNegative) case UCHAR_CLOSEPAREN: minusAdded = true; break; + default: + break; } } @@ -145,6 +147,9 @@ static char* NormalizeNumericPattern(const UChar* srcPattern, int isNegative) case UCHAR_PERCENT: destPattern[index++] = '%'; break; + + default: + break; } } diff --git a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt index 0a05e96eb494ba..089363cf5554ec 100644 --- a/src/native/libs/System.IO.Compression.Native/CMakeLists.txt +++ b/src/native/libs/System.IO.Compression.Native/CMakeLists.txt @@ -66,7 +66,7 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) ${NATIVE_LIBS_EXTRA} ) - if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) + if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_USE_SYSTEM_BROTLI) set(DEF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/System.IO.Compression.Native_unixexports.src) set(EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/System.IO.Compression.Native.exports) generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) @@ -78,16 +78,14 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) set_property(TARGET System.IO.Compression.Native APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION}) set_property(TARGET System.IO.Compression.Native APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE}) - if (NOT CLR_CMAKE_USE_SYSTEM_BROTLI) - add_custom_command(TARGET System.IO.Compression.Native POST_BUILD - COMMENT "Verifying System.IO.Compression.Native entry points against entrypoints.c " - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh - $ - ${CMAKE_CURRENT_SOURCE_DIR}/entrypoints.c - ${CMAKE_NM} - VERBATIM - ) - endif () + add_custom_command(TARGET System.IO.Compression.Native POST_BUILD + COMMENT "Verifying System.IO.Compression.Native entry points against entrypoints.c " + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh + $ + ${CMAKE_CURRENT_SOURCE_DIR}/entrypoints.c + ${CMAKE_NM} + VERBATIM + ) endif () install_with_stripped_symbols (System.IO.Compression.Native PROGRAMS .) diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index 9c65db55c4ee03..cdd86ed46f0652 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -49,8 +49,10 @@ #elif HAVE_SYS_STATVFS_H && !HAVE_NON_LEGACY_STATFS // SunOS #include #include +#if HAVE_STATFS_VFS #include #endif +#endif #ifdef _AIX #include @@ -1050,6 +1052,8 @@ int32_t SystemNative_MAdvise(void* address, uint64_t length, int32_t advice) errno = ENOTSUP; return -1; #endif + default: + break; // fall through to error } assert_msg(false, "Unknown MemoryAdvice", (int)advice); @@ -1087,6 +1091,8 @@ int64_t SystemNative_SysConf(int32_t name) return sysconf(_SC_CLK_TCK); case PAL_SC_PAGESIZE: return sysconf(_SC_PAGESIZE); + default: + break; // fall through to error } assert_msg(false, "Unknown SysConf name", (int)name); diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_signverify.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_signverify.c index 6e7c77e9d7d070..37f61c7b1215ad 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_signverify.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_signverify.c @@ -16,7 +16,10 @@ static int32_t ExecuteSignTransform(SecTransformRef signer, CFDataRef* pSignatur assert(pErrorOut != NULL); int32_t ret = INT_MIN; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" CFTypeRef signerResponse = SecTransformExecute(signer, pErrorOut); +#pragma clang diagnostic pop CFDataRef signature = NULL; if (signerResponse == NULL || *pErrorOut != NULL) @@ -62,7 +65,10 @@ static int32_t ExecuteVerifyTransform(SecTransformRef verifier, CFErrorRef* pErr assert(pErrorOut != NULL); int32_t ret = kErrorSeeError; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" CFTypeRef verifierResponse = SecTransformExecute(verifier, pErrorOut); +#pragma clang diagnostic pop if (verifierResponse != NULL) { @@ -79,6 +85,8 @@ static int32_t ExecuteVerifyTransform(SecTransformRef verifier, CFErrorRef* pErr static int32_t ConfigureSignVerifyTransform(SecTransformRef xform, CFDataRef cfDataHash, CFErrorRef* pErrorOut) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" if (!SecTransformSetAttribute(xform, kSecInputIsAttributeName, kSecInputIsDigest, pErrorOut)) { return 0; @@ -88,6 +96,7 @@ static int32_t ConfigureSignVerifyTransform(SecTransformRef xform, CFDataRef cfD { return 0; } +#pragma clang diagnostic pop return 1; } diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c index d37f08ed14e2ec..9b44cbbef8e093 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c @@ -463,7 +463,11 @@ int32_t AppleCryptoNative_SslIsHostnameMatch(SSLContextRef sslContext, CFStringR for (CFIndex i = 0; i < certificateCount; i++) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" SecCertificateRef item = SecTrustGetCertificateAtIndex(existingTrust, i); +#pragma clang diagnostic pop + CFArrayAppendValue(certs, item); // Copy the EE cert into the anchors set, this will make the chain part diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c index 94e22f28c8794a..39b8e4619912b3 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509.c @@ -43,16 +43,7 @@ AppleCryptoNative_X509GetPublicKey(SecCertificateRef cert, SecKeyRef* pPublicKey if (cert == NULL || pPublicKeyOut == NULL) return kErrorUnknownState; - if (__builtin_available(macOS 10.14, iOS 12, tvOS 12, *)) - { - *pPublicKeyOut = SecCertificateCopyKey(cert); - } -#if defined(TARGET_IOS) || defined(TARGET_TVOS) - else - { - *pPublicKeyOut = SecCertificateCopyPublicKey(cert); - } -#endif + *pPublicKeyOut = SecCertificateCopyKey(cert); return 1; } diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c index 152ed890ed6eda..de1a84f26798d4 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_x509chain.c @@ -92,7 +92,10 @@ SecCertificateRef AppleCryptoNative_X509ChainGetCertificateAtIndex(SecTrustRef c if (chain == NULL || index < 0) return NULL; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return SecTrustGetCertificateAtIndex(chain, index); +#pragma clang diagnostic pop } CFArrayRef AppleCryptoNative_X509ChainGetTrustResults(SecTrustRef chain) diff --git a/src/native/libs/System.Security.Cryptography.Native/configure.cmake b/src/native/libs/System.Security.Cryptography.Native/configure.cmake index 74ed49f5d19168..ea779318c667ca 100644 --- a/src/native/libs/System.Security.Cryptography.Native/configure.cmake +++ b/src/native/libs/System.Security.Cryptography.Native/configure.cmake @@ -22,6 +22,11 @@ check_function_exists( HAVE_OPENSSL_SHA3 ) +check_function_exists( + EVP_DigestSqueeze + HAVE_OPENSSL_SHA3_SQUEEZE +) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/pal_crypto_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pal_crypto_config.h) diff --git a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c index 0268221b428b93..cb4b621e27fa37 100644 --- a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c @@ -142,6 +142,7 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_EvpDigestFinalXOF) DllImportEntry(CryptoNative_EvpDigestOneShot) DllImportEntry(CryptoNative_EvpDigestReset) + DllImportEntry(CryptoNative_EvpDigestSqueeze) DllImportEntry(CryptoNative_EvpDigestUpdate) DllImportEntry(CryptoNative_EvpDigestXOFOneShot) DllImportEntry(CryptoNative_EvpMacFetch) @@ -155,6 +156,7 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_EvpMacOneShot) DllImportEntry(CryptoNative_EvpMacReset) DllImportEntry(CryptoNative_EvpMd5) + DllImportEntry(CryptoNative_EvpMdCtxCopyEx) DllImportEntry(CryptoNative_EvpMdCtxCreate) DllImportEntry(CryptoNative_EvpMdCtxDestroy) DllImportEntry(CryptoNative_EvpMdSize) @@ -310,6 +312,7 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_IsSslStateOK) DllImportEntry(CryptoNative_SslCtxAddExtraChainCert) DllImportEntry(CryptoNative_SslCtxSetCaching) + DllImportEntry(CryptoNative_SslCtxRemoveSession) DllImportEntry(CryptoNative_SslCtxSetCiphers) DllImportEntry(CryptoNative_SslCtxSetDefaultOcspCallback) DllImportEntry(CryptoNative_SslCtxSetEncryptionPolicy) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index b48d39de83cdd5..7837810de715e2 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -178,6 +178,13 @@ const EVP_MD *EVP_shake256(void); int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); #endif +#if !HAVE_OPENSSL_SHA3_SQUEEZE +#undef HAVE_OPENSSL_SHA3_SQUEEZE +#define HAVE_OPENSSL_SHA3_SQUEEZE 1 +int EVP_DigestSqueeze(EVP_MD_CTX *ctx, unsigned char *out, size_t outlen); +#endif + + #define API_EXISTS(fn) (fn != NULL) // List of all functions from the libssl that are used in the System.Security.Cryptography.Native. @@ -369,6 +376,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); REQUIRED_FUNCTION(EVP_DigestFinal_ex) \ LIGHTUP_FUNCTION(EVP_DigestFinalXOF) \ REQUIRED_FUNCTION(EVP_DigestInit_ex) \ + LIGHTUP_FUNCTION(EVP_DigestSqueeze) \ REQUIRED_FUNCTION(EVP_DigestUpdate) \ REQUIRED_FUNCTION(EVP_get_digestbyname) \ LIGHTUP_FUNCTION(EVP_MAC_fetch) \ @@ -547,6 +555,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); REQUIRED_FUNCTION(SSL_CTX_new) \ REQUIRED_FUNCTION(SSL_CTX_sess_set_new_cb) \ REQUIRED_FUNCTION(SSL_CTX_sess_set_remove_cb) \ + REQUIRED_FUNCTION(SSL_CTX_remove_session) \ LIGHTUP_FUNCTION(SSL_CTX_set_alpn_protos) \ LIGHTUP_FUNCTION(SSL_CTX_set_alpn_select_cb) \ REQUIRED_FUNCTION(SSL_CTX_set_cipher_list) \ @@ -895,6 +904,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define EVP_DigestFinal_ex EVP_DigestFinal_ex_ptr #define EVP_DigestFinalXOF EVP_DigestFinalXOF_ptr #define EVP_DigestInit_ex EVP_DigestInit_ex_ptr +#define EVP_DigestSqueeze EVP_DigestSqueeze_ptr #define EVP_DigestUpdate EVP_DigestUpdate_ptr #define EVP_get_digestbyname EVP_get_digestbyname_ptr #define EVP_md5 EVP_md5_ptr @@ -1074,6 +1084,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define SSL_CTX_new SSL_CTX_new_ptr #define SSL_CTX_sess_set_new_cb SSL_CTX_sess_set_new_cb_ptr #define SSL_CTX_sess_set_remove_cb SSL_CTX_sess_set_remove_cb_ptr +#define SSL_CTX_remove_session SSL_CTX_remove_session_ptr #define SSL_CTX_set_alpn_protos SSL_CTX_set_alpn_protos_ptr #define SSL_CTX_set_alpn_select_cb SSL_CTX_set_alpn_select_cb_ptr #define SSL_CTX_set_cipher_list SSL_CTX_set_cipher_list_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in b/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in index d7aef5a7d1b674..c216e88e272e4a 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in +++ b/src/native/libs/System.Security.Cryptography.Native/pal_crypto_config.h.in @@ -4,3 +4,4 @@ #cmakedefine01 HAVE_OPENSSL_ALPN #cmakedefine01 HAVE_OPENSSL_CHACHA20POLY1305 #cmakedefine01 HAVE_OPENSSL_SHA3 +#cmakedefine01 HAVE_OPENSSL_SHA3_SQUEEZE diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c index 7559b4c1970b24..1fcb0fc0058cea 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp.c @@ -143,7 +143,7 @@ int32_t CryptoNative_EvpDigestFinalXOF(EVP_MD_CTX* ctx, uint8_t* md, uint32_t le return 0; } -static EVP_MD_CTX* EvpDup(const EVP_MD_CTX* ctx) +EVP_MD_CTX* CryptoNative_EvpMdCtxCopyEx(const EVP_MD_CTX* ctx) { if (ctx == NULL) { @@ -174,7 +174,7 @@ int32_t CryptoNative_EvpDigestCurrent(const EVP_MD_CTX* ctx, uint8_t* md, uint32 { ERR_clear_error(); - EVP_MD_CTX* dup = EvpDup(ctx); + EVP_MD_CTX* dup = CryptoNative_EvpMdCtxCopyEx(ctx); if (dup != NULL) { @@ -190,7 +190,7 @@ int32_t CryptoNative_EvpDigestCurrentXOF(const EVP_MD_CTX* ctx, uint8_t* md, uin { ERR_clear_error(); - EVP_MD_CTX* dup = EvpDup(ctx); + EVP_MD_CTX* dup = CryptoNative_EvpMdCtxCopyEx(ctx); if (dup != NULL) { @@ -262,6 +262,29 @@ int32_t CryptoNative_EvpDigestXOFOneShot(const EVP_MD* type, const void* source, return ret; } +int32_t CryptoNative_EvpDigestSqueeze(EVP_MD_CTX* ctx, uint8_t* md, uint32_t len, int32_t* haveFeature) +{ + ERR_clear_error(); + + if (ctx == NULL || haveFeature == NULL || (md == NULL && len > 0)) + { + return 0; + } + + *haveFeature = 0; + int32_t ret = 0; + +#if HAVE_OPENSSL_SHA3_SQUEEZE + if (API_EXISTS(EVP_DigestSqueeze)) + { + *haveFeature = 1; + ret = EVP_DigestSqueeze(ctx, md, (size_t)len); + } +#endif + + return ret; +} + int32_t CryptoNative_EvpMdSize(const EVP_MD* md) { // No error queue impact. diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_evp.h b/src/native/libs/System.Security.Cryptography.Native/pal_evp.h index f31521ff0e6dee..5d8460c7b7d087 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_evp.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_evp.h @@ -89,6 +89,14 @@ Combines EVP_MD_CTX_create, EVP_DigestUpdate, and EVP_DigestFinalXOF in to a sin */ PALEXPORT int32_t CryptoNative_EvpDigestXOFOneShot(const EVP_MD* type, const void* source, int32_t sourceSize, uint8_t* md, uint32_t len); +/* +Function: +EvpMdCtxCopyEx + +Creates a new EVP_MD_CTX and copies the ctx input using EVP_MD_CTX_copy_ex. Returns NULL on error. +*/ +PALEXPORT EVP_MD_CTX* CryptoNative_EvpMdCtxCopyEx(const EVP_MD_CTX* ctx); + /* Function: EvpMdSize @@ -97,6 +105,15 @@ Direct shim to EVP_MD_size. */ PALEXPORT int32_t CryptoNative_EvpMdSize(const EVP_MD* md); +/* +Function: +EvpDigestSqueeze + +Calls EVP_DigestSqueeze. If the function is not available, haveFeature is set to zero and the return value should +be ignored. If the function is available, haveFeature is set to one and the operation result is returned. +*/ +PALEXPORT int32_t CryptoNative_EvpDigestSqueeze(EVP_MD_CTX* ctx, uint8_t* md, uint32_t len, int32_t* haveFeature); + /* Function: EvpMd5 diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index e6bd41143c1655..e320d1c73d776b 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -701,6 +701,11 @@ int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, int con return retValue; } +int CryptoNative_SslCtxRemoveSession(SSL_CTX* ctx, SSL_SESSION* session) +{ + return SSL_CTX_remove_session(ctx, session); +} + const char* CryptoNative_SslGetServerName(SSL* ssl) { return SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h index 3c63564cc4e59f..9c9d7026119c5c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h @@ -167,6 +167,11 @@ Sets session caching. 0 is disabled. */ PALEXPORT int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, int contextIdLength, uint8_t* contextId, SslCtxNewSessionCallback newSessionCb, SslCtxRemoveSessionCallback removeSessionCb); +/* +Removes a session from internal cache. +*/ +PALEXPORT int CryptoNative_SslCtxRemoveSession(SSL_CTX* ctx, SSL_SESSION* session); + /* Sets callback to log TLS session keys */ diff --git a/src/native/libs/build-native.sh b/src/native/libs/build-native.sh index 3e90b3805aaec9..d3fefa7685a974 100755 --- a/src/native/libs/build-native.sh +++ b/src/native/libs/build-native.sh @@ -105,7 +105,7 @@ elif [[ "$__TargetOS" == linux-bionic && -z "$ROOTFS_DIR" ]]; then elif [[ "$__TargetOS" == iossimulator ]]; then # set default iOS simulator deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 $__CMakeArgs" + __CMakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $__CMakeArgs" if [[ "$__TargetArch" == x64 ]]; then __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" elif [[ "$__TargetArch" == x86 ]]; then @@ -119,7 +119,7 @@ elif [[ "$__TargetOS" == iossimulator ]]; then elif [[ "$__TargetOS" == ios ]]; then # set default iOS device deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 $__CMakeArgs" + __CMakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $__CMakeArgs" if [[ "$__TargetArch" == arm64 ]]; then __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" elif [[ "$__TargetArch" == arm ]]; then @@ -131,7 +131,7 @@ elif [[ "$__TargetOS" == ios ]]; then elif [[ "$__TargetOS" == tvossimulator ]]; then # set default tvOS simulator deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 $__CMakeArgs" + __CMakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $__CMakeArgs" if [[ "$__TargetArch" == x64 ]]; then __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" elif [[ "$__TargetArch" == arm64 ]]; then @@ -143,7 +143,7 @@ elif [[ "$__TargetOS" == tvossimulator ]]; then elif [[ "$__TargetOS" == tvos ]]; then # set default tvOS device deployment target # keep in sync with the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 $__CMakeArgs" + __CMakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 $__CMakeArgs" if [[ "$__TargetArch" == arm64 ]]; then __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" else diff --git a/src/native/managed/cdacreader/src/Constants.cs b/src/native/managed/cdacreader/src/Constants.cs new file mode 100644 index 00000000000000..0fbcaa0a246c73 --- /dev/null +++ b/src/native/managed/cdacreader/src/Constants.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Diagnostics.DataContractReader; + +internal static class Constants +{ + internal static class Globals + { + // See src/coreclr/debug/runtimeinfo/datadescriptor.h + internal const string SOSBreakingChangeVersion = nameof(SOSBreakingChangeVersion); + } +} diff --git a/src/native/managed/cdacreader/src/ContractDescriptorParser.cs b/src/native/managed/cdacreader/src/ContractDescriptorParser.cs new file mode 100644 index 00000000000000..a82235731e4a07 --- /dev/null +++ b/src/native/managed/cdacreader/src/ContractDescriptorParser.cs @@ -0,0 +1,342 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Contracts; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.Diagnostics.DataContractReader; + +/// +/// A parser for the JSON representation of a contract descriptor. +/// +/// +/// See design doc for the format. +/// +public partial class ContractDescriptorParser +{ + // data_descriptor.md uses a distinguished property name to indicate the size of a type + public const string TypeDescriptorSizeSigil = "!"; + + /// + /// Parses the "compact" representation of a contract descriptor. + /// + // Workaround for https://github.com/dotnet/runtime/issues/101205 + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Root))] + public static ContractDescriptor? ParseCompact(ReadOnlySpan json) + { + return JsonSerializer.Deserialize(json, ContractDescriptorContext.Default.ContractDescriptor); + } + + [JsonSerializable(typeof(ContractDescriptor))] + [JsonSerializable(typeof(int?))] + [JsonSerializable(typeof(string))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(TypeDescriptor))] + [JsonSerializable(typeof(FieldDescriptor))] + [JsonSerializable(typeof(GlobalDescriptor))] + [JsonSerializable(typeof(Dictionary))] + [JsonSourceGenerationOptions(AllowTrailingCommas = true, + DictionaryKeyPolicy = JsonKnownNamingPolicy.Unspecified, // contracts, types and globals are case sensitive + PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, + NumberHandling = JsonNumberHandling.AllowReadingFromString, + ReadCommentHandling = JsonCommentHandling.Skip, + UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip, + UnknownTypeHandling = JsonUnknownTypeHandling.JsonElement, + Converters = [typeof(TypeDescriptorConverter), + typeof(FieldDescriptorConverter), + typeof(GlobalDescriptorConverter)])] + internal sealed partial class ContractDescriptorContext : JsonSerializerContext + { + } + + public class ContractDescriptor + { + public int? Version { get; set; } + public string? Baseline { get; set; } + public Dictionary? Contracts { get; set; } + + public Dictionary? Types { get; set; } + + public Dictionary? Globals { get; set; } + + [JsonExtensionData] + public Dictionary? Extras { get; set; } + + public override string ToString() + { + return $"Version: {Version}, Baseline: {Baseline}, Contracts: {Contracts?.Count}, Types: {Types?.Count}, Globals: {Globals?.Count}"; + } + + } + + [JsonConverter(typeof(TypeDescriptorConverter))] + public class TypeDescriptor + { + public uint? Size { get; set; } + public Dictionary? Fields { get; set; } + } + + [JsonConverter(typeof(FieldDescriptorConverter))] + public class FieldDescriptor + { + public string? Type { get; set; } + public int Offset { get; set; } + } + + [JsonConverter(typeof(GlobalDescriptorConverter))] + public class GlobalDescriptor + { + public string? Type { get; set; } + public ulong Value { get; set; } + public bool Indirect { get; set; } + } + + internal sealed class TypeDescriptorConverter : JsonConverter + { + // Almost a normal dictionary converter except: + // 1. looks for a special key "!" to set the Size property + // 2. field names are property names, but treated case-sensitively + public override TypeDescriptor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException(); + uint? size = null; + Dictionary? fields = new(); + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonTokenType.EndObject: + return new TypeDescriptor { Size = size, Fields = fields }; + case JsonTokenType.PropertyName: + string? fieldNameOrSizeSigil = reader.GetString(); + reader.Read(); // read the next value: either a number or a field descriptor + if (fieldNameOrSizeSigil == TypeDescriptorSizeSigil) + { + uint newSize = reader.GetUInt32(); + if (size is not null) + { + throw new JsonException($"Size specified multiple times: {size} and {newSize}"); + } + size = newSize; + } + else + { + string? fieldName = fieldNameOrSizeSigil; + var field = JsonSerializer.Deserialize(ref reader, ContractDescriptorContext.Default.FieldDescriptor); + if (fieldName is null || field is null) + throw new JsonException(); + if (!fields.TryAdd(fieldName, field)) + { + throw new JsonException($"Duplicate field name: {fieldName}"); + } + } + break; + case JsonTokenType.Comment: + // unexpected - we specified to skip comments. but let's ignore anyway + break; + default: + throw new JsonException(); + } + } + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, TypeDescriptor value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + } + + internal sealed class FieldDescriptorConverter : JsonConverter + { + // Compact Field descriptors are either a number or a two element array + // 1. number - no type, offset is given as the number + // 2. [number, string] - offset is given as the number, type name is given as the string + public override FieldDescriptor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (TryGetInt32FromToken(ref reader, out int offset)) + return new FieldDescriptor { Offset = offset }; + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + reader.Read(); + // [number, string] + // ^ we're here + if (!TryGetInt32FromToken(ref reader, out offset)) + throw new JsonException(); + reader.Read(); // string + if (reader.TokenType != JsonTokenType.String) + throw new JsonException(); + string? type = reader.GetString(); + reader.Read(); // end of array + if (reader.TokenType != JsonTokenType.EndArray) + throw new JsonException(); + return new FieldDescriptor { Type = type, Offset = offset }; + } + + public override void Write(Utf8JsonWriter writer, FieldDescriptor value, JsonSerializerOptions options) + { + throw new JsonException(); + } + } + + internal sealed class GlobalDescriptorConverter : JsonConverter + { + public override GlobalDescriptor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + // four cases: + // 1. number - no type, direct value, given value + // 2. [number] - no type, indirect value, given aux data ptr + // 3. [number, string] - type, direct value, given value + // 4. [[number], string] - type, indirect value, given aux data ptr + + // Case 1: number + if (TryGetUInt64FromToken(ref reader, out ulong valueCase1)) + return new GlobalDescriptor { Value = valueCase1 }; + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + reader.Read(); + // we're in case 2 or 3 or 4: + // case 2: [number] + // ^ we're here + // case 3: [number, string] + // ^ we're here + // case 4: [[number], string] + // ^ we're here + if (TryGetUInt64FromToken(ref reader, out ulong valueCase2or3)) + { + // case 2 or 3 + // case 2: [number] + // ^ we're here + // case 3: [number, string] + // ^ we're here + reader.Read(); // end of array (case 2) or string (case 3) + if (reader.TokenType == JsonTokenType.EndArray) // it was case 2 + { + return new GlobalDescriptor { Value = valueCase2or3, Indirect = true }; + } + if (reader.TokenType == JsonTokenType.String) // it was case 3 + { + string? type = reader.GetString(); + reader.Read(); // end of array for case 3 + if (reader.TokenType != JsonTokenType.EndArray) + throw new JsonException(); + return new GlobalDescriptor { Type = type, Value = valueCase2or3 }; + } + throw new JsonException(); + } + if (reader.TokenType == JsonTokenType.StartArray) + { + // case 4: [[number], string] + // ^ we're here + reader.Read(); // number + if (!TryGetUInt64FromToken(ref reader, out ulong value)) + throw new JsonException(); + reader.Read(); // end of inner array + if (reader.TokenType != JsonTokenType.EndArray) + throw new JsonException(); + reader.Read(); // string + if (reader.TokenType != JsonTokenType.String) + throw new JsonException(); + string? type = reader.GetString(); + reader.Read(); // end of outer array + if (reader.TokenType != JsonTokenType.EndArray) + throw new JsonException(); + return new GlobalDescriptor { Type = type, Value = value, Indirect = true }; + } + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, GlobalDescriptor value, JsonSerializerOptions options) + { + throw new JsonException(); + } + } + + // Somewhat flexible parsing of numbers, allowing json number tokens or strings as decimal or hex, possibly negatated. + private static bool TryGetUInt64FromToken(ref Utf8JsonReader reader, out ulong value) + { + if (reader.TokenType == JsonTokenType.Number) + { + if (reader.TryGetUInt64(out value)) + return true; + if (reader.TryGetInt64(out long signedValue)) + { + value = (ulong)signedValue; + return true; + } + } + if (reader.TokenType == JsonTokenType.String) + { + var s = reader.GetString(); + if (s == null) + { + value = 0u; + return false; + } + if (ulong.TryParse(s, out value)) + return true; + if (long.TryParse(s, out long signedValue)) + { + value = (ulong)signedValue; + return true; + } + if (s.StartsWith("0x", StringComparison.OrdinalIgnoreCase) && + ulong.TryParse(s.AsSpan(2), System.Globalization.NumberStyles.HexNumber, null, out value)) + { + return true; + } + if (s.StartsWith("-0x", StringComparison.OrdinalIgnoreCase) && + ulong.TryParse(s.AsSpan(3), System.Globalization.NumberStyles.HexNumber, null, out ulong negValue)) + { + value = ~negValue + 1; // two's complement + return true; + } + } + value = 0; + return false; + } + + // Somewhat flexible parsing of numbers, allowing json number tokens or strings as either decimal or hex, possibly negated + private static bool TryGetInt32FromToken(ref Utf8JsonReader reader, out int value) + { + if (reader.TokenType == JsonTokenType.Number) + { + value = reader.GetInt32(); + return true; + } + if (reader.TokenType == JsonTokenType.String) + { + var s = reader.GetString(); + if (s == null) + { + value = 0; + return false; + } + if (int.TryParse(s, out value)) + { + return true; + } + if (s.StartsWith("0x", StringComparison.OrdinalIgnoreCase) && + int.TryParse(s.AsSpan(2), System.Globalization.NumberStyles.HexNumber, null, out value)) + { + return true; + } + if (s.StartsWith("-0x", StringComparison.OrdinalIgnoreCase) && + int.TryParse(s.AsSpan(3), System.Globalization.NumberStyles.HexNumber, null, out int negValue)) + { + value = -negValue; + return true; + } + } + value = 0; + return false; + } +} diff --git a/src/native/managed/cdacreader/src/Entrypoints.cs b/src/native/managed/cdacreader/src/Entrypoints.cs index 30cab9ec851887..908d534fe60c4e 100644 --- a/src/native/managed/cdacreader/src/Entrypoints.cs +++ b/src/native/managed/cdacreader/src/Entrypoints.cs @@ -14,7 +14,10 @@ internal static class Entrypoints [UnmanagedCallersOnly(EntryPoint = $"{CDAC}init")] private static unsafe int Init(ulong descriptor, delegate* unmanaged readFromTarget, void* readContext, IntPtr* handle) { - Target target = new(descriptor, readFromTarget, readContext); + // TODO: [cdac] Better error code/details + if (!Target.TryCreate(descriptor, readFromTarget, readContext, out Target? target)) + return -1; + GCHandle gcHandle = GCHandle.Alloc(target); *handle = GCHandle.ToIntPtr(gcHandle); return 0; diff --git a/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs b/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs index b0640c44efc98d..261aa034c3f894 100644 --- a/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs @@ -35,8 +35,7 @@ public SOSDacImpl(Target target) public int GetBreakingChangeVersion() { - // TODO: Return non-hard-coded version - return 4; + return _target.ReadGlobal(Constants.Globals.SOSBreakingChangeVersion); } public unsafe int GetCCWData(ulong ccw, void* data) => HResults.E_NOTIMPL; diff --git a/src/native/managed/cdacreader/src/Root.cs b/src/native/managed/cdacreader/src/Root.cs new file mode 100644 index 00000000000000..05aefea3dea2a5 --- /dev/null +++ b/src/native/managed/cdacreader/src/Root.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text.Json.Serialization; + +namespace Microsoft.Diagnostics.DataContractReader; + +internal static class Root +{ + // https://github.com/dotnet/runtime/issues/101205 + public static JsonDerivedTypeAttribute[] R1 = new JsonDerivedTypeAttribute[] { null! }; +} diff --git a/src/native/managed/cdacreader/src/Target.cs b/src/native/managed/cdacreader/src/Target.cs index 898cab774bfb56..c2e09d9d0fa116 100644 --- a/src/native/managed/cdacreader/src/Target.cs +++ b/src/native/managed/cdacreader/src/Target.cs @@ -3,6 +3,9 @@ using System; using System.Buffers.Binary; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.CompilerServices; namespace Microsoft.Diagnostics.DataContractReader; @@ -14,51 +17,292 @@ public struct TargetPointer public TargetPointer(ulong value) => Value = value; } -internal sealed unsafe class Target +public sealed unsafe class Target { - private readonly delegate* unmanaged _readFromTarget; - private readonly void* _readContext; + private const int StackAllocByteThreshold = 1024; - private bool _isLittleEndian; - private int _pointerSize; + private readonly struct Configuration + { + public bool IsLittleEndian { get; init; } + public int PointerSize { get; init; } + } + + private readonly Configuration _config; + private readonly Reader _reader; + + private readonly IReadOnlyDictionary _contracts = new Dictionary(); + private readonly IReadOnlyDictionary _globals = new Dictionary(); - public Target(ulong _, delegate* unmanaged readFromTarget, void* readContext) + public static bool TryCreate(ulong contractDescriptor, delegate* unmanaged readFromTarget, void* readContext, out Target? target) { - _readFromTarget = readFromTarget; - _readContext = readContext; + Reader reader = new Reader(readFromTarget, readContext); + if (TryReadContractDescriptor(contractDescriptor, reader, out Configuration config, out ContractDescriptorParser.ContractDescriptor? descriptor, out TargetPointer[] pointerData)) + { + target = new Target(config, descriptor!, pointerData, reader); + return true; + } + + target = null; + return false; + } + + private Target(Configuration config, ContractDescriptorParser.ContractDescriptor descriptor, TargetPointer[] pointerData, Reader reader) + { + _config = config; + _reader = reader; + + // TODO: [cdac] Read types + // note: we will probably want to store the globals and types into a more usable form + _contracts = descriptor.Contracts ?? []; + + // Read globals and map indirect values to pointer data + if (descriptor.Globals is not null) + { + Dictionary globals = []; + foreach ((string name, ContractDescriptorParser.GlobalDescriptor global) in descriptor.Globals) + { + ulong value = global.Value; + if (global.Indirect) + { + if (value >= (ulong)pointerData.Length) + throw new InvalidOperationException($"Invalid pointer data index {value}."); - // TODO: [cdac] Populate from descriptor - _isLittleEndian = BitConverter.IsLittleEndian; - _pointerSize = IntPtr.Size; + value = pointerData[value].Value; + } + + globals[name] = (value, global.Type); + } + + _globals = globals; + } + } + + // See docs/design/datacontracts/contract-descriptor.md + private static bool TryReadContractDescriptor( + ulong address, + Reader reader, + out Configuration config, + out ContractDescriptorParser.ContractDescriptor? descriptor, + out TargetPointer[] pointerData) + { + config = default; + descriptor = null; + pointerData = []; + + // Magic - uint64_t + Span buffer = stackalloc byte[sizeof(ulong)]; + if (reader.ReadFromTarget(address, buffer) < 0) + return false; + + address += sizeof(ulong); + ReadOnlySpan magicLE = "DNCCDAC\0"u8; + ReadOnlySpan magicBE = "\0CADCCND"u8; + bool isLittleEndian = buffer.SequenceEqual(magicLE); + if (!isLittleEndian && !buffer.SequenceEqual(magicBE)) + return false; + + // Flags - uint32_t + if (!TryRead(address, isLittleEndian, reader, out uint flags)) + return false; + + address += sizeof(uint); + + // Bit 1 represents the pointer size. 0 = 64-bit, 1 = 32-bit. + int pointerSize = (int)(flags & 0x2) == 0 ? sizeof(ulong) : sizeof(uint); + + config = new Configuration { IsLittleEndian = isLittleEndian, PointerSize = pointerSize }; + + // Descriptor size - uint32_t + if (!TryRead(address, config.IsLittleEndian, reader, out uint descriptorSize)) + return false; + + address += sizeof(uint); + + // Descriptor - char* + if (!TryReadPointer(address, config, reader, out TargetPointer descriptorAddr)) + return false; + + address += (uint)pointerSize; + + // Pointer data count - uint32_t + if (!TryRead(address, config.IsLittleEndian, reader, out uint pointerDataCount)) + return false; + + address += sizeof(uint); + + // Padding - uint32_t + address += sizeof(uint); + + // Pointer data - uintptr_t* + if (!TryReadPointer(address, config, reader, out TargetPointer pointerDataAddr)) + return false; + + // Read descriptor + Span descriptorBuffer = descriptorSize <= StackAllocByteThreshold + ? stackalloc byte[(int)descriptorSize] + : new byte[(int)descriptorSize]; + if (reader.ReadFromTarget(descriptorAddr.Value, descriptorBuffer) < 0) + return false; + + descriptor = ContractDescriptorParser.ParseCompact(descriptorBuffer); + if (descriptor is null) + return false; + + // Read pointer data + pointerData = new TargetPointer[pointerDataCount]; + for (int i = 0; i < pointerDataCount; i++) + { + if (!TryReadPointer(pointerDataAddr.Value + (uint)(i * pointerSize), config, reader, out pointerData[i])) + return false; + } + + return true; + } + + public T Read(ulong address, out T value) where T : unmanaged, IBinaryInteger, IMinMaxValue + { + if (!TryRead(address, out value)) + throw new InvalidOperationException($"Failed to read {typeof(T)} at 0x{address:x8}."); + + return value; + } + + public bool TryRead(ulong address, out T value) where T : unmanaged, IBinaryInteger, IMinMaxValue + => TryRead(address, _config.IsLittleEndian, _reader, out value); + + private static bool TryRead(ulong address, bool isLittleEndian, Reader reader, out T value) where T : unmanaged, IBinaryInteger, IMinMaxValue + { + value = default; + Span buffer = stackalloc byte[sizeof(T)]; + if (reader.ReadFromTarget(address, buffer) < 0) + return false; + + return isLittleEndian + ? T.TryReadLittleEndian(buffer, !IsSigned(), out value) + : T.TryReadBigEndian(buffer, !IsSigned(), out value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsSigned() where T : struct, INumberBase, IMinMaxValue + { + return T.IsNegative(T.MinValue); + } + + public TargetPointer ReadPointer(ulong address) + { + if (!TryReadPointer(address, out TargetPointer pointer)) + throw new InvalidOperationException($"Failed to read pointer at 0x{address:x8}."); + + return pointer; } public bool TryReadPointer(ulong address, out TargetPointer pointer) + => TryReadPointer(address, _config, _reader, out pointer); + + private static bool TryReadPointer(ulong address, Configuration config, Reader reader, out TargetPointer pointer) { pointer = TargetPointer.Null; - byte* buffer = stackalloc byte[_pointerSize]; - ReadOnlySpan span = new ReadOnlySpan(buffer, _pointerSize); - if (ReadFromTarget(address, buffer, (uint)_pointerSize) < 0) + Span buffer = stackalloc byte[config.PointerSize]; + if (reader.ReadFromTarget(address, buffer) < 0) return false; - if (_pointerSize == sizeof(uint)) + if (config.PointerSize == sizeof(uint) + && TryRead(address, config.IsLittleEndian, reader, out uint value32)) { - pointer = new TargetPointer( - _isLittleEndian - ? BinaryPrimitives.ReadUInt32LittleEndian(span) - : BinaryPrimitives.ReadUInt32BigEndian(span)); + pointer = new TargetPointer(value32); + return true; } - else if (_pointerSize == sizeof(ulong)) + else if (config.PointerSize == sizeof(ulong) + && TryRead(address, config.IsLittleEndian, reader, out ulong value64)) + { + pointer = new TargetPointer(value64); + return true; + } + + return false; + } + + public T ReadGlobal(string name) where T : struct, INumber + { + if (!TryReadGlobal(name, out T value)) + throw new InvalidOperationException($"Failed to read global {typeof(T)} '{name}'."); + + return value; + } + + public bool TryReadGlobal(string name, out T value) where T : struct, INumber, INumberBase + { + value = default; + if (!_globals.TryGetValue(name, out (ulong Value, string? Type) global)) + return false; + + // TODO: [cdac] Move type validation out of the read such that it does not have to happen for every read + if (global.Type is not null) { - pointer = new TargetPointer( - _isLittleEndian - ? BinaryPrimitives.ReadUInt64LittleEndian(span) - : BinaryPrimitives.ReadUInt64BigEndian(span)); + string? expectedType = Type.GetTypeCode(typeof(T)) switch + { + TypeCode.SByte => "int8", + TypeCode.Byte => "uint8", + TypeCode.Int16 => "int16", + TypeCode.UInt16 => "uint16", + TypeCode.Int32 => "int32", + TypeCode.UInt32 => "uint32", + TypeCode.Int64 => "int64", + TypeCode.UInt64 => "uint64", + _ => null, + }; + if (expectedType is null || global.Type != expectedType) + { + return false; + } } + value = T.CreateChecked(global.Value); return true; } - private int ReadFromTarget(ulong address, byte* buffer, uint bytesToRead) - => _readFromTarget(address, buffer, bytesToRead, _readContext); + public TargetPointer ReadGlobalPointer(string name) + { + if (!TryReadGlobalPointer(name, out TargetPointer pointer)) + throw new InvalidOperationException($"Failed to read global pointer '{name}'."); + + return pointer; + } + + public bool TryReadGlobalPointer(string name, out TargetPointer pointer) + { + pointer = TargetPointer.Null; + if (!_globals.TryGetValue(name, out (ulong Value, string? Type) global)) + return false; + + if (global.Type is not null && Array.IndexOf(["pointer", "nint", "nuint"], global.Type) == -1) + return false; + + pointer = new TargetPointer(global.Value); + return true; + } + + private sealed class Reader + { + private readonly delegate* unmanaged _readFromTarget; + private readonly void* _context; + + public Reader(delegate* unmanaged readFromTarget, void* context) + { + _readFromTarget = readFromTarget; + _context = context; + } + + public int ReadFromTarget(ulong address, Span buffer) + { + fixed (byte* bufferPtr = buffer) + { + return _readFromTarget(address, bufferPtr, (uint)buffer.Length, _context); + } + } + + public int ReadFromTarget(ulong address, byte* buffer, uint bytesToRead) + => _readFromTarget(address, buffer, bytesToRead, _context); + } } diff --git a/src/native/managed/cdacreader/src/cdacreader.csproj b/src/native/managed/cdacreader/src/cdacreader.csproj index 253bb3c6c27e01..20ecd197c70460 100644 --- a/src/native/managed/cdacreader/src/cdacreader.csproj +++ b/src/native/managed/cdacreader/src/cdacreader.csproj @@ -9,6 +9,7 @@ false true + false diff --git a/src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs b/src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs new file mode 100644 index 00000000000000..6f93b1225670e4 --- /dev/null +++ b/src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs @@ -0,0 +1,215 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Text.Json; +using System.Text.Unicode; +using Xunit; + +namespace Microsoft.Diagnostics.DataContractReader.UnitTests; + +public class ContractDescriptorParserTests +{ + [Fact] + public void ParsesEmptyContract() + { + Assert.False(JsonSerializer.IsReflectionEnabledByDefault); + ReadOnlySpan json = "{}"u8; + ContractDescriptorParser.ContractDescriptor descriptor = ContractDescriptorParser.ParseCompact(json); + Assert.Null(descriptor.Version); + Assert.Null(descriptor.Baseline); + Assert.Null(descriptor.Contracts); + Assert.Null(descriptor.Types); + Assert.Null(descriptor.Extras); + } + [Fact] + public void ParsesTrivialContract() + { + ReadOnlySpan json = """ + { + "version": 0, + "baseline": "empty", + "contracts": {}, + "types": {}, + "globals": {} + } + """u8; + ContractDescriptorParser.ContractDescriptor descriptor = ContractDescriptorParser.ParseCompact(json); + Assert.Equal(0, descriptor.Version); + Assert.Equal("empty", descriptor.Baseline); + Assert.Empty(descriptor.Contracts); + Assert.Empty(descriptor.Types); + Assert.Empty(descriptor.Globals); + Assert.Null(descriptor.Extras); + } + + [Fact] + public void ParseSizedTypes() + { + ReadOnlySpan json = """ + { + "version": 0, + "baseline": "empty", + "contracts": {}, + "types": + { + "pointer": { "!" : 8}, + "int": { "!" : 4}, + "Point": { + "x": [ 4, "int"], + "y": 8, + "!": 12 + }, + "Point3D": { // no size + "r": [ 0, "double"], + "phi": 8, + "rho": 16 + } + }, + "globals": {} + } + """u8; + ContractDescriptorParser.ContractDescriptor descriptor = ContractDescriptorParser.ParseCompact(json); + Assert.Equal(0, descriptor.Version); + Assert.Equal("empty", descriptor.Baseline); + Assert.Empty(descriptor.Contracts); + Assert.Empty(descriptor.Globals); + Assert.Equal(4, descriptor.Types.Count); + Assert.Equal(8u, descriptor.Types["pointer"].Size); + Assert.Equal(4u, descriptor.Types["int"].Size); + Assert.Equal(2, descriptor.Types["Point"].Fields.Count); + Assert.Equal(4, descriptor.Types["Point"].Fields["x"].Offset); + Assert.Equal(8, descriptor.Types["Point"].Fields["y"].Offset); + Assert.Equal("int", descriptor.Types["Point"].Fields["x"].Type); + Assert.Null(descriptor.Types["Point"].Fields["y"].Type); + Assert.Equal(12u, descriptor.Types["Point"].Size); + Assert.Equal(3, descriptor.Types["Point3D"].Fields.Count); + Assert.Equal(0, descriptor.Types["Point3D"].Fields["r"].Offset); + Assert.Equal(8, descriptor.Types["Point3D"].Fields["phi"].Offset); + Assert.Equal(16, descriptor.Types["Point3D"].Fields["rho"].Offset); + Assert.Equal("double", descriptor.Types["Point3D"].Fields["r"].Type); + Assert.Null(descriptor.Types["Point3D"].Fields["phi"].Type); + Assert.Null(descriptor.Types["Point3D"].Size); + } + + [Fact] + public void ParseContractsCaseSensitive() + { + ReadOnlySpan json = """ + { + "version": 0, + "baseline": "empty", + "contracts": { + "foo": 1, + "Foo": 2 + }, + "types": {}, + "globals": {} + } + """u8; + ContractDescriptorParser.ContractDescriptor descriptor = ContractDescriptorParser.ParseCompact(json); + Assert.Equal(0, descriptor.Version); + Assert.Equal("empty", descriptor.Baseline); + Assert.Equal(2, descriptor.Contracts.Count); + Assert.Equal(1, descriptor.Contracts["foo"]); + Assert.Equal(2, descriptor.Contracts["Foo"]); + } + + [Fact] + public void ParsesGlobals() + { + ReadOnlySpan json = """ + { + "version": 0, + "baseline": "empty", + "contracts": {}, + "types": {}, + "globals": { + "globalInt": 1, + "globalPtr": [2], + "globalTypedInt": [3, "uint8"], + "globalTypedPtr": [[4], "uintptr"], + "globalHex": "0x1234", + "globalNegative": -2, + "globalStringyInt": "17", + "globalStringyNegative": "-2", + "globalNegativeHex": "-0xff", + "globalBigStringyInt": "0x123456789abcdef", + "globalStringyPtr": ["0x1234"], + "globalTypedStringyInt": ["0x1234", "int"], + "globalTypedStringyPtr": [["0x1234"], "int"] + } + } + """u8; + ContractDescriptorParser.ContractDescriptor descriptor = ContractDescriptorParser.ParseCompact(json); + Assert.Equal(0, descriptor.Version); + Assert.Equal("empty", descriptor.Baseline); + Assert.Empty(descriptor.Contracts); + Assert.Empty(descriptor.Types); + Assert.Equal(13, descriptor.Globals.Count); + Assert.Equal((ulong)1, descriptor.Globals["globalInt"].Value); + Assert.False(descriptor.Globals["globalInt"].Indirect); + Assert.Equal((ulong)2, descriptor.Globals["globalPtr"].Value); + Assert.True(descriptor.Globals["globalPtr"].Indirect); + Assert.Equal((ulong)3, descriptor.Globals["globalTypedInt"].Value); + Assert.False(descriptor.Globals["globalTypedInt"].Indirect); + Assert.Equal("uint8", descriptor.Globals["globalTypedInt"].Type); + Assert.Equal((ulong)4, descriptor.Globals["globalTypedPtr"].Value); + Assert.True(descriptor.Globals["globalTypedPtr"].Indirect); + Assert.Equal("uintptr", descriptor.Globals["globalTypedPtr"].Type); + Assert.Equal((ulong)0x1234, descriptor.Globals["globalHex"].Value); + Assert.False(descriptor.Globals["globalHex"].Indirect); + Assert.Equal((ulong)0xfffffffffffffffe, descriptor.Globals["globalNegative"].Value); + Assert.False(descriptor.Globals["globalNegative"].Indirect); + Assert.Equal((ulong)17, descriptor.Globals["globalStringyInt"].Value); + Assert.False(descriptor.Globals["globalStringyInt"].Indirect); + Assert.Equal((ulong)0xfffffffffffffffe, descriptor.Globals["globalStringyNegative"].Value); + Assert.False(descriptor.Globals["globalStringyNegative"].Indirect); + Assert.Equal((ulong)0xffffffffffffff01, descriptor.Globals["globalNegativeHex"].Value); + Assert.False(descriptor.Globals["globalNegativeHex"].Indirect); + Assert.Equal((ulong)0x123456789abcdef, descriptor.Globals["globalBigStringyInt"].Value); + Assert.False(descriptor.Globals["globalBigStringyInt"].Indirect); + Assert.Equal((ulong)0x1234, descriptor.Globals["globalStringyPtr"].Value); + Assert.True(descriptor.Globals["globalStringyPtr"].Indirect); + Assert.Equal("int", descriptor.Globals["globalTypedStringyInt"].Type); + Assert.Equal((ulong)0x1234, descriptor.Globals["globalTypedStringyInt"].Value); + Assert.False(descriptor.Globals["globalTypedStringyInt"].Indirect); + Assert.Equal("int", descriptor.Globals["globalTypedStringyPtr"].Type); + Assert.Equal((ulong)0x1234, descriptor.Globals["globalTypedStringyPtr"].Value); + Assert.True(descriptor.Globals["globalTypedStringyPtr"].Indirect); + } + + [Fact] + void ParsesExoticOffsets() + { + ReadOnlySpan json = """ + { + "version": 0, + "baseline": "empty", + "contracts": {}, + "types": { + "OddStruct": { + "a": -12, + "b": "0x12", + "c": "-0x12", + "d": ["0x100", "int"] + } + }, + "globals": { + } + } + """u8; + ContractDescriptorParser.ContractDescriptor descriptor = ContractDescriptorParser.ParseCompact(json); + Assert.Equal(0, descriptor.Version); + Assert.Equal("empty", descriptor.Baseline); + Assert.Empty(descriptor.Contracts); + Assert.Empty(descriptor.Globals); + Assert.Equal(1, descriptor.Types.Count); + Assert.Equal(4, descriptor.Types["OddStruct"].Fields.Count); + Assert.Equal(-12, descriptor.Types["OddStruct"].Fields["a"].Offset); + Assert.Equal(0x12, descriptor.Types["OddStruct"].Fields["b"].Offset); + Assert.Equal(-0x12, descriptor.Types["OddStruct"].Fields["c"].Offset); + Assert.Equal(0x100, descriptor.Types["OddStruct"].Fields["d"].Offset); + Assert.Equal("int", descriptor.Types["OddStruct"].Fields["d"].Type); + } +} diff --git a/src/native/managed/cdacreader/tests/Microsoft.Diagnostics.DataContractReader.Tests.csproj b/src/native/managed/cdacreader/tests/Microsoft.Diagnostics.DataContractReader.Tests.csproj new file mode 100644 index 00000000000000..c12c45e6f1fe84 --- /dev/null +++ b/src/native/managed/cdacreader/tests/Microsoft.Diagnostics.DataContractReader.Tests.csproj @@ -0,0 +1,16 @@ + + + true + $(NetCoreAppToolCurrent) + false + + + + + + + + + + diff --git a/src/native/managed/cdacreader/tests/TargetTests.cs b/src/native/managed/cdacreader/tests/TargetTests.cs new file mode 100644 index 00000000000000..5a8569c1b557cb --- /dev/null +++ b/src/native/managed/cdacreader/tests/TargetTests.cs @@ -0,0 +1,358 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Buffers.Binary; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using Xunit; + +namespace Microsoft.Diagnostics.DataContractReader.UnitTests; + +public unsafe class TargetTests +{ + private const ulong ContractDescriptorAddr = 0xaaaaaaaa; + private const uint JsonDescriptorAddr = 0xdddddddd; + private const uint PointerDataAddr = 0xeeeeeeee; + + private static readonly (string Name, ulong Value, string? Type)[] TestGlobals = + [ + ("value", (ulong)sbyte.MaxValue, null), + ("int8Value", 0x12, "int8"), + ("uint8Value", 0x12, "uint8"), + ("int16Value", 0x1234, "int16"), + ("uint16Value", 0x1234, "uint16"), + ("int32Value", 0x12345678, "int32"), + ("uint32Value", 0x12345678, "uint32"), + ("int64Value", 0x123456789abcdef0, "int64"), + ("uint64Value", 0x123456789abcdef0, "uint64"), + ("nintValue", 0xabcdef0, "nint"), + ("nuintValue", 0xabcdef0, "nuint"), + ("pointerValue", 0xabcdef0, "pointer"), + ]; + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void ReadGlobalValue(bool isLittleEndian, bool is64Bit) + { + string globalsJson = string.Join(',', TestGlobals.Select(i => $"\"{i.Name}\": {(i.Type is null ? i.Value.ToString() : $"[{i.Value}, \"{i.Type}\"]")}")); + byte[] json = Encoding.UTF8.GetBytes($$""" + { + "version": 0, + "baseline": "empty", + "contracts": {}, + "types": {}, + "globals": { {{globalsJson}} } + } + """); + Span descriptor = stackalloc byte[ContractDescriptor.Size(is64Bit)]; + ContractDescriptor.Fill(descriptor, isLittleEndian, is64Bit, json.Length, 0); + fixed (byte* jsonPtr = json) + { + ReadContext context = new ReadContext + { + ContractDescriptor = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(descriptor)), + ContractDescriptorLength = descriptor.Length, + JsonDescriptor = jsonPtr, + JsonDescriptorLength = json.Length, + }; + + bool success = Target.TryCreate(ContractDescriptorAddr, &ReadFromTarget, &context, out Target? target); + Assert.True(success); + + ValidateGlobals(target, TestGlobals); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void ReadIndirectGlobalValue(bool isLittleEndian, bool is64Bit) + { + int pointerSize = is64Bit ? sizeof(ulong) : sizeof(uint); + Span pointerData = stackalloc byte[TestGlobals.Length * pointerSize]; + for (int i = 0; i < TestGlobals.Length; i++) + { + var (_, value, _) = TestGlobals[i]; + WritePointer(pointerData.Slice(i * pointerSize), value, isLittleEndian, pointerSize); + } + + string globalsJson = string.Join(',', TestGlobals.Select((g, i) => $"\"{g.Name}\": {(g.Type is null ? $"[{i}]" : $"[[{i}], \"{g.Type}\"]")}")); + byte[] json = Encoding.UTF8.GetBytes($$""" + { + "version": 0, + "baseline": "empty", + "contracts": {}, + "types": {}, + "globals": { {{globalsJson}} } + } + """); + Span descriptor = stackalloc byte[ContractDescriptor.Size(is64Bit)]; + ContractDescriptor.Fill(descriptor, isLittleEndian, is64Bit, json.Length, pointerData.Length / pointerSize); + fixed (byte* jsonPtr = json) + { + ReadContext context = new ReadContext + { + ContractDescriptor = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(descriptor)), + ContractDescriptorLength = descriptor.Length, + JsonDescriptor = jsonPtr, + JsonDescriptorLength = json.Length, + PointerData = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(pointerData)), + PointerDataLength = pointerData.Length + }; + + bool success = Target.TryCreate(ContractDescriptorAddr, &ReadFromTarget, &context, out Target? target); + Assert.True(success); + + // Indirect values are pointer-sized, so max 32-bits for a 32-bit target + var expected = is64Bit + ? TestGlobals + : TestGlobals.Select(g => (g.Name, g.Value & 0xffffffff, g.Type)).ToArray(); + + ValidateGlobals(target, expected); + } + } + + private static void WritePointer(Span dest, ulong value, bool isLittleEndian, int pointerSize) + { + if (pointerSize == sizeof(ulong)) + { + if (isLittleEndian) + { + BinaryPrimitives.WriteUInt64LittleEndian(dest, value); + } + else + { + BinaryPrimitives.WriteUInt64BigEndian(dest, value); + } + } + else if (pointerSize == sizeof(uint)) + { + if (isLittleEndian) + { + BinaryPrimitives.WriteUInt32LittleEndian(dest, (uint)value); + } + else + { + BinaryPrimitives.WriteUInt32BigEndian(dest, (uint)value); + } + } + } + + private static void ValidateGlobals( + Target target, + (string Name, ulong Value, string? Type)[] globals, + [CallerMemberName] string caller = "", + [CallerFilePath] string filePath = "", + [CallerLineNumber] int lineNumber = 0) + { + foreach (var (name, value, type) in globals) + { + // Validate that each global can/cannot be read successfully based on its type + // and that it matches the expected value if successfully read + { + bool success = target.TryReadGlobal(name, out sbyte actual); + AssertEqualsWithCallerInfo(type is null || type == "int8", success); + if (success) + AssertEqualsWithCallerInfo((sbyte)value, actual); + } + { + bool success = target.TryReadGlobal(name, out byte actual); + AssertEqualsWithCallerInfo(type is null || type == "uint8", success); + if (success) + AssertEqualsWithCallerInfo(value, actual); + } + { + bool success = target.TryReadGlobal(name, out short actual); + AssertEqualsWithCallerInfo(type is null || type == "int16", success); + if (success) + AssertEqualsWithCallerInfo((short)value, actual); + } + { + bool success = target.TryReadGlobal(name, out ushort actual); + AssertEqualsWithCallerInfo(type is null || type == "uint16", success); + if (success) + AssertEqualsWithCallerInfo(value, actual); + } + { + bool success = target.TryReadGlobal(name, out int actual); + AssertEqualsWithCallerInfo(type is null || type == "int32", success); + if (success) + AssertEqualsWithCallerInfo((int)value, actual); + } + { + bool success = target.TryReadGlobal(name, out uint actual); + AssertEqualsWithCallerInfo(type is null || type == "uint32", success); + if (success) + AssertEqualsWithCallerInfo(value, actual); + } + { + bool success = target.TryReadGlobal(name, out long actual); + AssertEqualsWithCallerInfo(type is null || type == "int64", success); + if (success) + AssertEqualsWithCallerInfo((long)value, actual); + } + { + bool success = target.TryReadGlobal(name, out ulong actual); + AssertEqualsWithCallerInfo(type is null || type == "uint64", success); + if (success) + AssertEqualsWithCallerInfo(value, actual); + } + { + bool success = target.TryReadGlobalPointer(name, out TargetPointer actual); + AssertEqualsWithCallerInfo(type is null || type == "pointer" || type == "nint" || type == "nuint", success); + if (success) + AssertEqualsWithCallerInfo(value, actual.Value); + } + } + + void AssertEqualsWithCallerInfo(T expected, T actual) where T : unmanaged + { + Assert.True(expected.Equals(actual), $"Expected: {expected}. Actual: {actual}. [test case: {caller} in {filePath}:{lineNumber}]"); + } + } + + [UnmanagedCallersOnly] + private static int ReadFromTarget(ulong address, byte* buffer, uint length, void* context) + { + ReadContext* readContext = (ReadContext*)context; + var span = new Span(buffer, (int)length); + + // Populate the span with the requested portion of the contract descriptor + if (address >= ContractDescriptorAddr && address <= ContractDescriptorAddr + (ulong)readContext->ContractDescriptorLength - length) + { + ulong offset = address - ContractDescriptorAddr; + new ReadOnlySpan(readContext->ContractDescriptor + offset, (int)length).CopyTo(span); + return 0; + } + + // Populate the span with the JSON descriptor - this assumes the product will read it all at once. + if (address == JsonDescriptorAddr) + { + new ReadOnlySpan(readContext->JsonDescriptor, readContext->JsonDescriptorLength).CopyTo(span); + return 0; + } + + // Populate the span with the requested portion of the pointer data + if (address >= PointerDataAddr && address <= PointerDataAddr + (ulong)readContext->PointerDataLength - length) + { + ulong offset = address - PointerDataAddr; + new ReadOnlySpan(readContext->PointerData + offset, (int)length).CopyTo(span); + return 0; + } + + return -1; + } + + // Used by ReadFromTarget to return the appropriate bytes + private struct ReadContext + { + public byte* ContractDescriptor; + public int ContractDescriptorLength; + + public byte* JsonDescriptor; + public int JsonDescriptorLength; + + public byte* PointerData; + public int PointerDataLength; + } + + private static class ContractDescriptor + { + public static int Size(bool is64Bit) => is64Bit ? sizeof(ContractDescriptor64) : sizeof(ContractDescriptor32); + + public static void Fill(Span dest, bool isLittleEndian, bool is64Bit, int jsonDescriptorSize, int pointerDataCount) + { + if (is64Bit) + { + ContractDescriptor64.Fill(dest, isLittleEndian, jsonDescriptorSize, pointerDataCount); + } + else + { + ContractDescriptor32.Fill(dest, isLittleEndian, jsonDescriptorSize, pointerDataCount); + } + } + + private struct ContractDescriptor32 + { + public ulong Magic = BitConverter.ToUInt64("DNCCDAC\0"u8); + public uint Flags = 0x2 /*32-bit*/ | 0x1; + public uint DescriptorSize; + public uint Descriptor = JsonDescriptorAddr; + public uint PointerDataCount; + public uint Pad0 = 0; + public uint PointerData = PointerDataAddr; + + public ContractDescriptor32() { } + + public static void Fill(Span dest, bool isLittleEndian, int jsonDescriptorSize, int pointerDataCount) + { + ContractDescriptor32 descriptor = new() + { + DescriptorSize = (uint)jsonDescriptorSize, + PointerDataCount = (uint)pointerDataCount, + }; + if (BitConverter.IsLittleEndian != isLittleEndian) + descriptor.ReverseEndianness(); + + MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref descriptor, 1)).CopyTo(dest); + } + + private void ReverseEndianness() + { + Magic = BinaryPrimitives.ReverseEndianness(Magic); + Flags = BinaryPrimitives.ReverseEndianness(Flags); + DescriptorSize = BinaryPrimitives.ReverseEndianness(DescriptorSize); + Descriptor = BinaryPrimitives.ReverseEndianness(Descriptor); + PointerDataCount = BinaryPrimitives.ReverseEndianness(PointerDataCount); + Pad0 = BinaryPrimitives.ReverseEndianness(Pad0); + PointerData = BinaryPrimitives.ReverseEndianness(PointerData); + } + } + + private struct ContractDescriptor64 + { + public ulong Magic = BitConverter.ToUInt64("DNCCDAC\0"u8); + public uint Flags = 0x1; + public uint DescriptorSize; + public ulong Descriptor = JsonDescriptorAddr; + public uint PointerDataCount; + public uint Pad0 = 0; + public ulong PointerData = PointerDataAddr; + + public ContractDescriptor64() { } + + public static void Fill(Span dest, bool isLittleEndian, int jsonDescriptorSize, int pointerDataCount) + { + ContractDescriptor64 descriptor = new() + { + DescriptorSize = (uint)jsonDescriptorSize, + PointerDataCount = (uint)pointerDataCount, + }; + if (BitConverter.IsLittleEndian != isLittleEndian) + descriptor.ReverseEndianness(); + + MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref descriptor, 1)).CopyTo(dest); + } + + private void ReverseEndianness() + { + Magic = BinaryPrimitives.ReverseEndianness(Magic); + Flags = BinaryPrimitives.ReverseEndianness(Flags); + DescriptorSize = BinaryPrimitives.ReverseEndianness(DescriptorSize); + Descriptor = BinaryPrimitives.ReverseEndianness(Descriptor); + PointerDataCount = BinaryPrimitives.ReverseEndianness(PointerDataCount); + Pad0 = BinaryPrimitives.ReverseEndianness(Pad0); + PointerData = BinaryPrimitives.ReverseEndianness(PointerData); + } + } + } + +} diff --git a/src/native/managed/compile-native.proj b/src/native/managed/compile-native.proj index d227466bfcebd1..bcda8c5d6b57b5 100644 --- a/src/native/managed/compile-native.proj +++ b/src/native/managed/compile-native.proj @@ -35,24 +35,17 @@ --gcc-toolchain=$(ROOTFS_DIR)/usr - - - - - - - + + - - @(SubprojectProps->'%(Identity)=%(Value)', ';') - - + + - - - - - $(OutputPath)stripped\ - $(StrippedOutputPath)$(TargetName)$(NativeBinaryExt) - .dylib.dwarf - .so.dbg - $(StrippedOutputPath)$(TargetName)$(StrippedExt) - - - - - - - true - - - - - - false - - - - - - - - - - - - - <_StripLike Condition="'$(TargetsOSX)' == 'true' or '$(TargetsAppleMobile)' == 'true'">apple - <_StripLike Condition="'$(_StripLike)' == ''">gnu - - - - - - - - - - - - - - - - - - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(RuntimeFlavor.ToLower())', '$(TargetOS).$(TargetArchitecture).$(RuntimeConfiguration)')) - - - - <_NormalizedInstallRuntimeComponentDest Include="$([MSBuild]::NormalizeDirectory('$(FinalRuntimeComponentDestinationBase)', '%(InstallRuntimeComponentDestination.Identity)'))" /> - - - - - - - - - - - - - - - - - - - + + + + + + + + + $(OutputPath)stripped\ + $(StrippedOutputPath)$(TargetName)$(NativeBinaryExt) + .dylib.dwarf + .so.dbg + $(StrippedOutputPath)$(TargetName)$(StrippedExt) + + + + + + + true + + + + + + false + + + + + + + + + + + + + <_StripLike Condition="'$(TargetsOSX)' == 'true' or '$(TargetsAppleMobile)' == 'true'">apple + <_StripLike Condition="'$(_StripLike)' == ''">gnu + + + + + + + + + + + + + + + + + + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(RuntimeFlavor.ToLower())', '$(TargetOS).$(TargetArchitecture).$(RuntimeConfiguration)')) + + + + <_NormalizedInstallRuntimeComponentDest Include="$([MSBuild]::NormalizeDirectory('$(FinalRuntimeComponentDestinationBase)', '%(InstallRuntimeComponentDestination.Identity)'))" /> + + + + + + + + + + + + + + + + + + diff --git a/src/native/managed/subproject.props b/src/native/managed/subproject.props new file mode 100644 index 00000000000000..b51d6f3428a4a6 --- /dev/null +++ b/src/native/managed/subproject.props @@ -0,0 +1,13 @@ + + + + + + + + + + + @(SubprojectProps->'%(Identity)=%(Value)', ';') + + diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 09d58b2a9d083d..4e98e9271490b6 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -1237,26 +1237,7 @@ private string FixupSymbolName(string name) if (_symbolNameFixups.TryGetValue(name, out string? fixedName)) return fixedName; - UTF8Encoding utf8 = new(); - byte[] bytes = utf8.GetBytes(name); - StringBuilder sb = new(); - - foreach (byte b in bytes) - { - if ((b >= (byte)'0' && b <= (byte)'9') || - (b >= (byte)'a' && b <= (byte)'z') || - (b >= (byte)'A' && b <= (byte)'Z') || - (b == (byte)'_')) - { - sb.Append((char)b); - } - else - { - sb.Append('_'); - } - } - - fixedName = sb.ToString(); + fixedName = Utils.FixupSymbolName(name); _symbolNameFixups[name] = fixedName; return fixedName; } diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.props b/src/tasks/AotCompilerTask/MonoAOTCompiler.props index 1c7bc065d2a475..1fc8e8f41adf50 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.props +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.props @@ -1,9 +1,9 @@ - + - + diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index a9bf648f8129a3..aed4bf7dfaeba3 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -218,15 +218,24 @@ public void CreateXcodeProject(string projectName, string cmakeDirectoryPath) targetName = Target.ToString(); break; } - var deployTarget = (Target == TargetNames.MacCatalyst) ? " -DCMAKE_OSX_ARCHITECTURES=" + XcodeArch : " -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0"; var cmakeArgs = new StringBuilder(); cmakeArgs .Append("-S.") .Append(" -B").Append(projectName) .Append(" -GXcode") .Append(" -DTARGETS_APPLE_MOBILE=1") - .Append(" -DCMAKE_SYSTEM_NAME=").Append(targetName) - .Append(deployTarget); + .Append(" -DCMAKE_SYSTEM_NAME=").Append(targetName); + + if (Target == TargetNames.MacCatalyst) + { + // min deploy target version is passed later when invoking xcodebuild + cmakeArgs.Append(" -DCMAKE_OSX_ARCHITECTURES=" + XcodeArch); + } + else + { + // arch is passed later when invoking xcodebuild + cmakeArgs.Append(" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2"); + } Utils.RunProcess(Logger, "cmake", cmakeArgs.ToString(), workingDir: cmakeDirectoryPath); } @@ -608,7 +617,7 @@ public string BuildAppBundle( .Append(" -UseModernBuildSystem=YES") .Append(" -archivePath \"").Append(Path.GetDirectoryName(xcodePrjPath)).Append('"') .Append(" -derivedDataPath \"").Append(Path.GetDirectoryName(xcodePrjPath)).Append('"') - .Append(" IPHONEOS_DEPLOYMENT_TARGET=14.2"); + .Append(" IPHONEOS_DEPLOYMENT_TARGET=15.0"); break; } } @@ -633,7 +642,7 @@ public string BuildAppBundle( .Append(" -UseModernBuildSystem=YES") .Append(" -archivePath \"").Append(Path.GetDirectoryName(xcodePrjPath)).Append('"') .Append(" -derivedDataPath \"").Append(Path.GetDirectoryName(xcodePrjPath)).Append('"') - .Append(" IPHONEOS_DEPLOYMENT_TARGET=13.5"); + .Append(" IPHONEOS_DEPLOYMENT_TARGET=15.0"); break; } } diff --git a/src/tasks/Common/Utils.cs b/src/tasks/Common/Utils.cs index eca2ccd9740233..1e724bf3ce2d8d 100644 --- a/src/tasks/Common/Utils.cs +++ b/src/tasks/Common/Utils.cs @@ -11,6 +11,7 @@ using System.Reflection.Metadata; using System.Security.Cryptography; using System.Text; +using System.Linq; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -33,6 +34,8 @@ public enum HashEncodingType private static readonly object s_SyncObj = new object(); + private static readonly char[] s_charsToReplace = new[] { '.', '-', '+', '<', '>' }; + public static string GetEmbeddedResource(string file) { using Stream stream = typeof(Utils).Assembly @@ -323,7 +326,7 @@ public static string ComputeTextIntegrity(string str) return "sha256-" + Convert.ToBase64String(hash); } -#if NETCOREAPP +#if NET public static void DirectoryCopy(string sourceDir, string destDir, Func? predicate=null) { if (!Directory.Exists(destDir)) @@ -347,7 +350,7 @@ public static void DirectoryCopy(string sourceDir, string destDir, Func= (byte)'0' && b <= (byte)'9') || + (b >= (byte)'a' && b <= (byte)'z') || + (b >= (byte)'A' && b <= (byte)'Z') || + (b == (byte)'_')) + { + sb.Append((char)b); + } + else if (s_charsToReplace.Contains((char)b)) + { + sb.Append('_'); + } + else + { + sb.Append($"_{b:X}_"); + } + } + + return sb.ToString(); + } } diff --git a/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs b/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs index 843333ff3fcbbd..1ec6c1a090a69b 100644 --- a/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs +++ b/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs @@ -233,6 +233,9 @@ private static bool ExtractTargetPlatformAndArchitecture(string runtimeIdentifie case "riscv64": architecture = Architecture.RiscV64; break; + case "loongarch64": + architecture = Architecture.LoongArch64; + break; default: return false; } @@ -391,6 +394,7 @@ private static string ArchitectureToString(Architecture architecture) Architecture.Arm => "arm", Architecture.Arm64 => "arm64", Architecture.RiscV64 => "riscv64", + Architecture.LoongArch64 => "loongarch64", _ => null }; } diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs index 2d21f3820a5584..01c5d4dda4dd0f 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; using System.IO; using Microsoft.Build.Framework; @@ -59,52 +60,66 @@ public override bool Execute() continue; } - var dllFilePath = candidate.ItemSpec; - var webcilFileName = Path.GetFileNameWithoutExtension(dllFilePath) + Utils.WebcilInWasmExtension; - string candidatePath = candidate.GetMetadata("AssetTraitName") == "Culture" - ? Path.Combine(OutputPath, candidate.GetMetadata("AssetTraitValue")) - : OutputPath; - - string finalWebcil = Path.Combine(candidatePath, webcilFileName); - - if (Utils.IsNewerThan(dllFilePath, finalWebcil)) + try { - var tmpWebcil = Path.Combine(tmpDir, webcilFileName); - var logAdapter = new LogAdapter(Log); - var webcilWriter = Microsoft.WebAssembly.Build.Tasks.WebcilConverter.FromPortableExecutable(inputPath: dllFilePath, outputPath: tmpWebcil, logger: logAdapter); - webcilWriter.ConvertToWebcil(); - - if (!Directory.Exists(candidatePath)) - Directory.CreateDirectory(candidatePath); - - if (Utils.CopyIfDifferent(tmpWebcil, finalWebcil, useHash: true)) - Log.LogMessage(MessageImportance.Low, $"Generated {finalWebcil} ."); - else - Log.LogMessage(MessageImportance.Low, $"Skipped generating {finalWebcil} as the contents are unchanged."); + TaskItem webcilItem = ConvertDll(tmpDir, candidate); + webCilCandidates.Add(webcilItem); } - else + catch (Exception ex) { - Log.LogMessage(MessageImportance.Low, $"Skipping {dllFilePath} as it is older than the output file {finalWebcil}"); + Log.LogError($"Failed to convert '{candidate.ItemSpec}' to webcil: {ex.Message}"); + return false; } + } + + WebCilCandidates = webCilCandidates.ToArray(); + return true; + } - _fileWrites.Add(finalWebcil); + private TaskItem ConvertDll(string tmpDir, ITaskItem candidate) + { + var dllFilePath = candidate.ItemSpec; + var webcilFileName = Path.GetFileNameWithoutExtension(dllFilePath) + Utils.WebcilInWasmExtension; + string candidatePath = candidate.GetMetadata("AssetTraitName") == "Culture" + ? Path.Combine(OutputPath, candidate.GetMetadata("AssetTraitValue")) + : OutputPath; - var webcilItem = new TaskItem(finalWebcil, candidate.CloneCustomMetadata()); - webcilItem.SetMetadata("RelativePath", Path.ChangeExtension(candidate.GetMetadata("RelativePath"), Utils.WebcilInWasmExtension)); - webcilItem.SetMetadata("OriginalItemSpec", finalWebcil); + string finalWebcil = Path.Combine(candidatePath, webcilFileName); - if (webcilItem.GetMetadata("AssetTraitName") == "Culture") - { - string relatedAsset = webcilItem.GetMetadata("RelatedAsset"); - relatedAsset = Path.ChangeExtension(relatedAsset, Utils.WebcilInWasmExtension); - webcilItem.SetMetadata("RelatedAsset", relatedAsset); - Log.LogMessage(MessageImportance.Low, $"Changing related asset of {webcilItem} to {relatedAsset}."); - } + if (Utils.IsNewerThan(dllFilePath, finalWebcil)) + { + var tmpWebcil = Path.Combine(tmpDir, webcilFileName); + var logAdapter = new LogAdapter(Log); + var webcilWriter = Microsoft.WebAssembly.Build.Tasks.WebcilConverter.FromPortableExecutable(inputPath: dllFilePath, outputPath: tmpWebcil, logger: logAdapter); + webcilWriter.ConvertToWebcil(); - webCilCandidates.Add(webcilItem); + if (!Directory.Exists(candidatePath)) + Directory.CreateDirectory(candidatePath); + + if (Utils.CopyIfDifferent(tmpWebcil, finalWebcil, useHash: true)) + Log.LogMessage(MessageImportance.Low, $"Generated {finalWebcil} ."); + else + Log.LogMessage(MessageImportance.Low, $"Skipped generating {finalWebcil} as the contents are unchanged."); + } + else + { + Log.LogMessage(MessageImportance.Low, $"Skipping {dllFilePath} as it is older than the output file {finalWebcil}"); } - WebCilCandidates = webCilCandidates.ToArray(); - return true; + _fileWrites.Add(finalWebcil); + + var webcilItem = new TaskItem(finalWebcil, candidate.CloneCustomMetadata()); + webcilItem.SetMetadata("RelativePath", Path.ChangeExtension(candidate.GetMetadata("RelativePath"), Utils.WebcilInWasmExtension)); + webcilItem.SetMetadata("OriginalItemSpec", finalWebcil); + + if (webcilItem.GetMetadata("AssetTraitName") == "Culture") + { + string relatedAsset = webcilItem.GetMetadata("RelatedAsset"); + relatedAsset = Path.ChangeExtension(relatedAsset, Utils.WebcilInWasmExtension); + webcilItem.SetMetadata("RelatedAsset", relatedAsset); + Log.LogMessage(MessageImportance.Low, $"Changing related asset of {webcilItem} to {relatedAsset}."); + } + + return webcilItem; } } diff --git a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs index 13c34bde4b8ea1..0a0495f72fef4e 100644 --- a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs +++ b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilConverter.cs @@ -213,7 +213,7 @@ private static void WriteSectionHeader(Stream s, WebcilSectionHeader sectionHead WriteStructure(s, sectionHeader); } -#if NETCOREAPP2_1_OR_GREATER +#if NET private static void WriteStructure(Stream s, T structure) where T : unmanaged { @@ -256,7 +256,7 @@ private static void CopySections(Stream outStream, FileStream inputStream, Immut } } -#if NETCOREAPP2_1_OR_GREATER +#if NET private static void ReadExactly(FileStream s, Span buffer) { s.ReadExactly(buffer); diff --git a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs index ac4f9d86095a90..6e079b58c32599 100644 --- a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs +++ b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilReader.cs @@ -278,7 +278,7 @@ private static MetadataReaderProvider DecodeEmbeddedPortablePdbDirectoryData(Blo using (var compressedStream = new MemoryStream(compressedBuffer, writable: false)) using (var deflateStream = new System.IO.Compression.DeflateStream(compressedStream, System.IO.Compression.CompressionMode.Decompress, leaveOpen: true)) { -#if NETCOREAPP1_1_OR_GREATER +#if NET decompressedBuffer = GC.AllocateUninitializedArray(decompressedSize); #else decompressedBuffer = new byte[decompressedSize]; diff --git a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilWasmWrapper.cs b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilWasmWrapper.cs index 3f8560446306fb..f47a1247474784 100644 --- a/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilWasmWrapper.cs +++ b/src/tasks/Microsoft.NET.WebAssembly.Webcil/WebcilWasmWrapper.cs @@ -63,7 +63,7 @@ public void WriteWasmWrappedWebcil(Stream outputStream) // // extracted by wasm-reader -s wrapper.wasm private static -#if NET7_0_OR_GREATER +#if NET ReadOnlyMemory #else byte[] @@ -80,7 +80,7 @@ private static // // extracted by wasm-reader -s wrapper.wasm private static -#if NET7_0_OR_GREATER +#if NET ReadOnlyMemory #else byte[] @@ -91,7 +91,7 @@ private static private static void WriteWasmHeader(Stream outputStream) { -#if NET7_0_OR_GREATER +#if NET outputStream.Write(s_wasmWrapperPrefix.Span); #else outputStream.Write(s_wasmWrapperPrefix, 0, s_wasmWrapperPrefix.Length); @@ -100,7 +100,7 @@ private static void WriteWasmHeader(Stream outputStream) private static void WriteWasmSuffix(Stream outputStream) { -#if NET7_0_OR_GREATER +#if NET outputStream.Write(s_wasmWrapperSuffix.Span); #else outputStream.Write(s_wasmWrapperSuffix, 0, s_wasmWrapperSuffix.Length); diff --git a/src/tasks/MobileBuildTasks/Apple/AppleProject.cs b/src/tasks/MobileBuildTasks/Apple/AppleProject.cs index f7927fa2bb5a81..6a0f61c1968c41 100644 --- a/src/tasks/MobileBuildTasks/Apple/AppleProject.cs +++ b/src/tasks/MobileBuildTasks/Apple/AppleProject.cs @@ -27,7 +27,7 @@ public AppleProject(string projectName, string runtimeIdentifier, TaskLoggingHel { GetTargets(runtimeIdentifier, out targetOS, out targetArchitecture); - defaultMinOSVersion = (targetOS == "maccatalyst") ? "13.1" : "11.0"; + defaultMinOSVersion = (targetOS == "maccatalyst") ? "15.0" : "12.2"; targetAbi = DetermineAbi(targetArchitecture); AppleSdk sdk = new AppleSdk(targetOS, logger); diff --git a/src/tasks/WasmAppBuilder/ManagedToNativeGenerator.cs b/src/tasks/WasmAppBuilder/ManagedToNativeGenerator.cs index 3acdcf06ba8a64..db9cf0cef04d87 100644 --- a/src/tasks/WasmAppBuilder/ManagedToNativeGenerator.cs +++ b/src/tasks/WasmAppBuilder/ManagedToNativeGenerator.cs @@ -36,8 +36,6 @@ public class ManagedToNativeGenerator : Task [Output] public string[]? FileWrites { get; private set; } - private static readonly char[] s_charsToReplace = new[] { '.', '-', '+', '<', '>' }; - public override bool Execute() { if (Assemblies!.Length == 0) @@ -108,30 +106,7 @@ string FixupSymbolName(string name) if (_symbolNameFixups.TryGetValue(name, out string? fixedName)) return fixedName; - UTF8Encoding utf8 = new(); - byte[] bytes = utf8.GetBytes(name); - StringBuilder sb = new(); - - foreach (byte b in bytes) - { - if ((b >= (byte)'0' && b <= (byte)'9') || - (b >= (byte)'a' && b <= (byte)'z') || - (b >= (byte)'A' && b <= (byte)'Z') || - (b == (byte)'_')) - { - sb.Append((char)b); - } - else if (s_charsToReplace.Contains((char)b)) - { - sb.Append('_'); - } - else - { - sb.Append($"_{b:X}_"); - } - } - - fixedName = sb.ToString(); + fixedName = Utils.FixupSymbolName(name); _symbolNameFixups[name] = fixedName; return fixedName; } diff --git a/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs b/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs index 4a29b47666e94d..7808655b7f6b68 100644 --- a/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs +++ b/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs @@ -304,7 +304,7 @@ private string DelegateKey(PInvokeCallback export) // it needs to match the key generated in get_native_to_interp var method = export.Method; string module_symbol = method.DeclaringType!.Module!.Assembly!.GetName()!.Name!; - return $"\"{module_symbol}_{method.DeclaringType.Name}_{method.Name}\"".Replace('.', '_'); + return $"\"{_fixupSymbolName($"{module_symbol}_{method.DeclaringType.Name}_{method.Name}")}\""; } #pragma warning disable SYSLIB1045 // framework doesn't support GeneratedRegexAttribute diff --git a/src/tests/Common/CLRTest.Jit.targets b/src/tests/Common/CLRTest.Jit.targets index 6fd00de8977f6a..5c2a0735a414fe 100644 --- a/src/tests/Common/CLRTest.Jit.targets +++ b/src/tests/Common/CLRTest.Jit.targets @@ -140,7 +140,7 @@ IF NOT DEFINED DoLink ( DependsOnTargets="GetDisasmCheckData"> false - true + true $(scriptPath)__jit_disasm.out $(scriptPath)__jit_disasm_list.out @@ -184,7 +184,7 @@ fi DependsOnTargets="GetDisasmCheckData"> false - true + true $(scriptPath)__jit_disasm.out $(scriptPath)__jit_disasm_list.out diff --git a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs index 0337fa9e624f0d..66937878587ddd 100644 --- a/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs +++ b/src/tests/Common/CoreCLRTestLibrary/OutOfProcessTest.cs @@ -49,7 +49,7 @@ static OutOfProcessTest() && !OperatingSystem.IsBrowser() && !OperatingSystem.IsOSPlatform("Wasi"); - public static void RunOutOfProcessTest(string assemblyPath) + public static void RunOutOfProcessTest(string assemblyPath, string testPathPrefix) { int ret = -100; string baseDir = AppContext.BaseDirectory; @@ -63,17 +63,23 @@ public static void RunOutOfProcessTest(string assemblyPath) { CoreclrTestWrapperLib wrapper = new CoreclrTestWrapperLib(); + string testScriptPath = assemblyPath; + if (testPathPrefix != null) + testScriptPath = Path.Combine(testPathPrefix, testScriptPath); + if (OperatingSystem.IsWindows()) { - testExecutable = Path.Combine(baseDir, Path.ChangeExtension(assemblyPath, ".cmd")); + testExecutable = Path.Combine(baseDir, Path.ChangeExtension(testScriptPath, ".cmd")); } else { - testExecutable = Path.Combine(baseDir, Path.ChangeExtension(assemblyPath.Replace("\\", "/"), ".sh")); + testExecutable = Path.Combine(baseDir, Path.ChangeExtension(testScriptPath.Replace("\\", "/"), ".sh")); } if (!File.Exists(testExecutable)) { + Console.WriteLine($"Test executable '{testExecutable}' not found, skipping."); + // Skip platform-specific test when running on the excluded platform return; } diff --git a/src/tests/Common/CoreCLRTestLibrary/Utilities.cs b/src/tests/Common/CoreCLRTestLibrary/Utilities.cs index d48a3e6bd6e79d..a3d6df5a623482 100644 --- a/src/tests/Common/CoreCLRTestLibrary/Utilities.cs +++ b/src/tests/Common/CoreCLRTestLibrary/Utilities.cs @@ -101,7 +101,7 @@ public static bool IsWindowsIoTCore public static bool HasAssemblyFiles => !string.IsNullOrEmpty(typeof(Utilities).Assembly.Location); public static bool IsSingleFile => !HasAssemblyFiles; -#if NETCOREAPP +#if NET public static bool IsReflectionEmitSupported => RuntimeFeature.IsDynamicCodeSupported; public static bool IsNotReflectionEmitSupported => !IsReflectionEmitSupported; #else diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index b5f42595ca77e3..5701becf7c486c 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -47,6 +47,16 @@ } }"; +const string SimpleVecOpTest_ValidationLogicForCndSel = @"for (var i = 0; i < RetElementCount; i++) + { + {Op1BaseType} iterResult = (mask[i] != 0) ? {GetIterResult} : falseVal[i]; + if (iterResult != result[i]) + { + succeeded = false; + break; + } + }"; + const string VecPairBinOpTest_ValidationLogic = @" int index = 0; int half = RetElementCount / 2; @@ -88,26 +98,30 @@ (string templateFileName, string outputTemplateName, Dictionary templateData)[] Templates = new[] { - ("_UnaryOpScalarTestTemplate.template", "DuplicateTest.template", new Dictionary { ["TemplateName"] = "Duplicate", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmUnaryOpTestTemplate.template", "ImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmUnaryOpTestTemplate.template", "VecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmTernaryOpTestTemplate.template", "ImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmOpTestTemplate.template", "ImmOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmBinaryOpTestTemplate.template", "ImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_ImmBinaryOpTestTemplate.template", "VecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "SimpleBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_TernaryOpTestTemplate.template", "VecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmTernaryOpTestTemplate.template", "VecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_ImmTernaryOpTestTemplate.template", "SimpleImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "SimpleUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "SimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "VecPairBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecPairBinOpTest_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "VecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "VecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_TernaryOpTestTemplate.template", "SimpleTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), - ("_UnaryOpTestTemplate.template", "SecureHashUnOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), - ("_BinaryOpTestTemplate.template", "SecureHashBinOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), - ("_TernaryOpTestTemplate.template", "SecureHashTernOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }) + ("_UnaryOpScalarTestTemplate.template", "DuplicateTest.template", new Dictionary { ["TemplateName"] = "Duplicate", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmUnaryOpTestTemplate.template", "ImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmUnaryOpTestTemplate.template", "VecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmTernaryOpTestTemplate.template", "ImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmOpTestTemplate.template", "ImmOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmBinaryOpTestTemplate.template", "ImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmBinaryOpTestTemplate.template", "VecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "SimpleBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_TernaryOpTestTemplate.template", "VecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmTernaryOpTestTemplate.template", "VecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_ImmTernaryOpTestTemplate.template", "SimpleImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "SimpleUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "SimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "VecPairBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecPairBinOpTest_ValidationLogic }), + ("_BinaryOp_SveTestTemplate.template", "SveVecPairBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecPairBinOpTest_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "VecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "VecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_TernaryOpTestTemplate.template", "SimpleTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_UnaryOpTestTemplate.template", "SecureHashUnOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), + ("_BinaryOpTestTemplate.template", "SecureHashBinOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), + ("_TernaryOpTestTemplate.template", "SecureHashTernOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), + ("_SveUnaryOpTestTemplate.template", "SveSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel }), + ("_SveBinaryOpTestTemplate.template", "SveVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel }), + ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), }; (string templateFileName, Dictionary templateData)[] AdvSimdInputs = new [] @@ -2878,16 +2892,324 @@ (string templateFileName, Dictionary templateData)[] SveInputs = new [] { - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_float", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_double", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_short", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_int", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_long", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_byte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_uint", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(sbyte)Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(short)Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.Abs(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Abs_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Abs", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(long)Helpers.Abs(firstOp[i]) != (long)result[i]", ["GetIterResult"] = "(long)Helpers.Abs(leftOp[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Add_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Add", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Add(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossRecursivePairwise(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0.0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossRecursivePairwise(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0.0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningLong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningLong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningULong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWideningULong(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_And_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "And", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.And(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AndAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AndAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AndAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + ("SveConditionalSelect.template", new Dictionary { ["TestName"] = "Sve_ConditionalSelect_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ConditionalSelect", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "(firstOp[i] != 0 ? (result[i] != secondOp[i]) : (result[i] != thirdOp[i]))",}), + + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count16BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count16BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int16)));",}), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count32BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count32BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int32)));",}), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count64BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count64BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Int64)));",}), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "Sve_Count8BitElements", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Count8BitElements", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "SveMaskPattern.All", ["ValidateResult"] = "isUnexpectedResult = (result != (UInt64)(Unsafe.SizeOf>() / sizeof(Byte)));",}), + + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask16Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask16Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask32Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask32Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask64Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask64Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int32)i, right) != (Int32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_Int64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (Int64)i, right) != (Int64)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt32)i, right) != (UInt32)result[i]",}), + ("ScalarBinOpRetVecTest.template",new Dictionary {["TestName"] = "Sve_CreateWhileLessThanOrEqualMask8Bit_UInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateWhileLessThanOrEqualMask8Bit", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.WhileLessThanOrEqualMask(left + (UInt64)i, right) != (UInt64)result[i]",}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Divide_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Divide", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Divide(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Divide(left[i], right[i])"}), + + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_float", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_double", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_sbyte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_short", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_int", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_long", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_byte", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_ushort", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_uint", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt16SignExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt16SignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt16SignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt16SignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt32SignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt32SignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt32SignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt16ZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt16ZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt16ZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt16ZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt32ZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt32ZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt32ZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Max_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Max", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumber_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumber_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Max(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumberAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MaxNumberAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Min_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Min", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumber_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumber_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Min(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumberAcross_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_MinNumberAcross_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_OrAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "OrAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.OrAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend32_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningLower_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_short_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_int_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_SignExtendWideningUpper_long_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.SignExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(byte)TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Xor_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Xor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Xor(left[i], right[i])"}), + + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_XorAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "XorAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.XorAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipEven_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend32_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningLower_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWidening(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_ushort_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_uint_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SveVecReduceUnOpTest.template",new Dictionary {["TestName"] = "Sve_ZeroExtendWideningUpper_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipLow_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i + 1] != right[index]"}), }; diff --git a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs index c4bdef69eb9e91..712c435162aaf3 100644 --- a/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs +++ b/src/tests/Common/XUnitWrapperGenerator/ITestInfo.cs @@ -336,13 +336,16 @@ public sealed class OutOfProcessTest : ITestInfo private CodeBuilder _executionStatement { get; } private string RelativeAssemblyPath { get; } - public OutOfProcessTest(string displayName, string relativeAssemblyPath) + public OutOfProcessTest(string displayName, string relativeAssemblyPath, string? testBuildMode) { Method = displayName; DisplayNameForFiltering = displayName; TestNameExpression = $"@\"{displayName}\""; RelativeAssemblyPath = relativeAssemblyPath; + // Native AOT tests get generated into a 'native' directory, so we need to get out of that one first to find the test + string testPathPrefix = string.Equals(testBuildMode, "nativeaot", StringComparison.OrdinalIgnoreCase) ? "\"..\"" : "null"; + _executionStatement = new CodeBuilder(); _executionStatement.AppendLine(); _executionStatement.AppendLine("if (TestLibrary.OutOfProcessTest.OutOfProcessTestsSupported)"); @@ -350,7 +353,7 @@ public OutOfProcessTest(string displayName, string relativeAssemblyPath) using (_executionStatement.NewBracesScope()) { _executionStatement.AppendLine($@"TestLibrary.OutOfProcessTest" - + $@".RunOutOfProcessTest(@""{relativeAssemblyPath}"");"); + + $@".RunOutOfProcessTest(@""{relativeAssemblyPath}"", {testPathPrefix});"); } } diff --git a/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs b/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs index 9b9dd10b23569d..61f4488f0aaa3e 100644 --- a/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs +++ b/src/tests/Common/XUnitWrapperGenerator/OptionsHelper.cs @@ -9,6 +9,7 @@ public static class OptionsHelper private const string InMergedTestDirectoryOption = "build_property.InMergedTestDirectory"; private const string IsMergedTestRunnerAssemblyOption = "build_property.IsMergedTestRunnerAssembly"; private const string PriorityOption = "build_property.Priority"; + private const string TestBuildModeOption = "build_property.TestBuildMode"; private const string RuntimeFlavorOption = "build_property.RuntimeFlavor"; private const string IsOutOfProcessTestAssemblyOption = "build_metadata.AdditionalFiles.IsOutOfProcessTestAssembly"; private const string TestFilterOption = "build_property.TestFilter"; @@ -38,6 +39,8 @@ private static bool GetBoolOption(this AnalyzerConfigOptions options, string key internal static string RuntimeFlavor(this AnalyzerConfigOptions options) => options.TryGetValue(RuntimeFlavorOption, out string? flavor) ? flavor : "CoreCLR"; + internal static string? TestBuildMode(this AnalyzerConfigOptions options) => options.TryGetValue(TestBuildModeOption, out string? option) ? option : null; + internal static bool IsOutOfProcessTestAssembly(this AnalyzerConfigOptions options) => options.GetBoolOption(IsOutOfProcessTestAssemblyOption); internal static string? TestFilter(this AnalyzerConfigOptions options) => options.TryGetValue(TestFilterOption, out string? filter) ? filter : null; diff --git a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs index 06cfdf3022c1b7..bbff22006a4bd0 100644 --- a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs +++ b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.cs @@ -56,7 +56,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) string? testDisplayName = fileOptions.TestDisplayName(); if (assemblyPath is not null && testDisplayName is not null) { - return ImmutableArray.Create(new OutOfProcessTest(testDisplayName, assemblyPath)); + return ImmutableArray.Create(new OutOfProcessTest(testDisplayName, assemblyPath, fileOptions.TestBuildMode())); } } diff --git a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props index 067c31f8d6b4d0..fca5c164fba2e1 100644 --- a/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props +++ b/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props @@ -5,6 +5,7 @@ + diff --git a/src/tests/Common/testenvironment.proj b/src/tests/Common/testenvironment.proj index 73c5bf8a151c4f..8333973b0c0cf9 100644 --- a/src/tests/Common/testenvironment.proj +++ b/src/tests/Common/testenvironment.proj @@ -84,6 +84,7 @@ DOTNET_JitEnableOptRepeat; DOTNET_JitOptRepeat; DOTNET_JitOptRepeatCount; + DOTNET_JitDoReversePostOrderLayout; @@ -243,6 +244,7 @@ + diff --git a/src/tests/Directory.Build.props b/src/tests/Directory.Build.props index 1575beb7044ad0..8f85e3a0c293f2 100644 --- a/src/tests/Directory.Build.props +++ b/src/tests/Directory.Build.props @@ -141,6 +141,7 @@ false false false + true diff --git a/src/tests/Interop/ArrayMarshalling/UnalignedStructArray/MarshalUnalignedStructArray.cs b/src/tests/Interop/ArrayMarshalling/UnalignedStructArray/MarshalUnalignedStructArray.cs new file mode 100644 index 00000000000000..266a5dbf28d83b --- /dev/null +++ b/src/tests/Interop/ArrayMarshalling/UnalignedStructArray/MarshalUnalignedStructArray.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Runtime.InteropServices; +using TestLibrary; +using Xunit; + +public static unsafe class MarshalUnalignedStructArrayTest +{ + [Fact] + public static void TestEntryPoint() + { + /* + * This test validates that the size and offsets of InnerStruct and OuterStruct are as expected. + * It also demonstrates accessing unaligned data in an array. + */ + // Validate that both InnerStruct and OuterStruct have the correct size + Assert.Equal(12, sizeof(InnerStruct)); + Assert.Equal(24, sizeof(OuterStruct)); + + // Validate that the fields of InnerStruct are at the expected offsets + Assert.Equal(0, Marshal.OffsetOf("F0").ToInt32()); + Assert.Equal(8, Marshal.OffsetOf("F1").ToInt32()); + + // Validate that the fields of OuterStruct are at the expected offsets + Assert.Equal(0, Marshal.OffsetOf("F0").ToInt32()); + Assert.Equal(8, Marshal.OffsetOf("F1").ToInt32()); + Assert.Equal(20, Marshal.OffsetOf("F2").ToInt32()); + + // Validate that we are able to access unaligned in an array + InnerStruct[] arrStructs = new InnerStruct[] + { + new InnerStruct(1, 2), + new InnerStruct(3, 4), + new InnerStruct(5, 6), + }; + + fixed (InnerStruct* pStruct = &arrStructs[0]) + { + byte* ptr = (byte*)pStruct; + ptr += 12; + Assert.Equal(3, *(long*)ptr); + Assert.Equal(4, *(int*)(ptr + 8)); + } + + } +} + +[StructLayout(LayoutKind.Sequential, Size = 12)] +struct InnerStruct +{ + public long F0; + public uint F1; + + public InnerStruct(long f0, uint f1) + { + F0 = f0; + F1 = f1; + } +} + +[StructLayout(LayoutKind.Sequential, Size = 24)] +struct OuterStruct +{ + public sbyte F0; + public InnerStruct F1; + public uint F2; + + public OuterStruct(sbyte f0, InnerStruct f1, uint f2) + { + F0 = f0; + F1 = f1; + F2 = f2; + } +} diff --git a/src/tests/Interop/COM/NETClients/IDispatch/Program.cs b/src/tests/Interop/COM/NETClients/IDispatch/Program.cs index 3de48ae59b7944..c57f8c5149f27e 100644 --- a/src/tests/Interop/COM/NETClients/IDispatch/Program.cs +++ b/src/tests/Interop/COM/NETClients/IDispatch/Program.cs @@ -215,6 +215,67 @@ System.Collections.Generic.IEnumerable GetEnumerable(System.Collections.IEn } } + static void Validate_ValueCoerce_ReturnToManaged() + { + var dispatchCoerceTesting = (DispatchCoerceTesting)new DispatchCoerceTestingClass(); + + Console.WriteLine($"Calling {nameof(DispatchCoerceTesting.ReturnToManaged)} ..."); + + // Supported types + // See returned values in DispatchCoerceTesting.h + (VarEnum type, int expectedValue)[] supportedTypes = + { + (VarEnum.VT_EMPTY, 0), + (VarEnum.VT_I2, 123), + (VarEnum.VT_I4, 123), + (VarEnum.VT_R4, 1), + (VarEnum.VT_R8, 1), + (VarEnum.VT_CY, 123), + (VarEnum.VT_DATE, 1), + (VarEnum.VT_BSTR, 123), + (VarEnum.VT_ERROR, 123), + (VarEnum.VT_BOOL, -1), + (VarEnum.VT_DECIMAL, 123), + }; + + foreach (var (vt, expected) in supportedTypes) + { + Console.WriteLine($"Converting {vt} to int should be supported."); + int result = dispatchCoerceTesting.ReturnToManaged((short)vt); + Assert.Equal(expected, result); + } + + // Invalid: Rejected before reaching coerce + Console.WriteLine("Invalid variant type should throw InvalidOleVariantTypeException."); + var variantException = Assert.Throws(() => dispatchCoerceTesting.ReturnToManaged(0x7FFF)); + Assert.Equal(unchecked((int)0x80131531), variantException.HResult); + + // Not supported source or destination type: COMException { HResult: 0x80020005 } + + // DISP_E_PARAMNOTFOUND: Converts to Missing + Console.WriteLine("Converting from VT_ERROR with DISP_E_PARAMNOTFOUND should be rejected."); + var comException = Assert.Throws(() => dispatchCoerceTesting.ReturnToManaged(unchecked((short)((short)VarEnum.VT_ERROR | 0x8000)))); + Assert.Equal(unchecked((int)0x80020005), comException.HResult); + + Console.WriteLine("Converting int to VT_MISSING should be rejected."); + comException = Assert.Throws(() => dispatchCoerceTesting.ReturnToManaged_Missing()); + Assert.Equal(unchecked((int)0x80020005), comException.HResult); + + Console.WriteLine("Converting int to VT_NULL should be rejected."); + comException = Assert.Throws(() => dispatchCoerceTesting.ReturnToManaged_DBNull()); + Assert.Equal(unchecked((int)0x80020005), comException.HResult); + + // Rejected by VariantChangeTypeEx + Console.WriteLine("Converting VT_UNKNOWN to int should fail from VariantChangeTypeEx."); + Assert.Throws(() => dispatchCoerceTesting.ReturnToManaged((short)VarEnum.VT_UNKNOWN)); + Console.WriteLine("Converting VT_NULL to int should fail from VariantChangeTypeEx."); + Assert.Throws(() => dispatchCoerceTesting.ReturnToManaged((short)VarEnum.VT_NULL)); + + // LOCAL_BOOL + Console.WriteLine("VARIANT_BOOL should convert to non-numeric string."); + Assert.Equal("True", dispatchCoerceTesting.BoolToString()); + } + [Fact] public static int TestEntryPoint() { @@ -233,6 +294,7 @@ public static int TestEntryPoint() Validate_StructNotSupported(); Validate_LCID_Marshaled(); Validate_Enumerator(); + Validate_ValueCoerce_ReturnToManaged(); } catch (Exception e) { diff --git a/src/tests/Interop/COM/NETServer/DispatchCoerceTesting.cs b/src/tests/Interop/COM/NETServer/DispatchCoerceTesting.cs new file mode 100644 index 00000000000000..0367c605df4830 --- /dev/null +++ b/src/tests/Interop/COM/NETServer/DispatchCoerceTesting.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using Server.Contract; + +[ComVisible(true)] +[Guid(Server.Contract.Guids.DispatchCoerceTesting)] +public class DispatchCoerceTesting : Server.Contract.IDispatchCoerceTesting +{ + public int ReturnToManaged(short vt) + { + throw new NotImplementedException(); + } + + public int ManagedArgument(int arg) + { + return arg; + } + + public System.Reflection.Missing ReturnToManaged_Missing() + { + return System.Reflection.Missing.Value; + } + + public DBNull ReturnToManaged_DBNull() + { + return DBNull.Value; + } + + public string BoolToString() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp b/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp index 827b8d22876326..4c509a3df16240 100644 --- a/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp +++ b/src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp @@ -11,6 +11,7 @@ void Validate_Float_In_ReturnAndUpdateByRef(); void Validate_Double_In_ReturnAndUpdateByRef(); void Validate_LCID_Marshaled(); void Validate_Enumerator(); +void Validate_ParamCoerce(); template struct ComInit @@ -48,6 +49,7 @@ int __cdecl main() Validate_Double_In_ReturnAndUpdateByRef(); Validate_LCID_Marshaled(); Validate_Enumerator(); + Validate_ParamCoerce(); } catch (HRESULT hr) { @@ -459,3 +461,111 @@ void Validate_Enumerator() ::printf(" -- Validate returned IEnumVARIANT\n"); ValidateReturnedEnumerator(&result); } + +void Validate_ParamCoerce_Type(ComSmartPtr& dispatchCoerceTesting, VARENUM type, int lcid, DISPID methodId) +{ + HRESULT hr; + + DISPPARAMS params; + VARIANTARG arg; + params.cArgs = 1; + params.rgvarg = &arg; + params.cNamedArgs = 0; + params.rgdispidNamedArgs = nullptr; + + VARIANT result; + + V_VT(&arg) = type; + + switch (type) + { + case VT_BSTR: + { + BSTR str = ::SysAllocString(L"123"); + V_BSTR(&arg) = str; + break; + } + case VT_R4: + { + V_R4(&arg) = 1.23f; + break; + } + case VT_DATE: + case VT_R8: + { + V_R8(&arg) = 1.23; + break; + } + case VT_CY: + { + VarCyFromI4(123, &V_CY(&arg)); + break; + } + case VT_DECIMAL: + { + VarDecFromI4(123, &V_DECIMAL(&arg)); + break; + } + default: + { + V_I1(&arg) = 123; + break; + } + } + + THROW_IF_FAILED(dispatchCoerceTesting->Invoke( + methodId, + IID_NULL, + lcid, + DISPATCH_METHOD, + ¶ms, + &result, + nullptr, + nullptr + )); + + THROW_FAIL_IF_FALSE(V_I4(&result) != 0); +} + +void Validate_ParamCoerce() +{ + HRESULT hr; + + CoreShimComActivation csact{ W("NETServer"), W("DispatchCoerceTesting") }; + + ComSmartPtr dispatchCoerceTesting; + THROW_IF_FAILED(::CoCreateInstance(CLSID_DispatchCoerceTesting, nullptr, CLSCTX_INPROC, IID_IDispatchCoerceTesting, (void**)&dispatchCoerceTesting)); + + LPOLESTR numericMethodName = (LPOLESTR)W("ManagedArgument"); + LCID lcid = MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT); + DISPID methodId; + + ::wprintf(W("Invoke %s\n"), numericMethodName); + THROW_IF_FAILED(dispatchCoerceTesting->GetIDsOfNames( + IID_NULL, + &numericMethodName, + 1, + lcid, + &methodId)); + + ::wprintf(W("Validating VT_I2\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_I2, lcid, methodId); + ::wprintf(W("Validating VT_I4\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_I4, lcid, methodId); + ::wprintf(W("Validating VT_R4\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_R4, lcid, methodId); + ::wprintf(W("Validating VT_R8\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_R8, lcid, methodId); + ::wprintf(W("Validating VT_CY\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_CY, lcid, methodId); + ::wprintf(W("Validating VT_DATE\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_DATE, lcid, methodId); + ::wprintf(W("Validating VT_BSTR\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_BSTR, lcid, methodId); + ::wprintf(W("Validating VT_ERROR\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_ERROR, lcid, methodId); + ::wprintf(W("Validating VT_BOOL\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_BOOL, lcid, methodId); + ::wprintf(W("Validating VT_DECIMAL\n")); + Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_DECIMAL, lcid, methodId); +} diff --git a/src/tests/Interop/COM/NativeClients/Dispatch/CoreShim.X.manifest b/src/tests/Interop/COM/NativeClients/Dispatch/CoreShim.X.manifest index 0e635e03c3ee0d..94105dbcbf72fb 100644 --- a/src/tests/Interop/COM/NativeClients/Dispatch/CoreShim.X.manifest +++ b/src/tests/Interop/COM/NativeClients/Dispatch/CoreShim.X.manifest @@ -11,6 +11,11 @@ + + + diff --git a/src/tests/Interop/COM/NativeServer/COMNativeServer.X.manifest b/src/tests/Interop/COM/NativeServer/COMNativeServer.X.manifest index 9f688bc8e22bab..12ac7bd541cdeb 100644 --- a/src/tests/Interop/COM/NativeServer/COMNativeServer.X.manifest +++ b/src/tests/Interop/COM/NativeServer/COMNativeServer.X.manifest @@ -42,6 +42,11 @@ clsid="{4DBD9B61-E372-499F-84DE-EFC70AA8A009}" threadingModel="Both" /> + + + cArgs)); + + if (pVarResult == nullptr) + return E_POINTER; + + VARENUM currType; + VARIANTARG *currArg; + size_t argIdx = expectedArgCount - 1; + + // Extract args + { + currType = VT_I2; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + args[0] = &currArg->iVal; + } + + VARENUM resultType = (VARENUM)*args[0]; + VariantInit(pVarResult); + V_VT(pVarResult) = resultType & 0x7FFF; + + switch ((uint16_t)resultType) + { + case VT_BSTR: + { + BSTR str = ::SysAllocString(L"123"); + V_BSTR(pVarResult) = str; + break; + } + case VT_R4: + { + V_R4(pVarResult) = 1.23f; + break; + } + case VT_DATE: + case VT_R8: + { + V_R8(pVarResult) = 1.23; + break; + } + case VT_CY: + { + VarCyFromI4(123, &V_CY(pVarResult)); + break; + } + case VT_DECIMAL: + { + VarDecFromI4(123, &V_DECIMAL(pVarResult)); + break; + } + case ((VT_ERROR | 0x8000)): + { + V_I4(pVarResult) = DISP_E_PARAMNOTFOUND; + break; + } + case VT_UNKNOWN: + { + V_UNKNOWN(pVarResult) = static_cast(this); + break; + } + default: + { + V_I1(pVarResult) = 123; + break; + } + } + + return S_OK; + } + + HRESULT ManagedArgument_Dispatch(_In_ DISPPARAMS *pDispParams, _Inout_ VARIANT *pVarResult) + { + HRESULT hr; + + int *args[1]; + size_t expectedArgCount = 1; + RETURN_IF_FAILED(VerifyValues(uint32_t(expectedArgCount), pDispParams->cArgs)); + + if (pVarResult == nullptr) + return E_POINTER; + + VARENUM currType; + VARIANTARG *currArg; + size_t argIdx = expectedArgCount - 1; + + // Extract args + { + currType = VT_I4; + currArg = NextArg(pDispParams->rgvarg, argIdx); + RETURN_IF_FAILED(VerifyValues(VARENUM(currType), VARENUM(currArg->vt))); + args[0] = &currArg->intVal; + } + + V_VT(pVarResult) = VT_I2; + V_I2(pVarResult) = *args[0]; + return S_OK; + } + + HRESULT ReturnToManaged_Missing_Dispatch(_In_ DISPPARAMS *pDispParams, _Inout_ VARIANT *pVarResult) + { + HRESULT hr; + + size_t expectedArgCount = 0; + RETURN_IF_FAILED(VerifyValues(uint32_t(expectedArgCount), pDispParams->cArgs)); + + if (pVarResult == nullptr) + return E_POINTER; + + V_VT(pVarResult) = VT_I4; + V_I4(pVarResult) = 1234; + return S_OK; + } + + HRESULT ReturnToManaged_DBNull_Dispatch(_In_ DISPPARAMS *pDispParams, _Inout_ VARIANT *pVarResult) + { + HRESULT hr; + + size_t expectedArgCount = 0; + RETURN_IF_FAILED(VerifyValues(uint32_t(expectedArgCount), pDispParams->cArgs)); + + if (pVarResult == nullptr) + return E_POINTER; + + V_VT(pVarResult) = VT_I4; + V_I4(pVarResult) = 1234; + return S_OK; + } + + HRESULT BoolToString_Dispatch(_In_ DISPPARAMS *pDispParams, _Inout_ VARIANT *pVarResult) + { + HRESULT hr; + + size_t expectedArgCount = 0; + RETURN_IF_FAILED(VerifyValues(uint32_t(expectedArgCount), pDispParams->cArgs)); + + if (pVarResult == nullptr) + return E_POINTER; + + V_VT(pVarResult) = VT_BOOL; + V_BOOL(pVarResult) = VARIANT_TRUE; + return S_OK; + } + +public: // IUnknown + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) + { + return DoQueryInterface(riid, ppvObject, static_cast(this), static_cast(this)); + } + + DEFINE_REF_COUNTING(); +}; + +const WCHAR * const DispatchCoerceTesting::Names[] = +{ + W("__RESERVED__"), + W("ReturnToManaged"), + W("ManagedArgument"), + W("ReturnToManaged_Missing"), + W("ReturnToManaged_DBNull"), + W("BoolToString") +}; + +const int DispatchCoerceTesting::NamesCount = ARRAY_SIZE(DispatchCoerceTesting::Names); diff --git a/src/tests/Interop/COM/NativeServer/Servers.cpp b/src/tests/Interop/COM/NativeServer/Servers.cpp index 05f26be8d4741d..ebe4f9df5acde2 100644 --- a/src/tests/Interop/COM/NativeServer/Servers.cpp +++ b/src/tests/Interop/COM/NativeServer/Servers.cpp @@ -166,6 +166,7 @@ STDAPI DllRegisterServer(void) RETURN_IF_FAILED(RegisterClsid(__uuidof(ErrorMarshalTesting), L"Both")); RETURN_IF_FAILED(RegisterClsid(__uuidof(DispatchTesting), L"Both")); RETURN_IF_FAILED(RegisterClsid(__uuidof(EventTesting), L"Both")); + RETURN_IF_FAILED(RegisterClsid(__uuidof(DispatchCoerceTesting), L"Both")); RETURN_IF_FAILED(RegisterClsid(__uuidof(AggregationTesting), L"Both")); RETURN_IF_FAILED(RegisterClsid(__uuidof(ColorTesting), L"Both")); RETURN_IF_FAILED(RegisterClsid(__uuidof(InspectableTesting), L"Both")); @@ -185,6 +186,7 @@ STDAPI DllUnregisterServer(void) RETURN_IF_FAILED(RemoveClsid(__uuidof(ErrorMarshalTesting))); RETURN_IF_FAILED(RemoveClsid(__uuidof(DispatchTesting))); RETURN_IF_FAILED(RemoveClsid(__uuidof(EventTesting))); + RETURN_IF_FAILED(RemoveClsid(__uuidof(DispatchCoerceTesting))); RETURN_IF_FAILED(RemoveClsid(__uuidof(AggregationTesting))); RETURN_IF_FAILED(RemoveClsid(__uuidof(ColorTesting))); RETURN_IF_FAILED(RemoveClsid(__uuidof(InspectableTesting))); @@ -216,6 +218,9 @@ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID FA if (rclsid == __uuidof(EventTesting)) return ClassFactoryBasic::Create(riid, ppv); + if (rclsid == __uuidof(DispatchCoerceTesting)) + return ClassFactoryBasic::Create(riid, ppv); + if (rclsid == __uuidof(AggregationTesting)) return ClassFactoryAggregate::Create(riid, ppv); diff --git a/src/tests/Interop/COM/NativeServer/Servers.h b/src/tests/Interop/COM/NativeServer/Servers.h index c87288d2535b1a..44e5070a25a6b2 100644 --- a/src/tests/Interop/COM/NativeServer/Servers.h +++ b/src/tests/Interop/COM/NativeServer/Servers.h @@ -16,6 +16,7 @@ class DECLSPEC_UUID("CCFF894B-A27C-45E0-9B30-6C88D722E843") MiscTypesTesting; class DECLSPEC_UUID("71CF5C45-106C-4B32-B418-43A463C6041F") ErrorMarshalTesting; class DECLSPEC_UUID("0F8ACD0C-ECE0-4F2A-BD1B-6BFCA93A0726") DispatchTesting; class DECLSPEC_UUID("4DBD9B61-E372-499F-84DE-EFC70AA8A009") EventTesting; +class DECLSPEC_UUID("661F9962-3477-416B-BE40-4CBA3190A562") DispatchCoerceTesting; class DECLSPEC_UUID("4CEFE36D-F377-4B6E-8C34-819A8BB9CB04") AggregationTesting; class DECLSPEC_UUID("C222F472-DA5A-4FC6-9321-92F4F7053A65") ColorTesting; class DECLSPEC_UUID("66DB7882-E2B0-471D-92C7-B2B52A0EA535") LicenseTesting; @@ -30,6 +31,7 @@ class DECLSPEC_UUID("4F54231D-9E11-4C0B-8E0B-2EBD8B0E5811") TrackMyLifetimeTesti #define CLSID_ErrorMarshalTesting __uuidof(ErrorMarshalTesting) #define CLSID_DispatchTesting __uuidof(DispatchTesting) #define CLSID_EventTesting __uuidof(EventTesting) +#define CLSID_DispatchCoerceTesting __uuidof(DispatchCoerceTesting) #define CLSID_AggregationTesting __uuidof(AggregationTesting) #define CLSID_ColorTesting __uuidof(ColorTesting) #define CLSID_LicenseTesting __uuidof(LicenseTesting) @@ -45,6 +47,7 @@ class DECLSPEC_UUID("4F54231D-9E11-4C0B-8E0B-2EBD8B0E5811") TrackMyLifetimeTesti #define IID_IDispatchTesting __uuidof(IDispatchTesting) #define IID_TestingEvents __uuidof(TestingEvents) #define IID_IEventTesting __uuidof(IEventTesting) +#define IID_IDispatchCoerceTesting __uuidof(IDispatchCoerceTesting) #define IID_IAggregationTesting __uuidof(IAggregationTesting) #define IID_IColorTesting __uuidof(IColorTesting) #define IID_ILicenseTesting __uuidof(ILicenseTesting) @@ -89,6 +92,7 @@ struct CoreShimComActivation #include "ErrorMarshalTesting.h" #include "DispatchTesting.h" #include "EventTesting.h" + #include "DispatchCoerceTesting.h" #include "AggregationTesting.h" #include "ColorTesting.h" #include "LicenseTesting.h" diff --git a/src/tests/Interop/COM/ServerContracts/Server.CoClasses.cs b/src/tests/Interop/COM/ServerContracts/Server.CoClasses.cs index 2479e6cd6f083a..f2c44e4cab4b85 100644 --- a/src/tests/Interop/COM/ServerContracts/Server.CoClasses.cs +++ b/src/tests/Interop/COM/ServerContracts/Server.CoClasses.cs @@ -123,6 +123,25 @@ internal class DispatchTestingClass { } + /// + /// Managed definition of CoClass + /// + [ComImport] + [CoClass(typeof(DispatchCoerceTestingClass))] + [Guid("B630A508-4DA5-4C14-A7AB-618AD66B2EBF")] + internal interface DispatchCoerceTesting : Server.Contract.IDispatchCoerceTesting + { + } + + /// + /// Managed activation for CoClass + /// + [ComImport] + [Guid(Server.Contract.Guids.DispatchCoerceTesting)] + internal class DispatchCoerceTestingClass + { + } + /// /// Managed definition of CoClass /// diff --git a/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs b/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs index dd0f71634e2bdc..27ee5b3bfc3db4 100644 --- a/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs +++ b/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs @@ -319,6 +319,22 @@ public interface TestingEvents void OnEvent([MarshalAs(UnmanagedType.BStr)] string msg); }; + [ComVisible(true)] + [Guid("B630A508-4DA5-4C14-A7AB-618AD66B2EBF")] + [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] + public interface IDispatchCoerceTesting + { + int ReturnToManaged(short vt); + + int ManagedArgument(int arg); + + System.Reflection.Missing ReturnToManaged_Missing(); + + DBNull ReturnToManaged_DBNull(); + + string BoolToString(); + } + [ComVisible(true)] [Guid("98cc27f0-d521-4f79-8b63-e980e3a92974")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] diff --git a/src/tests/Interop/COM/ServerContracts/Server.Contracts.h b/src/tests/Interop/COM/ServerContracts/Server.Contracts.h index d2c26884589efa..719659b7ed905e 100644 --- a/src/tests/Interop/COM/ServerContracts/Server.Contracts.h +++ b/src/tests/Interop/COM/ServerContracts/Server.Contracts.h @@ -452,6 +452,12 @@ TestingEvents : IDispatch // void OnEvent(_In_z_ BSTR t); }; +struct __declspec(uuid("b630a508-4da5-4c14-a7ab-618ad66b2ebf")) +IDispatchCoerceTesting : IDispatch +{ + // Methods should only be invoked via IDispatch +}; + struct __declspec(uuid("98cc27f0-d521-4f79-8b63-e980e3a92974")) IAggregationTesting : IUnknown { diff --git a/src/tests/Interop/COM/ServerContracts/ServerGuids.cs b/src/tests/Interop/COM/ServerContracts/ServerGuids.cs index 8b0c65a3ce1532..6c6b6569b634a7 100644 --- a/src/tests/Interop/COM/ServerContracts/ServerGuids.cs +++ b/src/tests/Interop/COM/ServerContracts/ServerGuids.cs @@ -15,6 +15,7 @@ internal sealed class Guids public const string ErrorMarshalTesting = "71CF5C45-106C-4B32-B418-43A463C6041F"; public const string DispatchTesting = "0F8ACD0C-ECE0-4F2A-BD1B-6BFCA93A0726"; public const string EventTesting = "4DBD9B61-E372-499F-84DE-EFC70AA8A009"; + public const string DispatchCoerceTesting = "661F9962-3477-416B-BE40-4CBA3190A562"; public const string AggregationTesting = "4CEFE36D-F377-4B6E-8C34-819A8BB9CB04"; public const string ColorTesting = "C222F472-DA5A-4FC6-9321-92F4F7053A65"; public const string LicenseTesting = "66DB7882-E2B0-471D-92C7-B2B52A0EA535"; diff --git a/src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj b/src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj index 83624287a592ec..b6a0995379d76a 100644 --- a/src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj +++ b/src/tests/JIT/Directed/tailcall/mutual_recursion.fsproj @@ -2,6 +2,9 @@ true + + + true True diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 125c187bdd2d4e..faf6d504ece6bc 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -1443,6 +1443,8 @@ public static float CompareTest(float left, float right) public static short AddAcrossWidening(sbyte[] op1) => Reduce(AddWidening, op1); + public static long AddAcrossWideningLong(sbyte[] op1) => Reduce(AddWidening, op1); + public static short AddPairwiseWidening(sbyte[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); public static short AddPairwiseWideningAndAdd(short[] op1, sbyte[] op2, int i) => (short)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); @@ -1469,6 +1471,8 @@ private static sbyte HighNarrowing(short op1, bool round) public static short AddWidening(short op1, sbyte op2) => (short)(op1 + op2); + public static long AddWidening(long op1, sbyte op2) => (long)(op1 + (long)op2); + public static short AddWideningUpper(sbyte[] op1, sbyte[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); public static short AddWideningUpper(short[] op1, sbyte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); @@ -1533,6 +1537,18 @@ private static short Reduce(Func reduceOp, sbyte[] op1) return acc; } + private static long Reduce(Func reduceOp, sbyte[] op1) + { + long acc = op1[0]; + + for (int i = 1; i < op1.Length; i++) + { + acc = reduceOp(acc, op1[i]); + } + + return acc; + } + public static uint AbsoluteDifferenceWidening(short op1, short op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); public static uint AbsoluteDifferenceWideningUpper(short[] op1, short[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1543,6 +1559,8 @@ private static short Reduce(Func reduceOp, sbyte[] op1) public static int AddAcrossWidening(short[] op1) => Reduce(AddWidening, op1); + public static long AddAcrossWideningLong(short[] op1) => Reduce(AddWidening, op1); + public static int AddPairwiseWidening(short[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); public static int AddPairwiseWideningAndAdd(int[] op1, short[] op2, int i) => (int)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); @@ -1569,6 +1587,8 @@ private static short HighNarrowing(int op1, bool round) public static int AddWidening(int op1, short op2) => (int)(op1 + op2); + public static long AddWidening(long op1, short op2) => (long)(op1 + (long)op2); + public static int AddWideningUpper(short[] op1, short[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); public static int AddWideningUpper(int[] op1, short[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); @@ -1633,6 +1653,18 @@ private static int Reduce(Func reduceOp, short[] op1) return acc; } + private static long Reduce(Func reduceOp, short[] op1) + { + long acc = op1[0]; + + for (int i = 1; i < op1.Length; i++) + { + acc = reduceOp(acc, op1[i]); + } + + return acc; + } + public static ulong AbsoluteDifferenceWidening(int op1, int op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); public static ulong AbsoluteDifferenceWideningUpper(int[] op1, int[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1701,6 +1733,29 @@ private static int HighNarrowing(long op1, bool round) public static long MultiplyWideningUpperAndSubtract(long[] op1, int[] op2, int[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static T SignExtend(T n, int numBits, bool zeroExtend) where T : struct, IComparable, IConvertible + { + // Get the underlying integer value + dynamic value = Convert.ChangeType(n, typeof(long)); + + // Mask to extract the lowest numBits + long mask = (1L << numBits) - 1; + long lowestBits = value & mask; + + // Sign extension for signed integers + long signBitMask = 1L << (numBits - 1); + if (!zeroExtend && ((lowestBits & signBitMask) != 0)) + { + // If sign bit is set, it's a negative number + return (T)Convert.ChangeType(-((~lowestBits & mask) + 1), typeof(T)); + } + else + { + // If sign bit is not set, it's a positive number + return (T)Convert.ChangeType(lowestBits, typeof(T)); + } + } + public static int SubtractHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: false); public static long SubtractHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); @@ -1743,6 +1798,8 @@ private static long Reduce(Func reduceOp, int[] op1) public static ushort AddAcrossWidening(byte[] op1) => Reduce(AddWidening, op1); + public static ulong AddAcrossWideningULong(byte[] op1) => Reduce(AddWidening, op1); + public static ushort AddPairwiseWidening(byte[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); public static ushort AddPairwiseWideningAndAdd(ushort[] op1, byte[] op2, int i) => (ushort)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); @@ -1769,6 +1826,8 @@ private static byte HighNarrowing(ushort op1, bool round) public static ushort AddWidening(ushort op1, byte op2) => (ushort)(op1 + op2); + public static ulong AddWidening(ulong op1, byte op2) => (ulong)(op1 + (ulong)op2); + public static ushort AddWideningUpper(byte[] op1, byte[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); public static ushort AddWideningUpper(ushort[] op1, byte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); @@ -1833,6 +1892,18 @@ private static ushort Reduce(Func reduceOp, byte[] op1) return acc; } + private static ulong Reduce(Func reduceOp, byte[] op1) + { + ulong acc = op1[0]; + + for (int i = 1; i < op1.Length; i++) + { + acc = reduceOp(acc, op1[i]); + } + + return acc; + } + public static uint AbsoluteDifferenceWidening(ushort op1, ushort op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); public static uint AbsoluteDifferenceWideningUpper(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1843,6 +1914,8 @@ private static ushort Reduce(Func reduceOp, byte[] op1) public static uint AddAcrossWidening(ushort[] op1) => Reduce(AddWidening, op1); + public static ulong AddAcrossWideningULong(ushort[] op1) => Reduce(AddWidening, op1); + public static uint AddPairwiseWidening(ushort[] op1, int i) => AddWidening(op1[2 * i], op1[2 * i + 1]); public static uint AddPairwiseWideningAndAdd(uint[] op1, ushort[] op2, int i) => (uint)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); @@ -1869,6 +1942,8 @@ private static ushort HighNarrowing(uint op1, bool round) public static uint AddWidening(uint op1, ushort op2) => (uint)(op1 + op2); + public static ulong AddWidening(ulong op1, ushort op2) => (ulong)(op1 + (ulong)op2); + public static uint AddWideningUpper(ushort[] op1, ushort[] op2, int i) => AddWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); public static uint AddWideningUpper(uint[] op1, ushort[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); @@ -1933,6 +2008,18 @@ private static uint Reduce(Func reduceOp, ushort[] op1) return acc; } + private static ulong Reduce(Func reduceOp, ushort[] op1) + { + ulong acc = op1[0]; + + for (int i = 1; i < op1.Length; i++) + { + acc = reduceOp(acc, op1[i]); + } + + return acc; + } + public static ulong AbsoluteDifferenceWidening(uint op1, uint op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); public static ulong AbsoluteDifferenceWideningUpper(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -2033,6 +2120,9 @@ private static ulong Reduce(Func reduceOp, uint[] op1) return acc; } + public static double AddWidening(double op1, float op2) => (double)(op1 + (double)op2); + + private static bool SignedSatQ(short val, out sbyte result) { bool saturated = false; @@ -5028,10 +5118,16 @@ private static double Pairwise(Func pairOp, double[] op1 public static sbyte AddAcross(sbyte[] op1) => Reduce(Add, op1); + public static sbyte AndAcross(sbyte[] op1) => Reduce(And, op1); + public static sbyte MaxAcross(sbyte[] op1) => Reduce(Max, op1); public static sbyte MinAcross(sbyte[] op1) => Reduce(Min, op1); + public static sbyte OrAcross(sbyte[] op1) => Reduce(Or, op1); + + public static sbyte XorAcross(sbyte[] op1) => Reduce(Xor, op1); + private static sbyte Reduce(Func reduceOp, sbyte[] op1) { sbyte acc = op1[0]; @@ -5046,10 +5142,16 @@ private static sbyte Reduce(Func reduceOp, sbyte[] op1) public static byte AddAcross(byte[] op1) => Reduce(Add, op1); + public static byte AndAcross(byte[] op1) => Reduce(And, op1); + public static byte MaxAcross(byte[] op1) => Reduce(Max, op1); public static byte MinAcross(byte[] op1) => Reduce(Min, op1); + public static byte OrAcross(byte[] op1) => Reduce(Or, op1); + + public static byte XorAcross(byte[] op1) => Reduce(Xor, op1); + private static byte Reduce(Func reduceOp, byte[] op1) { byte acc = op1[0]; @@ -5064,10 +5166,16 @@ private static byte Reduce(Func reduceOp, byte[] op1) public static short AddAcross(short[] op1) => Reduce(Add, op1); + public static short AndAcross(short[] op1) => Reduce(And, op1); + public static short MaxAcross(short[] op1) => Reduce(Max, op1); public static short MinAcross(short[] op1) => Reduce(Min, op1); + public static short OrAcross(short[] op1) => Reduce(Or, op1); + + public static short XorAcross(short[] op1) => Reduce(Xor, op1); + private static short Reduce(Func reduceOp, short[] op1) { short acc = op1[0]; @@ -5082,10 +5190,16 @@ private static short Reduce(Func reduceOp, short[] op1) public static ushort AddAcross(ushort[] op1) => Reduce(Add, op1); + public static ushort AndAcross(ushort[] op1) => Reduce(And, op1); + public static ushort MaxAcross(ushort[] op1) => Reduce(Max, op1); public static ushort MinAcross(ushort[] op1) => Reduce(Min, op1); + public static ushort OrAcross(ushort[] op1) => Reduce(Or, op1); + + public static ushort XorAcross(ushort[] op1) => Reduce(Xor, op1); + private static ushort Reduce(Func reduceOp, ushort[] op1) { ushort acc = op1[0]; @@ -5100,10 +5214,16 @@ private static ushort Reduce(Func reduceOp, ushort[] op1 public static int AddAcross(int[] op1) => Reduce(Add, op1); + public static int AndAcross(int[] op1) => Reduce(And, op1); + public static int MaxAcross(int[] op1) => Reduce(Max, op1); public static int MinAcross(int[] op1) => Reduce(Min, op1); + public static int OrAcross(int[] op1) => Reduce(Or, op1); + + public static int XorAcross(int[] op1) => Reduce(Xor, op1); + private static int Reduce(Func reduceOp, int[] op1) { int acc = op1[0]; @@ -5118,10 +5238,16 @@ private static int Reduce(Func reduceOp, int[] op1) public static uint AddAcross(uint[] op1) => Reduce(Add, op1); + public static uint AndAcross(uint[] op1) => Reduce(And, op1); + public static uint MaxAcross(uint[] op1) => Reduce(Max, op1); public static uint MinAcross(uint[] op1) => Reduce(Min, op1); + public static uint OrAcross(uint[] op1) => Reduce(Or, op1); + + public static uint XorAcross(uint[] op1) => Reduce(Xor, op1); + private static uint Reduce(Func reduceOp, uint[] op1) { uint acc = op1[0]; @@ -5134,6 +5260,54 @@ private static uint Reduce(Func reduceOp, uint[] op1) return acc; } + public static long AddAcross(long[] op1) => Reduce(Add, op1); + + public static long AndAcross(long[] op1) => Reduce(And, op1); + + public static long MaxAcross(long[] op1) => Reduce(Max, op1); + + public static long MinAcross(long[] op1) => Reduce(Min, op1); + + public static long OrAcross(long[] op1) => Reduce(Or, op1); + + public static long XorAcross(long[] op1) => Reduce(Xor, op1); + + private static long Reduce(Func reduceOp, long[] op1) + { + long acc = op1[0]; + + for (int i = 1; i < op1.Length; i++) + { + acc = reduceOp(acc, op1[i]); + } + + return acc; + } + + public static ulong AddAcross(ulong[] op1) => Reduce(Add, op1); + + public static ulong AndAcross(ulong[] op1) => Reduce(And, op1); + + public static ulong MaxAcross(ulong[] op1) => Reduce(Max, op1); + + public static ulong MinAcross(ulong[] op1) => Reduce(Min, op1); + + public static ulong OrAcross(ulong[] op1) => Reduce(Or, op1); + + public static ulong XorAcross(ulong[] op1) => Reduce(Xor, op1); + + private static ulong Reduce(Func reduceOp, ulong[] op1) + { + ulong acc = op1[0]; + + for (int i = 1; i < op1.Length; i++) + { + acc = reduceOp(acc, op1[i]); + } + + return acc; + } + public static float AddAcross(float[] op1) => Reduce(Add, op1); public static float MaxAcross(float[] op1) => Reduce(Max, op1); @@ -5152,6 +5326,31 @@ private static float Reduce(Func reduceOp, float[] op1) return acc; } + public static float AddAcrossRecursivePairwise(float[] op1) => ReduceRecursivePairwise(Add, op1); + + private static float ReduceRecursivePairwise(Func reduceOp, float[] op1) + { + if (op1.Length == 2) + { + return reduceOp(op1[0], op1[1]); + } + + if (op1.Length % 2 != 0) + { + return float.NaN; + } + + float[] l = new float[op1.Length / 2]; + Array.Copy(op1, 0, l, 0, (op1.Length / 2)); + float l_reduced = ReduceRecursivePairwise(reduceOp, l); + + float[] r = new float[op1.Length / 2]; + Array.Copy(op1, (op1.Length / 2), r, 0, (op1.Length / 2)); + float r_reduced = ReduceRecursivePairwise(reduceOp, r); + + return reduceOp(l_reduced, r_reduced); + } + public static double AddAcross(double[] op1) => Reduce(Add, op1); public static double MaxAcross(double[] op1) => Reduce(Max, op1); @@ -5170,6 +5369,31 @@ private static double Reduce(Func reduceOp, double[] op1 return acc; } + public static double AddAcrossRecursivePairwise(double[] op1) => ReduceRecursivePairwise(Add, op1); + + private static double ReduceRecursivePairwise(Func reduceOp, double[] op1) + { + if (op1.Length == 2) + { + return reduceOp(op1[0], op1[1]); + } + + if (op1.Length % 2 != 0) + { + return double.NaN; + } + + double[] l = new double[op1.Length / 2]; + Array.Copy(op1, 0, l, 0, (op1.Length / 2)); + double l_reduced = ReduceRecursivePairwise(reduceOp, l); + + double[] r = new double[op1.Length / 2]; + Array.Copy(op1, (op1.Length / 2), r, 0, (op1.Length / 2)); + double r_reduced = ReduceRecursivePairwise(reduceOp, r); + + return reduceOp(l_reduced, r_reduced); + } + public static float MaxNumberAcross(float[] op1) => Reduce(MaxNumber, op1); public static float MinNumberAcross(float[] op1) => Reduce(MinNumber, op1); @@ -5986,5 +6210,45 @@ public static int DotProduct(int op1, sbyte[] op2, int s, sbyte[] op3, int t) return result; } + + public static int WhileLessThanMask(int op1, int op2) + { + return (op1 < op2) ? 1 : 0; + } + + public static uint WhileLessThanMask(uint op1, uint op2) + { + return (uint)((op1 < op2) ? 1 : 0); + } + + public static long WhileLessThanMask(long op1, long op2) + { + return (op1 < op2) ? 1 : 0; + } + + public static ulong WhileLessThanMask(ulong op1, ulong op2) + { + return (ulong)((op1 < op2) ? 1 : 0); + } + + public static int WhileLessThanOrEqualMask(int op1, int op2) + { + return (op1 <= op2) ? 1 : 0; + } + + public static uint WhileLessThanOrEqualMask(uint op1, uint op2) + { + return (uint)((op1 <= op2) ? 1 : 0); + } + + public static long WhileLessThanOrEqualMask(long op1, long op2) + { + return (op1 <= op2) ? 1 : 0; + } + + public static ulong WhileLessThanOrEqualMask(ulong op1, ulong op2) + { + return (ulong)((op1 <= op2) ? 1 : 0); + } } } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarBinOpRetVecTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarBinOpRetVecTest.template new file mode 100644 index 00000000000000..a2434756fae862 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarBinOpRetVecTest.template @@ -0,0 +1,216 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new ScalarBinaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class ScalarBinaryOpTest__{TestName} + { + private struct TestStruct + { + public {Op1BaseType} _fld1; + public {Op2BaseType} _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + testStruct._fld1 = {NextValueOp1}; + testStruct._fld2 = {NextValueOp2}; + + return testStruct; + } + + public void RunStructFldScenario(ScalarBinaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2); + testClass.ValidateResult(_fld1, _fld2, result); + } + } + + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType} _data1; + private static {Op2BaseType} _data2; + + private {Op1BaseType} _fld1; + private {Op2BaseType} _fld2; + + public ScalarBinaryOpTest__{TestName}() + { + Succeeded = true; + + _fld1 = {NextValueOp1}; + _fld2 = {NextValueOp2}; + + _data1 = {NextValueOp1}; + _data2 = {NextValueOp2}; + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data1)), + Unsafe.ReadUnaligned<{Op2BaseType}>(ref Unsafe.As<{Op2BaseType}, byte>(ref _data2)) + ); + + ValidateResult(_data1, _data2, result); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}), typeof({Op2BaseType}) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data1)), + Unsafe.ReadUnaligned<{Op2BaseType}>(ref Unsafe.As<{Op2BaseType}, byte>(ref _data2)) + }); + + ValidateResult(_data1, _data2, ({RetVectorType}<{RetBaseType}>)result); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data1 = Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data1)); + var data2 = Unsafe.ReadUnaligned<{Op2BaseType}>(ref Unsafe.As<{Op2BaseType}, byte>(ref _data2)); + var result = {Isa}.{Method}(data1, data2); + + ValidateResult(data1, data2, result); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2); + ValidateResult(_fld1, _fld2, result); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2); + + ValidateResult(test._fld1, test._fld2, result); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1BaseType} left, {Op2BaseType} right, {RetVectorType}<{RetBaseType}> result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (int i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetVectorType}<{RetBaseType}>>({Op1BaseType}, {Op2BaseType}): {Method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: {left}"); + TestLibrary.TestFramework.LogInformation($" right: {right}"); + TestLibrary.TestFramework.LogInformation($" result: {result}"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarUnOpTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarUnOpTest.template index c6fe68908e5627..f057ad4a818680 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarUnOpTest.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/ScalarUnOpTest.template @@ -9,6 +9,7 @@ ******************************************************************************/ using System; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveConditionalSelect.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveConditionalSelect.template new file mode 100644 index 00000000000000..963fa1713eec3b --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveConditionalSelect.template @@ -0,0 +1,362 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using System.Numerics; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new TernaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class TernaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] inArray3; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle inHandle3; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op3BaseType}[] inArray3, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfinArray2: {sizeOfinArray2}, sizeOfinArray3: {sizeOfinArray3}, sizeOfoutArray: {sizeOfoutArray}"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.inArray3 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + inHandle3.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + public {Op3VectorType}<{Op3BaseType}> _fld3; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario(TernaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2, _fld3); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + private {Op3VectorType}<{Op3BaseType}> _fld3; + + private DataTable _dataTable; + + public TernaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + _dataTable = new DataTable(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + //TODO-SVE: Once register allocation exists for predicates, move loadMask into DataTable + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(loadMask, ({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {LoadIsa}.Load{Op3VectorType}(loadMask, ({Op3BaseType}*)(_dataTable.inArray3Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof({Op3VectorType}<{Op3BaseType}>) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var op3 = Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr); + var result = {Isa}.{Method}(op1, op2, op3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2, _fld3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2, test._fld3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op3VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, inArray3, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, inArray3, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if ({ValidateIterResult}) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>, {Op3VectorType}<{Op3BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadMaskedUnOpTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadMaskedUnOpTest.template index 09aaf2f442e136..d5a62e5cda1cf6 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadMaskedUnOpTest.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/SveLoadMaskedUnOpTest.template @@ -64,9 +64,9 @@ namespace JIT.HardwareIntrinsics.Arm { int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op2BaseType}>(); int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); - if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) { - throw new ArgumentException("Invalid value of alignment"); + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); } this.inArray1 = new byte[alignment * 2]; diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_BinaryOp_SveTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_BinaryOp_SveTestTemplate.template new file mode 100644 index 00000000000000..9e2c2c7516c293 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_BinaryOp_SveTestTemplate.template @@ -0,0 +1,327 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new {TemplateName}BinaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class {TemplateName}BinaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario({TemplateName}BinaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + + private DataTable _dataTable; + + public {TemplateName}BinaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + Vector<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(loadMask, ({Op2BaseType}*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var result = {Isa}.{Method}(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpTestTemplate.template new file mode 100644 index 00000000000000..bd15acab428a09 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpTestTemplate.template @@ -0,0 +1,435 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new {TemplateName}BinaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + // Validates executing the test inside conditional, with op1 as falseValue + test.ConditionalSelect_Op1(); + + // Validates executing the test inside conditional, with op2 as falseValue + test.ConditionalSelect_Op2(); + + // Validates executing the test inside conditional, with op3 as falseValue + test.ConditionalSelect_FalseOp(); + + // Validates executing the test inside conditional, with op3 as zero + test.ConditionalSelect_ZeroOp(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class {TemplateName}BinaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfinArray2: {sizeOfinArray2}, sizeOfoutArray: {sizeOfoutArray}"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario({TemplateName}BinaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _mask; + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + private {Op2VectorType}<{Op2BaseType}> _falseFld; + + private DataTable _dataTable; + + public {TemplateName}BinaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(loadMask, ({Op2BaseType}*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var result = {Isa}.{Method}(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void ConditionalSelect_Op1() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask"); + ConditionalSelectScenario(_mask, _fld1, _fld2, _fld1); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld1); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld1); + } + + public void ConditionalSelect_Op2() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask"); + ConditionalSelectScenario(_mask, _fld1, _fld2, _fld2); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld2); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld2); + } + + public void ConditionalSelect_FalseOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask"); + ConditionalSelectScenario(_mask, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _falseFld); + } + + public void ConditionalSelect_ZeroOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask"); + ConditionalSelectScenario(_mask, _fld1, _fld2, {Op1VectorType}<{Op1BaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, {Op1VectorType}<{Op1BaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, {Op1VectorType}<{Op1BaseType}>.Zero); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> falseOp) + { + var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2), falseOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult(mask, op1, op2, falseOp, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateConditionalSelectResult({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op1VectorType}<{Op1BaseType}> rightOp, {Op1VectorType}<{Op1BaseType}> falseOp, void* output, [CallerMemberName] string method = "") + { + {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] right = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] falseVal = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref right[0]), rightOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + bool succeeded = true; + + {TemplateValidationLogicForCndSel} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template new file mode 100644 index 00000000000000..782f77de3520ea --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template @@ -0,0 +1,302 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new {TemplateName}UnaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class {TemplateName}UnaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario({TemplateName}UnaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + + private DataTable _dataTable; + + public {TemplateName}UnaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var result = {Isa}.{Method}(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpTestTemplate.template new file mode 100644 index 00000000000000..119cc5d88cb6fa --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveUnaryOpTestTemplate.template @@ -0,0 +1,391 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new {TemplateName}UnaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + // Validates executing the test inside conditional, with op1 as falseValue + test.ConditionalSelect_Op1(); + + // Validates executing the test inside conditional, with op3 as falseValue + test.ConditionalSelect_FalseOp(); + + // Validates executing the test inside conditional, with op3 as zero + test.ConditionalSelect_ZeroOp(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class {TemplateName}UnaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario({TemplateName}UnaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _mask; + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op1VectorType}<{Op1BaseType}> _falseFld; + + private DataTable _dataTable; + + public {TemplateName}UnaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var result = {Isa}.{Method}(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void ConditionalSelect_Op1() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask"); + ConditionalSelectScenario(_mask, _fld1, _fld1); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld1); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld1); + } + + public void ConditionalSelect_FalseOp() + { + TestLibrary.TestFramework.BeginScenario(nameof(ConditionalSelect_FalseOp)); + ConditionalSelectScenario(_mask, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _falseFld); + } + + public void ConditionalSelect_ZeroOp() + { + TestLibrary.TestFramework.BeginScenario(nameof(ConditionalSelect_ZeroOp)); + ConditionalSelectScenario(_mask, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all"); + ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, {Op1VectorType}<{Op1BaseType}>.Zero); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> falseOp) + { + var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1), falseOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult(mask, op1, falseOp, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateConditionalSelectResult({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {Op1VectorType}<{Op1BaseType}> falseOp, void* output, [CallerMemberName] string method = "") + { + {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] left = new {Op1BaseType}[Op1ElementCount]; + {Op1BaseType}[] falseVal = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref left[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + bool succeeded = true; + + {TemplateValidationLogicForCndSel} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_101034/Runtime_101034.cs b/src/tests/JIT/Regression/JitBlue/Runtime_101034/Runtime_101034.cs new file mode 100644 index 00000000000000..751dceda19632c --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_101034/Runtime_101034.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public static unsafe class Runtime_101034 +{ + [Fact] + public static void Test() + { + StructWithTwoShorts x = new() { ShortOne = -1, ShortTwo = -1 }; + StructWithThreeBytes y = default; + Problem(&x, &y); + Assert.True(y.ByteThree == 0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static StructWithTwoShorts Problem(StructWithTwoShorts* s, StructWithThreeBytes* p) + { + StructWithTwoShorts y = *s; + + int z = 255; + ForceILLocal(&z); + if (z == 255) + { + y.ShortOne = 255; + } + else + { + y.ShortOne = 1; + } + + if (p != null) + { + int x = 255; + *p = Unsafe.As(ref x); + } + + return y; + } + + private static void ForceILLocal(void* x) { } + + struct StructWithTwoShorts + { + public short ShortOne; + public short ShortTwo; + } + + struct StructWithThreeBytes + { + public byte ByteOne; + public byte ByteTwo; + public byte ByteThree; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_101034/Runtime_101034.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_101034/Runtime_101034.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_101034/Runtime_101034.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_72845/Runtime_72845.fsproj b/src/tests/JIT/Regression/JitBlue/Runtime_72845/Runtime_72845.fsproj index 4ecbaba4ff4301..302b1099bdf8dc 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_72845/Runtime_72845.fsproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_72845/Runtime_72845.fsproj @@ -7,6 +7,9 @@ True $(NetCoreAppToolCurrent) True + + + true diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_82291/Runtime_82291.cs b/src/tests/JIT/Regression/JitBlue/Runtime_82291/Runtime_82291.cs new file mode 100644 index 00000000000000..6432672d45ca28 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_82291/Runtime_82291.cs @@ -0,0 +1,42 @@ +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_82291 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static bool GetValueOrNull() + { + if (default(T) != null) + return true; + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool GetValueOrNullSlow() + { + if (default(T) != null) + return false; + + return false; + } + + + [MethodImpl(MethodImplOptions.NoInlining)] + static void GetValueOrNullSlow2() + { + if (default(T) != null) + return; + + return; + } + + [Fact] + public static void Test() + { + GetValueOrNull(); + GetValueOrNullSlow(); + GetValueOrNullSlow2(); + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_82291/Runtime_82291.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_82291/Runtime_82291.csproj new file mode 100644 index 00000000000000..197767e2c4e249 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_82291/Runtime_82291.csproj @@ -0,0 +1,5 @@ + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.cs b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.cs new file mode 100644 index 00000000000000..85aa6e62655d2f --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Xunit; + +public static class Runtime_94467 +{ + public interface ITypeChecker + { + static abstract bool Test(T value); + } + + public interface IHandler + { + bool Test(T value); + } + + public struct TypeChecker : ITypeChecker + { + public static bool Test(T value) => true; + } + + public class Handler : IHandler where TChecker : ITypeChecker + { + public bool Test(T value) => TChecker.Test(value); + } + + public static IHandler GetHandler() => new Handler(); + + [Fact] + public static int Test() + { + try { + var handler = GetHandler(); + if (handler.Test(true) && handler.Test(true)) + return 100; + else + return 101; + } catch (Exception) { + return -1; + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_94467/Runtime_94467.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file diff --git a/src/tests/JIT/opt/Vectorization/UnrollEqualsStartsWith.csproj b/src/tests/JIT/opt/Vectorization/UnrollEqualsStartsWith.csproj index c9327d09cb4dc3..87fba405d81ec4 100644 --- a/src/tests/JIT/opt/Vectorization/UnrollEqualsStartsWith.csproj +++ b/src/tests/JIT/opt/Vectorization/UnrollEqualsStartsWith.csproj @@ -1,6 +1,10 @@ True + + true + + true diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il index 2f3f65d1a19952..8480a5cf452079 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il @@ -149,6 +149,41 @@ ret } + .method public hidebysig + instance bool BoxBranchToOther(!T) cil managed + { + ldarg.1 + // Begin sequence + box !!U + brfalse.s NEXT_1 + // End sequence + NEXT_1: + + ldarg.1 + // Begin sequence + box !!U + brfalse NEXT_2 + // End sequence + NEXT_2: + + ldarg.1 + // Begin sequence + box !!U + brtrue.s NEXT_3 + // End sequence + NEXT_3: + + ldarg.1 + // Begin sequence + box !!U + brtrue NEXT_4 + // End sequence + NEXT_4: + + ldc.i4.1 + ret + } + .method public hidebysig instance bool BoxBranch_WithSideEffects(!T&) cil managed { @@ -284,6 +319,26 @@ ret } + .method public hidebysig + instance bool BoxIsinstBranch_UsingTypeConstraints(class InvalidCSharp.EmptyInterface) cil managed + { + .locals init ( + [0] !!U + ) + ldarg.1 + isinst !!U + brfalse.s NOT_U + ldarg.1 + isinst !!U + unbox.any !!U + stloc.0 + ldc.i4.0 + ret + NOT_U: + ldc.i4.1 + ret + } + .method public hidebysig instance bool AllocArrayOfT() cil managed aggressiveinlining { @@ -406,6 +461,19 @@ { } +.class public auto ansi beforefieldinit InvalidCSharp.ClassWithInterface + extends [System.Runtime]System.Object + implements InvalidCSharp.EmptyInterface +{ + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + ldarg.0 + call instance void [System.Runtime]System.Object::.ctor() + ret + } +} + // Generic substitution of allow-byreflike with allow-byreflike .class interface public auto ansi abstract InvalidCSharp.GenericDerivedInterface_OverByRef`1 implements class InvalidCSharp.GenericInterface_Over`1 @@ -651,6 +719,18 @@ call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranch(!0) pop + ldloca.s 0 + ldloc 0 + ldfld !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranchToOther(!0) + pop + + ldloca.s 0 + ldloc 0 + ldfld !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranchToOther(!0) + pop + ldloca.s 0 ldloca.s 0 ldflda !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field @@ -695,6 +775,11 @@ ldloca.s 0 ldflda !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxIsinstBranch_WithSideEffects(!0&) + pop + + ldloca.s 0 + newobj instance void InvalidCSharp.ClassWithInterface::.ctor() + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxIsinstBranch_UsingTypeConstraints(class InvalidCSharp.EmptyInterface) ret } diff --git a/src/tests/Regressions/coreclr/GitHub_100536/test100536.cs b/src/tests/Regressions/coreclr/GitHub_100536/test100536.cs new file mode 100644 index 00000000000000..8d46268144122e --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_100536/test100536.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Xunit; + +public class Test100536 +{ + [DllImport("__test", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Nonexistent")] + private static extern IntPtr Nonexistent(); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + private static void GarbleStack() + { + Span local = stackalloc byte[4096]; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Test() + { + try + { + Nonexistent(); + } + catch (Exception ex) + { + Console.WriteLine($"Expected exception {ex} caught"); + } + } + + [Fact] + public static void TestEntryPoint() + { + Test(); + GarbleStack(); + GC.Collect(); + } +} + diff --git a/src/tests/Regressions/coreclr/GitHub_100536/test100536.csproj b/src/tests/Regressions/coreclr/GitHub_100536/test100536.csproj new file mode 100644 index 00000000000000..fa208f1214f917 --- /dev/null +++ b/src/tests/Regressions/coreclr/GitHub_100536/test100536.csproj @@ -0,0 +1,11 @@ + + + 1 + + + + + + + + diff --git a/src/tests/Regressions/coreclr/GitHub_22888/test22888.csproj b/src/tests/Regressions/coreclr/GitHub_22888/test22888.csproj index f2a1d423be02aa..f74b821627d90b 100644 --- a/src/tests/Regressions/coreclr/GitHub_22888/test22888.csproj +++ b/src/tests/Regressions/coreclr/GitHub_22888/test22888.csproj @@ -3,6 +3,9 @@ true true + + + true diff --git a/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.Generics.cs b/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.Generics.cs index e1029797bf12cc..c64306a27bdcb0 100644 --- a/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.Generics.cs +++ b/src/tests/baseservices/compilerservices/UnsafeAccessors/UnsafeAccessorsTests.Generics.cs @@ -63,7 +63,6 @@ private void Add(Struct a) => } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_AccessStaticFieldClass() { Console.WriteLine($"Running {nameof(Verify_Generic_AccessStaticFieldClass)}"); @@ -99,7 +98,6 @@ public static void Verify_Generic_AccessStaticFieldClass() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_AccessFieldClass() { Console.WriteLine($"Running {nameof(Verify_Generic_AccessFieldClass)}"); @@ -142,7 +140,6 @@ sealed class Derived2 : GenericBase } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_InheritanceMethodResolution() { string expect = "abc"; @@ -232,7 +229,6 @@ sealed class Accessors } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_CallCtor() { Console.WriteLine($"Running {nameof(Verify_Generic_CallCtor)}"); @@ -284,7 +280,6 @@ public static void Verify_Generic_CallCtor() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_GenericTypeNonGenericInstanceMethod() { Console.WriteLine($"Running {nameof(Verify_Generic_GenericTypeNonGenericInstanceMethod)}"); @@ -315,7 +310,6 @@ public static void Verify_Generic_GenericTypeNonGenericInstanceMethod() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_GenericTypeGenericInstanceMethod() { Console.WriteLine($"Running {nameof(Verify_Generic_GenericTypeGenericInstanceMethod)}"); @@ -358,7 +352,6 @@ public static void Verify_Generic_GenericTypeGenericInstanceMethod() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_GenericTypeNonGenericStaticMethod() { Console.WriteLine($"Running {nameof(Verify_Generic_GenericTypeNonGenericStaticMethod)}"); @@ -370,7 +363,6 @@ public static void Verify_Generic_GenericTypeNonGenericStaticMethod() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_GenericTypeGenericStaticMethod() { Console.WriteLine($"Running {nameof(Verify_Generic_GenericTypeGenericStaticMethod)}"); @@ -445,7 +437,6 @@ class Invalid } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/89439", TestRuntimes.Mono)] public static void Verify_Generic_InvalidUseUnsafeAccessor() { Console.WriteLine($"Running {nameof(Verify_Generic_InvalidUseUnsafeAccessor)}"); diff --git a/src/tests/issues.targets b/src/tests/issues.targets index e5e6cc332a6292..8289fcefb924fb 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -682,6 +682,15 @@ + + needs triage + + + needs triage + + + https://github.com/dotnet/runtime/issues/91381 + https://github.com/dotnet/runtime/issues/89157 @@ -1151,6 +1160,46 @@ + + + + https://github.com/dotnet/runtime/issues/101284 + + + https://github.com/dotnet/runtime/issues/101284 + + + https://github.com/dotnet/runtime/issues/101284 + + + https://github.com/dotnet/runtime/issues/101284 + + + https://github.com/dotnet/runtime/issues/101284 + + + https://github.com/dotnet/runtime/issues/101284 + + + https://github.com/dotnet/runtime/issues/101363 + + + https://github.com/dotnet/runtime/issues/101363 + + + https://github.com/dotnet/runtime/issues/101363 + + + https://github.com/dotnet/runtime/issues/101363 + + + https://github.com/dotnet/runtime/issues/101363 + + + https://github.com/dotnet/runtime/issues/101364 + + + diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs index a9d3d44c758dde..f362c08d424649 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs @@ -55,6 +55,7 @@ internal static int Run() TestRecursionThroughGenericLookups.Run(); TestRecursionInFields.Run(); TestGvmLookupDependency.Run(); + Test99198Regression.Run(); TestInvokeMemberCornerCaseInGenerics.Run(); TestRefAny.Run(); TestNullableCasting.Run(); @@ -3480,6 +3481,80 @@ public static void Run() } } + class Test99198Regression + { + delegate void Set(ref T t, IFoo ifoo); + + interface IFoo + { + void Do(); + } + + class Atom { } + + struct Foo : IFoo + { + public nint Cookie1; + public nint Cookie2; + + public void Do() + { + Cookie1 = 42; + } + } + + class C where T : IFoo + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Set(ref T t, IFoo ifoo) + { + t.Do(); + ifoo.Do(); + } + } + + public static void RunDynamic() + { + static Type GetObject() => typeof(Foo); + var s = typeof(C<>).MakeGenericType(GetObject()).GetMethod("Set").CreateDelegate>>(); + + Foo ob = default; + IFoo boxed = ob; + + s(ref ob, boxed); + + if (ob.Cookie1 != 42 || ob.Cookie2 != 0) + throw new Exception(); + + ob = (Foo)boxed; + if (ob.Cookie1 != 42 || ob.Cookie2 != 0) + throw new Exception(); + } + + public static void Run() + { + new C>().ToString(); + + static Type GetObject() => typeof(Foo); + var s = typeof(C<>).MakeGenericType(GetObject()).GetMethod("Set").CreateDelegate>>(); + + Foo ob = default; + IFoo boxed = ob; + + s(ref ob, boxed); + + if (ob.Cookie1 != 42 || ob.Cookie2 != 0) + throw new Exception(); + + ob = (Foo)boxed; + if (ob.Cookie1 != 42 || ob.Cookie2 != 0) + throw new Exception(); + + static Type GetAtom() => typeof(Atom); + typeof(Test99198Regression).GetMethod(nameof(RunDynamic)).MakeGenericMethod(GetAtom()).Invoke(null, []); + } + } + class TestInvokeMemberCornerCaseInGenerics { class Generic diff --git a/src/tests/profiler/common/ProfilerTestRunner.cs b/src/tests/profiler/common/ProfilerTestRunner.cs index d78a1221b42213..2dfc2530c59d65 100644 --- a/src/tests/profiler/common/ProfilerTestRunner.cs +++ b/src/tests/profiler/common/ProfilerTestRunner.cs @@ -135,9 +135,9 @@ public static int Run(string profileePath, if (!verifier.HasPassingOutput) { - FailFastWithMessage("Profiler tests are expected to contain the text \'" + verifier.SuccessPhrase + "\' in the console output " + - "of the profilee app to indicate a passing test. Usually it is printed from the Shutdown() method of the profiler implementation. This " + - "text was not found in the output above."); + FailFastWithMessage($"Profiler tests are expected to contain the text '{verifier.SuccessPhrase}' in the console output " + + $"of the profilee app to indicate a passing test. Usually it is printed from the Shutdown() method of the profiler implementation. This " + + $"text was not found in the output above. Profilee returned exit code {process.ExitCode}."); } if (process.ExitCode != 100) @@ -195,14 +195,16 @@ private static void FailFastWithMessage(string error) /// class ProfileeOutputVerifier { + private volatile bool _hasPassingOutput; + public string SuccessPhrase = "PROFILER TEST PASSES"; - public bool HasPassingOutput { get; private set; } + public bool HasPassingOutput => _hasPassingOutput; public void WriteLine(string message) { if (message != null && message.Contains(SuccessPhrase)) { - HasPassingOutput = true; + _hasPassingOutput = true; } } @@ -210,7 +212,7 @@ public void WriteLine(string format, params object[] args) { if (string.Format(format,args).Contains(SuccessPhrase)) { - HasPassingOutput = true; + _hasPassingOutput = true; } } } diff --git a/src/tests/profiler/multiple/multiple.cs b/src/tests/profiler/multiple/multiple.cs index 0d686ae0691a94..a0952687021bf0 100644 --- a/src/tests/profiler/multiple/multiple.cs +++ b/src/tests/profiler/multiple/multiple.cs @@ -35,7 +35,7 @@ public static int RunTest(String[] args) } Console.WriteLine("Waiting for profilers to all detach"); - if (!_profilerDone.WaitOne(TimeSpan.FromMinutes(10))) + if (!_profilerDone.WaitOne(TimeSpan.FromMinutes(5))) { throw new Exception("Test timed out waiting for the profilers to set the callback, test will fail."); } @@ -45,11 +45,6 @@ public static int RunTest(String[] args) public static int Main(string[] args) { - // failing on MacOs 12 https://github.com/dotnet/runtime/issues/64765 - if (OperatingSystem.IsMacOS()) - { - return 100; - } if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase)) { return RunTest(args); diff --git a/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcUnixDomainSocketEndPoint.cs b/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcUnixDomainSocketEndPoint.cs index f9413852a510f2..b939b4b22d15af 100644 --- a/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcUnixDomainSocketEndPoint.cs +++ b/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcUnixDomainSocketEndPoint.cs @@ -23,7 +23,7 @@ public IpcUnixDomainSocketEndPoint(string endPoint) private static EndPoint CreateEndPoint(string endPoint) { -#if NETCOREAPP +#if NET return new UnixDomainSocketEndPoint(endPoint); #elif NETSTANDARD2_0 // UnixDomainSocketEndPoint is not part of .NET Standard 2.0 diff --git a/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs b/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs index 30ccdc1a48f4be..41726e9286791b 100644 --- a/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs +++ b/src/tests/tracing/eventpipe/common/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs @@ -136,7 +136,7 @@ protected async Task IsStreamConnectedAsync(Stream stream, CancellationToken tok protected bool IsCompletedSuccessfully(Task t) { -#if NETCOREAPP2_0_OR_GREATER +#if NET return t.IsCompletedSuccessfully; #else return t.IsCompleted && !t.IsCanceled && !t.IsFaulted; diff --git a/src/tools/illink/external/Mono.Options/Options.cs b/src/tools/illink/external/Mono.Options/Options.cs index 07176081d7b3fc..d8b3d78a455096 100644 --- a/src/tools/illink/external/Mono.Options/Options.cs +++ b/src/tools/illink/external/Mono.Options/Options.cs @@ -749,7 +749,7 @@ public string OptionName { get {return this.option;} } -#if !PCL && !NETCOREAPP +#if !PCL && !NET #pragma warning disable 618 // SecurityPermissionAttribute is obsolete [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)] #pragma warning restore 618 diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/NullableAttributes.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/NullableAttributes.cs index 7ab77287ed5f31..7cf10912ea38b2 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/NullableAttributes.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/NullableAttributes.cs @@ -5,7 +5,7 @@ // and updated to have the scope of the attributes be internal. namespace System.Diagnostics.CodeAnalysis { -#if !NETCOREAPP +#if !NET /// Specifies that null is allowed as an input even if the corresponding type disallows it. [AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] @@ -86,7 +86,7 @@ internal sealed class DoesNotReturnIfAttribute : Attribute #endif -#if !NETCOREAPP || NETCOREAPP3_1 +#if !NET /// Specifies that the method or property will ensure that the listed field and property members have not-null values. [AttributeUsage (AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs index db0eb0af579ede..2fa967fdc9405d 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs @@ -103,11 +103,11 @@ public static DynamicallyAccessedMemberTypes GetTypeAnnotation(ITypeSymbol type) internal partial bool MethodRequiresDataFlowAnalysis (MethodProxy method) => RequiresDataFlowAnalysis (method.Method); - internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) - => new MethodReturnValue (method.Method, dynamicallyAccessedMemberTypes); + internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, bool isNewObj, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) + => new MethodReturnValue (method.Method, isNewObj, dynamicallyAccessedMemberTypes); - internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method) - => GetMethodReturnValue (method, GetMethodReturnValueAnnotation (method.Method)); + internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, bool isNewObj) + => GetMethodReturnValue (method, isNewObj, GetMethodReturnValueAnnotation (method.Method)); internal partial GenericParameterValue GetGenericParameterValue (GenericParameterProxy genericParameter) => new GenericParameterValue (genericParameter.TypeParameterSymbol); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs index 96c4a07a92a79a..d41ccee2388a58 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/HandleCallAction.cs @@ -7,8 +7,11 @@ using ILLink.RoslynAnalyzer; using ILLink.RoslynAnalyzer.DataFlow; using ILLink.RoslynAnalyzer.TrimAnalysis; +using ILLink.Shared.DataFlow; using ILLink.Shared.TypeSystemProxy; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Operations; +using MultiValue = ILLink.Shared.DataFlow.ValueSet; namespace ILLink.Shared.TrimAnalysis { @@ -20,15 +23,125 @@ internal partial struct HandleCallAction readonly ISymbol _owningSymbol; readonly IOperation _operation; readonly ReflectionAccessAnalyzer _reflectionAccessAnalyzer; + ValueSetLattice _multiValueLattice; - public HandleCallAction (in DiagnosticContext diagnosticContext, ISymbol owningSymbol, IOperation operation) + public HandleCallAction ( + in DiagnosticContext diagnosticContext, + ISymbol owningSymbol, + IOperation operation, + ValueSetLattice multiValueLattice) { _owningSymbol = owningSymbol; _operation = operation; + _isNewObj = operation.Kind == OperationKind.ObjectCreation; _diagnosticContext = diagnosticContext; _annotations = FlowAnnotations.Instance; _reflectionAccessAnalyzer = default; _requireDynamicallyAccessedMembersAction = new (diagnosticContext, _reflectionAccessAnalyzer); + _multiValueLattice = multiValueLattice; + } + + private partial bool TryHandleIntrinsic ( + MethodProxy calledMethod, + MultiValue instanceValue, + IReadOnlyList argumentValues, + IntrinsicId intrinsicId, + out MultiValue? methodReturnValue) + { + MultiValue? maybeMethodReturnValue = methodReturnValue = null; + ValueSetLattice multiValueLattice = _multiValueLattice; + + switch (intrinsicId) { + case IntrinsicId.Array_Empty: + AddReturnValue (ArrayValue.Create (0)); + break; + + case IntrinsicId.TypeDelegator_Ctor: + if (_operation is IObjectCreationOperation) + AddReturnValue (argumentValues[0]); + + break; + + case IntrinsicId.Object_GetType: { + foreach (var valueNode in instanceValue.AsEnumerable ()) { + // Note that valueNode can be statically typed as some generic argument type. + // For example: + // void Method(T instance) { instance.GetType().... } + // But it could be that T is annotated with for example PublicMethods: + // void Method<[DAM(PublicMethods)] T>(T instance) { instance.GetType().GetMethod("Test"); } + // In this case it's in theory possible to handle it, by treating the T basically as a base class + // for the actual type of "instance". But the analysis for this would be pretty complicated (as the marking + // has to happen on the callsite, which doesn't know that GetType() will be used...). + // For now we're intentionally ignoring this case - it will produce a warning. + // The counter example is: + // Method(new Derived); + // In this case to get correct results, trimmer would have to mark all public methods on Derived. Which + // currently it won't do. + + // To emulate IL tools behavior (trimmer, NativeAOT compiler), we're going to intentionally "forget" the static type + // if it is a generic argument type. + + ITypeSymbol? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; + if (staticType?.TypeKind == TypeKind.TypeParameter) + staticType = null; + + if (staticType is null) { + // We don't know anything about the type GetType was called on. Track this as a usual "result of a method call without any annotations" + AddReturnValue (FlowAnnotations.Instance.GetMethodReturnValue (calledMethod, _isNewObj)); + } else if (staticType.IsSealed || staticType.IsTypeOf ("System", "Delegate") || staticType.TypeKind == TypeKind.Array) { + // We can treat this one the same as if it was a typeof() expression + + // We can allow Object.GetType to be modeled as System.Delegate because we keep all methods + // on delegates anyway so reflection on something this approximation would miss is actually safe. + + // We can also treat all arrays as "sealed" since it's not legal to derive from Array type (even though it is not sealed itself) + + // We ignore the fact that the type can be annotated (see below for handling of annotated types) + // This means the annotations (if any) won't be applied - instead we rely on the exact knowledge + // of the type. So for example even if the type is annotated with PublicMethods + // but the code calls GetProperties on it - it will work - mark properties, don't mark methods + // since we ignored the fact that it's annotated. + // This can be seen a little bit as a violation of the annotation, but we already have similar cases + // where a parameter is annotated and if something in the method sets a specific known type to it + // we will also make it just work, even if the annotation doesn't match the usage. + AddReturnValue (new SystemTypeValue (new (staticType))); + } else { + var annotation = FlowAnnotations.GetTypeAnnotation (staticType); + AddReturnValue (FlowAnnotations.Instance.GetMethodReturnValue (calledMethod, _isNewObj, annotation)); + } + } + break; + } + + // Some intrinsics are unimplemented by the analyzer. + // These will fall back to the usual return-value handling. + case IntrinsicId.Array_CreateInstance: + case IntrinsicId.Assembly_GetFile: + case IntrinsicId.Assembly_GetFiles: + case IntrinsicId.AssemblyName_get_EscapedCodeBase: + case IntrinsicId.Assembly_get_Location: + case IntrinsicId.AssemblyName_get_CodeBase: + case IntrinsicId.Delegate_get_Method: + case IntrinsicId.Enum_GetValues: + case IntrinsicId.Marshal_DestroyStructure: + case IntrinsicId.Marshal_GetDelegateForFunctionPointer: + case IntrinsicId.Marshal_OffsetOf: + case IntrinsicId.Marshal_PtrToStructure: + case IntrinsicId.Marshal_SizeOf: + case IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo: + break; + + default: + return false; + } + + methodReturnValue = maybeMethodReturnValue; + return true; + + void AddReturnValue (MultiValue value) + { + maybeMethodReturnValue = (maybeMethodReturnValue is null) ? value : multiValueLattice.Meet ((MultiValue) maybeMethodReturnValue, value); + } } private partial IEnumerable GetMethodsOnTypeHierarchy (TypeProxy type, string name, BindingFlags? bindingFlags) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs index 5001e5836eaccb..0b274879440f51 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodProxy.cs @@ -46,6 +46,8 @@ internal partial ImmutableArray GetGenericParameters () return builder.ToImmutableArray (); } + internal partial bool IsConstructor () => Method.IsConstructor (); + internal partial bool IsStatic () => Method.IsStatic; internal partial bool HasImplicitThis () => Method.HasImplicitThis (); diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodReturnValue.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodReturnValue.cs index 6a84896e577a86..d11181ad96d250 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodReturnValue.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/MethodReturnValue.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using ILLink.RoslynAnalyzer; using ILLink.Shared.DataFlow; @@ -11,16 +12,17 @@ namespace ILLink.Shared.TrimAnalysis { internal partial record MethodReturnValue { - public MethodReturnValue (IMethodSymbol methodSymbol) - : this (methodSymbol, FlowAnnotations.GetMethodReturnValueAnnotation (methodSymbol)) + public MethodReturnValue (IMethodSymbol methodSymbol, bool isNewObj) + : this (methodSymbol, isNewObj, FlowAnnotations.GetMethodReturnValueAnnotation (methodSymbol)) { } - public MethodReturnValue (IMethodSymbol methodSymbol, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) + public MethodReturnValue (IMethodSymbol methodSymbol, bool isNewObj, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) { + Debug.Assert (!isNewObj || methodSymbol.MethodKind == MethodKind.Constructor, "isNewObj can only be true for constructors"); MethodSymbol = methodSymbol; DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes; - StaticType = new (methodSymbol.ReturnType); + StaticType = new (isNewObj ? methodSymbol.ContainingType : methodSymbol.ReturnType); } public readonly IMethodSymbol MethodSymbol; diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index 9db61498b28ceb..2d9cb6cd84160d 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -75,16 +75,22 @@ public override void ApplyCondition (FeatureChecksValue featureChecksValue, ref // - 'this' parameter (for annotated methods) // - field reference - public override MultiValue Visit (IOperation? operation, StateValue argument) + public override MultiValue DefaultVisit (IOperation operation, StateValue argument) { - var returnValue = base.Visit (operation, argument); + var returnValue = base.DefaultVisit (operation, argument); // If the return value is empty (TopValue basically) and the Operation tree // reports it as having a constant value, use that as it will automatically cover // cases we don't need/want to handle. - if (operation != null && returnValue.IsEmpty () && TryGetConstantValue (operation, out var constValue)) + if (!returnValue.IsEmpty ()) + return returnValue; + + if (TryGetConstantValue (operation, out var constValue)) return constValue; + if (operation.Type is not null) + return UnknownValue.Instance; + return returnValue; } @@ -116,7 +122,7 @@ public override MultiValue VisitConversion (IConversionOperation operation, Stat var value = base.VisitConversion (operation, state); if (operation.OperatorMethod != null) - return operation.OperatorMethod.ReturnType.IsTypeInterestingForDataflow () ? new MethodReturnValue (operation.OperatorMethod) : value; + return operation.OperatorMethod.ReturnType.IsTypeInterestingForDataflow () ? new MethodReturnValue (operation.OperatorMethod, isNewObj: false) : value; // TODO - is it possible to have annotation on the operator method parameters? // if so, will these be checked here? @@ -321,92 +327,16 @@ internal static void HandleCall( ValueSetLattice multiValueLattice, out MultiValue methodReturnValue) { - var handleCallAction = new HandleCallAction (diagnosticContext, owningSymbol, operation); + var handleCallAction = new HandleCallAction (diagnosticContext, owningSymbol, operation, multiValueLattice); MethodProxy method = new (calledMethod); var intrinsicId = Intrinsics.GetIntrinsicIdForMethod (method); + if (!handleCallAction.Invoke (method, instance, arguments, intrinsicId, out methodReturnValue)) + UnhandledIntrinsicHelper (intrinsicId); - if (handleCallAction.Invoke (method, instance, arguments, intrinsicId, out methodReturnValue)) { - return; - } - - MultiValue? maybeMethodReturnValue = default; - - switch (intrinsicId) { - case IntrinsicId.Array_Empty: - AddReturnValue (ArrayValue.Create (0)); - break; - - case IntrinsicId.TypeDelegator_Ctor: - if (operation is IObjectCreationOperation) - AddReturnValue (arguments[0]); - - break; - - case IntrinsicId.Object_GetType: { - foreach (var valueNode in instance.AsEnumerable ()) { - // Note that valueNode can be statically typed as some generic argument type. - // For example: - // void Method(T instance) { instance.GetType().... } - // But it could be that T is annotated with for example PublicMethods: - // void Method<[DAM(PublicMethods)] T>(T instance) { instance.GetType().GetMethod("Test"); } - // In this case it's in theory possible to handle it, by treating the T basically as a base class - // for the actual type of "instance". But the analysis for this would be pretty complicated (as the marking - // has to happen on the callsite, which doesn't know that GetType() will be used...). - // For now we're intentionally ignoring this case - it will produce a warning. - // The counter example is: - // Method(new Derived); - // In this case to get correct results, trimmer would have to mark all public methods on Derived. Which - // currently it won't do. - - // To emulate IL tools behavior (trimmer, NativeAOT compiler), we're going to intentionally "forget" the static type - // if it is a generic argument type. - - ITypeSymbol? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; - if (staticType?.TypeKind == TypeKind.TypeParameter) - staticType = null; - - if (staticType is null) { - // We don't know anything about the type GetType was called on. Track this as a usual "result of a method call without any annotations" - AddReturnValue (FlowAnnotations.Instance.GetMethodReturnValue (new (calledMethod))); - } else if (staticType.IsSealed || staticType.IsTypeOf ("System", "Delegate") || staticType.TypeKind == TypeKind.Array) { - // We can treat this one the same as if it was a typeof() expression - - // We can allow Object.GetType to be modeled as System.Delegate because we keep all methods - // on delegates anyway so reflection on something this approximation would miss is actually safe. - - // We can also treat all arrays as "sealed" since it's not legal to derive from Array type (even though it is not sealed itself) - - // We ignore the fact that the type can be annotated (see below for handling of annotated types) - // This means the annotations (if any) won't be applied - instead we rely on the exact knowledge - // of the type. So for example even if the type is annotated with PublicMethods - // but the code calls GetProperties on it - it will work - mark properties, don't mark methods - // since we ignored the fact that it's annotated. - // This can be seen a little bit as a violation of the annotation, but we already have similar cases - // where a parameter is annotated and if something in the method sets a specific known type to it - // we will also make it just work, even if the annotation doesn't match the usage. - AddReturnValue (new SystemTypeValue (new (staticType))); - } else { - var annotation = FlowAnnotations.GetTypeAnnotation (staticType); - AddReturnValue (FlowAnnotations.Instance.GetMethodReturnValue (new (calledMethod), annotation)); - } - } - } - - break; - - default: - Debug.Fail ($"Unexpected method {calledMethod.GetDisplayName ()} unhandled by HandleCallAction."); - - // Do nothing even if we reach a point which we didn't expect - the analyzer should never crash as it's a too disruptive experience for the user. - break; - } - - methodReturnValue = maybeMethodReturnValue ?? multiValueLattice.Top; - - void AddReturnValue (MultiValue value) - { - maybeMethodReturnValue = (maybeMethodReturnValue is null) ? value : multiValueLattice.Meet ((MultiValue) maybeMethodReturnValue, value); - } + // Avoid crashing the analyzer in release builds + [Conditional ("DEBUG")] + static void UnhandledIntrinsicHelper (IntrinsicId intrinsicId) + => throw new NotImplementedException ($"Unhandled intrinsic: {intrinsicId}"); } public override void HandleReturnValue (MultiValue returnValue, IOperation operation, in FeatureContext featureContext) @@ -417,7 +347,7 @@ public override void HandleReturnValue (MultiValue returnValue, IOperation opera return; if (method.ReturnType.IsTypeInterestingForDataflow ()) { - var returnParameter = new MethodReturnValue (method); + var returnParameter = new MethodReturnValue (method, isNewObj: false); TrimAnalysisPatterns.Add ( new TrimAnalysisAssignmentPattern (returnValue, returnParameter, operation, OwningSymbol, featureContext), diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/FlowAnnotations.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/FlowAnnotations.cs index 7ca5df5a6b8fe4..4ef9a9ce61a41f 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/FlowAnnotations.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/FlowAnnotations.cs @@ -19,9 +19,9 @@ partial class FlowAnnotations { internal partial bool MethodRequiresDataFlowAnalysis (MethodProxy method); - internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes); + internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, bool isNewObj, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes); - internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method); + internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, bool isNewObj); internal partial GenericParameterValue GetGenericParameterValue (GenericParameterProxy genericParameter); diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs index 9063ac7368dbe4..ff2a393928deaf 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs @@ -26,13 +26,63 @@ internal partial struct HandleCallAction private readonly DiagnosticContext _diagnosticContext; private readonly FlowAnnotations _annotations; private readonly RequireDynamicallyAccessedMembersAction _requireDynamicallyAccessedMembersAction; + private readonly bool _isNewObj; public bool Invoke (MethodProxy calledMethod, MultiValue instanceValue, IReadOnlyList argumentValues, IntrinsicId intrinsicId, out MultiValue methodReturnValue) { - MultiValue? returnValue = null; + MultiValue? maybeMethodReturnValue; + + var handledIntrinsic = + TryHandleIntrinsic (calledMethod, instanceValue, argumentValues, intrinsicId, out maybeMethodReturnValue) || + TryHandleSharedIntrinsic (calledMethod, instanceValue, argumentValues, intrinsicId, out maybeMethodReturnValue); + + // As a convenience, if the code above didn't set the return value (and the method has a return value), + // we will set it to be an unknown value with the return type of the method. + var annotatedMethodReturnValue = _annotations.GetMethodReturnValue (calledMethod, _isNewObj); + bool returnsVoid = calledMethod.ReturnsVoid (); + methodReturnValue = maybeMethodReturnValue ?? + ((returnsVoid && !_isNewObj) + ? MultiValueLattice.Top + : annotatedMethodReturnValue); + + // Validate that the return value has the correct annotations as per the method return value annotations + if (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes != 0) { + foreach (var uniqueValue in methodReturnValue.AsEnumerable ()) { + if (uniqueValue is ValueWithDynamicallyAccessedMembers methodReturnValueWithMemberTypes) { + if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes)) + throw new InvalidOperationException ($"Internal trimming error: processing of call from {GetContainingSymbolDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); + } else if (uniqueValue is SystemTypeValue) { + // SystemTypeValue can fulfill any requirement, so it's always valid + // The requirements will be applied at the point where it's consumed (passed as a method parameter, set as field value, returned from the method) + } else if (uniqueValue == NullValue.Instance) { + // NullValue can fulfill any requirements because reflection access to it will typically throw. + } else { + throw new InvalidOperationException ($"Internal trimming error: processing of call from {GetContainingSymbolDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); + } + } + } + + return handledIntrinsic; + } + + private partial bool TryHandleIntrinsic ( + MethodProxy calledMethod, + MultiValue instanceValue, + IReadOnlyList argumentValues, + IntrinsicId intrinsicId, + out MultiValue? methodReturnValue); + + bool TryHandleSharedIntrinsic ( + MethodProxy calledMethod, + MultiValue instanceValue, + IReadOnlyList argumentValues, + IntrinsicId intrinsicId, + out MultiValue? methodReturnValue) + { + MultiValue? returnValue = methodReturnValue = null; bool requiresDataFlowAnalysis = _annotations.MethodRequiresDataFlowAnalysis (calledMethod); - var annotatedMethodReturnValue = _annotations.GetMethodReturnValue (calledMethod); + var annotatedMethodReturnValue = _annotations.GetMethodReturnValue (calledMethod, _isNewObj); Debug.Assert (requiresDataFlowAnalysis || annotatedMethodReturnValue.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.None); switch (intrinsicId) { @@ -154,8 +204,7 @@ GenericParameterValue genericParam // Array.Empty must for now be handled by the specific implementation since it requires instantiated generic method handling case IntrinsicId.Object_GetType: // Object.GetType requires additional handling by the caller to implement type hierarchy marking and related diagnostics - methodReturnValue = MultiValueLattice.Top; - return false; + throw new NotImplementedException ("These intrinsics should be handled by the specific implementation: " + intrinsicId); // // GetInterface (String) @@ -190,7 +239,7 @@ GenericParameterValue genericParam && valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.All) returnMemberTypes = DynamicallyAccessedMemberTypes.All; - AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, returnMemberTypes)); + AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, _isNewObj, returnMemberTypes)); } } } @@ -497,7 +546,7 @@ GenericParameterValue genericParam // We only applied the annotation based on binding flags, so we will keep the necessary types // but we will not keep anything on them. So the return value has no known annotations on it - AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, DynamicallyAccessedMemberTypes.None)); + AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, _isNewObj, DynamicallyAccessedMemberTypes.None)); } } } else if (value is NullValue) { @@ -511,9 +560,9 @@ GenericParameterValue genericParam // since All applies recursively to all nested type (see MarkStep.MarkEntireType). // Otherwise we only mark the nested type itself, nothing on it, so the return value has no annotation on it. if (value is ValueWithDynamicallyAccessedMembers { DynamicallyAccessedMemberTypes: DynamicallyAccessedMemberTypes.All }) - AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, DynamicallyAccessedMemberTypes.All)); + AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, _isNewObj, DynamicallyAccessedMemberTypes.All)); else - AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, DynamicallyAccessedMemberTypes.None)); + AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, _isNewObj, DynamicallyAccessedMemberTypes.None)); } } } @@ -785,7 +834,7 @@ GenericParameterValue genericParam } else if (typeNameValue is ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers && valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes != 0) { // Propagate the annotation from the type name to the return value. Annotation on a string value will be fulfilled whenever a value is assigned to the string with annotation. // So while we don't know which type it is, we can guarantee that it will fulfill the annotation. - AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes)); + AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, _isNewObj, valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes)); } else { _diagnosticContext.AddDiagnostic (DiagnosticId.UnrecognizedTypeNameInTypeGetType, calledMethod.GetDisplayName ()); AddReturnValue (MultiValueLattice.Top); @@ -909,7 +958,7 @@ GenericParameterValue genericParam propagatedMemberTypes |= DynamicallyAccessedMemberTypes.Interfaces; } - AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, propagatedMemberTypes)); + AddReturnValue (_annotations.GetMethodReturnValue (calledMethod, _isNewObj, propagatedMemberTypes)); } else if (value is SystemTypeValue systemTypeValue) { if (TryGetBaseType (systemTypeValue.RepresentedType, out var baseType)) AddReturnValue (new SystemTypeValue (baseType.Value)); @@ -1153,44 +1202,14 @@ GenericParameterValue genericParam } break; - // Disable warnings for all unimplemented intrinsics. Some intrinsic methods have annotations, but analyzing them - // would produce unnecessary warnings even for cases that are intrinsically handled. So we disable handling these calls - // until a proper intrinsic handling is made - // NOTE: Currently this is done "for the analyzer" and it relies on illink/NativeAOT to not call HandleCallAction - // for intrinsics which illink/NativeAOT need special handling for or those which are not implemented here and only there. - // Ideally we would run everything through HandleCallAction and it would return "false" for intrinsics it doesn't handle - // like it already does for Activator.CreateInstance for example. default: - methodReturnValue = MultiValueLattice.Top; - return true; + return false; } - // For now, if the intrinsic doesn't set a return value, fall back on the annotations. - // Note that this will be DynamicallyAccessedMembers.None for the intrinsics which don't return types. - returnValue ??= calledMethod.ReturnsVoid () ? MultiValueLattice.Top : annotatedMethodReturnValue; - if (MethodIsTypeConstructor (calledMethod)) returnValue = UnknownValue.Instance; - // Validate that the return value has the correct annotations as per the method return value annotations - if (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None) { - foreach (var uniqueValue in returnValue.Value.AsEnumerable ()) { - if (uniqueValue is ValueWithDynamicallyAccessedMembers methodReturnValueWithMemberTypes) { - if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes)) - throw new InvalidOperationException ($"Internal ILLink error: in {GetContainingSymbolDisplayName ()} processing call to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); - } else if (uniqueValue is SystemTypeValue) { - // SystemTypeValue can fulfill any requirement, so it's always valid - // The requirements will be applied at the point where it's consumed (passed as a method parameter, set as field value, returned from the method) - } else if (uniqueValue == NullValue.Instance) { - // NullValue can fulfill any requirements because reflection access to it will typically throw. - } else { - throw new InvalidOperationException ($"Internal ILLink error: in {GetContainingSymbolDisplayName ()} processing call to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); - } - } - } - - methodReturnValue = returnValue.Value; - + methodReturnValue = returnValue; return true; void AddReturnValue (MultiValue value) diff --git a/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs b/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs index 92ba44e630babf..008d1c1536ef77 100644 --- a/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs +++ b/src/tools/illink/src/ILLink.Shared/TypeSystemProxy/MethodProxy.cs @@ -56,6 +56,7 @@ internal bool HasParameterOfType (ParameterIndex parameterIndex, string fullType internal partial bool HasGenericParameters (); internal partial bool HasGenericParametersCount (int genericParameterCount); internal partial ImmutableArray GetGenericParameters (); + internal partial bool IsConstructor (); internal partial bool IsStatic (); internal partial bool HasImplicitThis (); internal partial bool ReturnsVoid (); diff --git a/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs b/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs index 0c257fa068d898..3b148cf3a1ac59 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/FlowAnnotations.cs @@ -682,11 +682,11 @@ public FieldAnnotation (FieldDefinition field, DynamicallyAccessedMemberTypes an internal partial bool MethodRequiresDataFlowAnalysis (MethodProxy method) => RequiresDataFlowAnalysis (method.Method); - internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) - => new MethodReturnValue (method.Method.ReturnType.ResolveToTypeDefinition (_context), method.Method, dynamicallyAccessedMemberTypes); + internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, bool isNewObj, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) + => MethodReturnValue.Create (method.Method, isNewObj, dynamicallyAccessedMemberTypes, _context); - internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method) - => GetMethodReturnValue (method, GetReturnParameterAnnotation (method.Method)); + internal partial MethodReturnValue GetMethodReturnValue (MethodProxy method, bool isNewObj) + => GetMethodReturnValue (method, isNewObj, GetReturnParameterAnnotation (method.Method)); internal partial GenericParameterValue GetGenericParameterValue (GenericParameterProxy genericParameter) => new GenericParameterValue (genericParameter.GenericParameter, GetGenericParameterAnnotation (genericParameter.GenericParameter)); diff --git a/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs b/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs index 108b79356a0228..998d9a06fdaeb6 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/HandleCallAction.cs @@ -2,11 +2,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using ILLink.Shared.TypeSystemProxy; using Mono.Cecil; +using Mono.Cecil.Cil; using Mono.Linker; using Mono.Linker.Dataflow; +using Mono.Linker.Steps; +using MultiValue = ILLink.Shared.DataFlow.ValueSet; namespace ILLink.Shared.TrimAnalysis { @@ -15,21 +20,163 @@ internal partial struct HandleCallAction #pragma warning disable CA1822 // Mark members as static - the other partial implementations might need to be instance methods readonly LinkContext _context; + readonly Instruction _operation; + readonly MarkStep _markStep; readonly ReflectionMarker _reflectionMarker; readonly MethodDefinition _callingMethodDefinition; + readonly MethodReference _calledMethodReference; public HandleCallAction ( LinkContext context, + Instruction operation, + MarkStep markStep, ReflectionMarker reflectionMarker, in DiagnosticContext diagnosticContext, - MethodDefinition callingMethodDefinition) + MethodDefinition callingMethodDefinition, + MethodReference calledMethodReference) { _context = context; + _operation = operation; + _isNewObj = operation.OpCode == OpCodes.Newobj; + _markStep = markStep; _reflectionMarker = reflectionMarker; _diagnosticContext = diagnosticContext; _callingMethodDefinition = callingMethodDefinition; _annotations = context.Annotations.FlowAnnotations; _requireDynamicallyAccessedMembersAction = new (reflectionMarker, diagnosticContext); + _calledMethodReference = calledMethodReference; + } + + private partial bool TryHandleIntrinsic ( + MethodProxy calledMethod, + MultiValue instanceValue, + IReadOnlyList argumentValues, + IntrinsicId intrinsicId, + out MultiValue? methodReturnValue) + { + MultiValue? maybeMethodReturnValue = methodReturnValue = null; + Debug.Assert (calledMethod.Method == _context.Resolve (_calledMethodReference)); + + switch (intrinsicId) { + case IntrinsicId.None: { + if (ReflectionMethodBodyScanner.IsPInvokeDangerous (calledMethod.Method, _context, out bool comDangerousMethod)) { + Debug.Assert (comDangerousMethod); // Currently COM dangerous is the only one we detect + _diagnosticContext.AddDiagnostic (DiagnosticId.CorrectnessOfCOMCannotBeGuaranteed, calledMethod.GetDisplayName ()); + } + if (_context.Annotations.DoesMethodRequireUnreferencedCode (calledMethod.Method, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCode)) + MarkStep.ReportRequiresUnreferencedCode (calledMethod.GetDisplayName (), requiresUnreferencedCode, _diagnosticContext); + + return TryHandleSharedIntrinsic (calledMethod, instanceValue, argumentValues, intrinsicId, out methodReturnValue); + } + + case IntrinsicId.TypeDelegator_Ctor: { + // This is an identity function for analysis purposes + if (_operation.OpCode == OpCodes.Newobj) + AddReturnValue (argumentValues[0]); + } + break; + + case IntrinsicId.Array_Empty: { + AddReturnValue (ArrayValue.Create (0, ((GenericInstanceMethod) _calledMethodReference).GenericArguments[0])); + } + break; + + case IntrinsicId.Array_CreateInstance: + case IntrinsicId.Enum_GetValues: + case IntrinsicId.Marshal_SizeOf: + case IntrinsicId.Marshal_OffsetOf: + case IntrinsicId.Marshal_PtrToStructure: + case IntrinsicId.Marshal_DestroyStructure: + case IntrinsicId.Marshal_GetDelegateForFunctionPointer: + case IntrinsicId.Assembly_get_Location: + case IntrinsicId.Assembly_GetFile: + case IntrinsicId.Assembly_GetFiles: + case IntrinsicId.AssemblyName_get_CodeBase: + case IntrinsicId.AssemblyName_get_EscapedCodeBase: + case IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo: + case IntrinsicId.Delegate_get_Method: + // These intrinsics are not interesting for trimmer (they are interesting for AOT and that's why they are recognized) + break; + + // + // System.Object + // + // GetType() + // + case IntrinsicId.Object_GetType: { + foreach (var valueNode in instanceValue.AsEnumerable ()) { + // Note that valueNode can be statically typed in IL as some generic argument type. + // For example: + // void Method(T instance) { instance.GetType().... } + // Currently this case will end up with null StaticType - since there's no typedef for the generic argument type. + // But it could be that T is annotated with for example PublicMethods: + // void Method<[DAM(PublicMethods)] T>(T instance) { instance.GetType().GetMethod("Test"); } + // In this case it's in theory possible to handle it, by treating the T basically as a base class + // for the actual type of "instance". But the analysis for this would be pretty complicated (as the marking + // has to happen on the callsite, which doesn't know that GetType() will be used...). + // For now we're intentionally ignoring this case - it will produce a warning. + // The counter example is: + // Method(new Derived); + // In this case to get correct results, trimmer would have to mark all public methods on Derived. Which + // currently it won't do. + + TypeDefinition? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; + if (staticType is null) { + // We don't know anything about the type GetType was called on. Track this as a usual result of a method call without any annotations + AddReturnValue (_context.Annotations.FlowAnnotations.GetMethodReturnValue (calledMethod, _isNewObj)); + } else if (staticType.IsSealed || staticType.IsTypeOf ("System", "Delegate") || staticType.IsTypeOf ("System", "Array")) { + // We can treat this one the same as if it was a typeof() expression + + // We can allow Object.GetType to be modeled as System.Delegate because we keep all methods + // on delegates anyway so reflection on something this approximation would miss is actually safe. + + // We can also treat all arrays as "sealed" since it's not legal to derive from Array type (even though it is not sealed itself) + + // We ignore the fact that the type can be annotated (see below for handling of annotated types) + // This means the annotations (if any) won't be applied - instead we rely on the exact knowledge + // of the type. So for example even if the type is annotated with PublicMethods + // but the code calls GetProperties on it - it will work - mark properties, don't mark methods + // since we ignored the fact that it's annotated. + // This can be seen a little bit as a violation of the annotation, but we already have similar cases + // where a parameter is annotated and if something in the method sets a specific known type to it + // we will also make it just work, even if the annotation doesn't match the usage. + AddReturnValue (new SystemTypeValue (staticType)); + } else { + // Make sure the type is marked (this will mark it as used via reflection, which is sort of true) + // This should already be true for most cases (method params, fields, ...), but just in case + _reflectionMarker.MarkType (_diagnosticContext.Origin, staticType); + + var annotation = _markStep.DynamicallyAccessedMembersTypeHierarchy + .ApplyDynamicallyAccessedMembersToTypeHierarchy (staticType); + + // Return a value which is "unknown type" with annotation. For now we'll use the return value node + // for the method, which means we're loosing the information about which staticType this + // started with. For now we don't need it, but we can add it later on. + AddReturnValue (_context.Annotations.FlowAnnotations.GetMethodReturnValue (calledMethod, _isNewObj, annotation)); + } + } + } + break; + + // Note about Activator.CreateInstance + // There are 2 interesting cases: + // - The generic argument for T is either specific type or annotated - in that case generic instantiation will handle this + // since from .NET 6+ the T is annotated with PublicParameterlessConstructor annotation, so the trimming tools would apply this as for any other method. + // - The generic argument for T is unannotated type - the generic instantiantion handling has a special case for handling PublicParameterlessConstructor requirement + // in such that if the generic argument type has the "new" constraint it will not warn (as it is effectively the same thing semantically). + // For all other cases, the trimming tools would have already produced a warning. + + default: + return false; + } + + methodReturnValue = maybeMethodReturnValue; + return true; + + void AddReturnValue (MultiValue value) + { + maybeMethodReturnValue = (maybeMethodReturnValue is null) ? value : MultiValueLattice.Meet ((MultiValue) maybeMethodReturnValue, value); + } } private partial bool MethodIsTypeConstructor (MethodProxy method) diff --git a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs index 4d4855dc7ce6d9..34e5797ffd03b9 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/MethodBodyScanner.cs @@ -986,11 +986,8 @@ private ValueNodeList PopCallArguments ( Stack currentStack, MethodReference methodCalled, MethodBody containingMethodBody, - bool isNewObj, int ilOffset, - out SingleValue? newObjValue) + bool isNewObj, int ilOffset) { - newObjValue = null; - int countToPop = 0; if (!isNewObj && methodCalled.HasThis && !methodCalled.ExplicitThis) countToPop++; @@ -1003,8 +1000,7 @@ private ValueNodeList PopCallArguments ( } if (isNewObj) { - newObjValue = UnknownValue.Instance; - methodParams.Add (newObjValue); + methodParams.Add (UnknownValue.Instance); } methodParams.Reverse (); return methodParams; @@ -1090,33 +1086,15 @@ private void HandleCall ( bool isNewObj = operation.OpCode.Code == Code.Newobj; - SingleValue? newObjValue; - ValueNodeList methodArguments = PopCallArguments (currentStack, calledMethod, callingMethodBody, isNewObj, - operation.Offset, out newObjValue); + ValueNodeList methodArguments = PopCallArguments (currentStack, calledMethod, callingMethodBody, isNewObj, operation.Offset); var dereferencedMethodParams = new List (); foreach (var argument in methodArguments) dereferencedMethodParams.Add (DereferenceValue (argument, locals, ref interproceduralState)); - MultiValue methodReturnValue; - bool handledFunction = HandleCall ( + MultiValue methodReturnValue = HandleCall ( callingMethodBody, calledMethod, operation, - new ValueNodeList (dereferencedMethodParams), - out methodReturnValue); - - // Handle the return value or newobj result - if (!handledFunction) { - if (isNewObj) { - if (newObjValue == null) - methodReturnValue = new MultiValue (UnknownValue.Instance); - else - methodReturnValue = newObjValue; - } else { - if (!calledMethod.ReturnsVoid ()) { - methodReturnValue = UnknownValue.Instance; - } - } - } + new ValueNodeList (dereferencedMethodParams)); if (isNewObj || !calledMethod.ReturnsVoid ()) currentStack.Push (new StackSlot (methodReturnValue)); @@ -1134,12 +1112,11 @@ private void HandleCall ( public TypeDefinition? ResolveToTypeDefinition (TypeReference typeReference) => typeReference.ResolveToTypeDefinition (_context); - public abstract bool HandleCall ( + public abstract MultiValue HandleCall ( MethodBody callingMethodBody, MethodReference calledMethod, Instruction operation, - ValueNodeList methodParams, - out MultiValue methodReturnValue); + ValueNodeList methodParams); // Limit tracking array values to 32 values for performance reasons. There are many arrays much longer than 32 elements in .NET, but the interesting ones for trimming are nearly always less than 32 elements. private const int MaxTrackedArrayValues = 32; diff --git a/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs b/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs index a4ca0634a81f8d..6e6fd7a1bf2159 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/MethodProxy.cs @@ -59,6 +59,8 @@ internal partial ImmutableArray GetGenericParameters () return builder.ToImmutableArray (); } + internal partial bool IsConstructor () => Method.IsConstructor; + internal partial bool IsStatic () => Method.IsStatic; internal partial bool HasImplicitThis () => Method.HasImplicitThis (); diff --git a/src/tools/illink/src/linker/Linker.Dataflow/MethodReturnValue.cs b/src/tools/illink/src/linker/Linker.Dataflow/MethodReturnValue.cs index 9197a7bda6be10..bec6951b17e4d7 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/MethodReturnValue.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/MethodReturnValue.cs @@ -2,9 +2,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using ILLink.Shared.DataFlow; using Mono.Cecil; +using Mono.Linker; using Mono.Linker.Dataflow; using TypeDefinition = Mono.Cecil.TypeDefinition; @@ -16,7 +18,14 @@ namespace ILLink.Shared.TrimAnalysis /// internal partial record MethodReturnValue { - public MethodReturnValue (TypeDefinition? staticType, MethodDefinition method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) + public static MethodReturnValue Create (MethodDefinition method, bool isNewObj, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes, LinkContext context) + { + Debug.Assert (!isNewObj || method.IsConstructor, "isNewObj can only be true for constructors"); + var staticType = isNewObj ? method.DeclaringType : method.ReturnType.ResolveToTypeDefinition (context); + return new MethodReturnValue (staticType, method, dynamicallyAccessedMemberTypes); + } + + private MethodReturnValue (TypeDefinition? staticType, MethodDefinition method, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) { StaticType = staticType == null ? null : new (staticType); Method = method; diff --git a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs index 72e9339bc3bc3f..3f5109bfeff9bd 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs @@ -6,7 +6,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using ILLink.Shared; using ILLink.Shared.TrimAnalysis; using ILLink.Shared.TypeSystemProxy; using Mono.Cecil; @@ -76,7 +75,7 @@ protected override void Scan (MethodIL methodIL, ref InterproceduralState interp if (!methodIL.Method.ReturnsVoid ()) { var method = methodIL.Method; - var methodReturnValue = _annotations.GetMethodReturnValue (method); + var methodReturnValue = _annotations.GetMethodReturnValue (method, isNewObj: false); if (methodReturnValue.DynamicallyAccessedMemberTypes != 0) HandleAssignmentPattern (_origin, ReturnValue, methodReturnValue); } @@ -118,19 +117,17 @@ protected override void HandleStoreParameter (MethodDefinition method, MethodPar protected override void HandleStoreMethodReturnValue (MethodDefinition method, MethodReturnValue returnValue, Instruction operation, MultiValue valueToStore) => HandleStoreValueWithDynamicallyAccessedMembers (returnValue, operation, valueToStore); - public override bool HandleCall (MethodBody callingMethodBody, MethodReference calledMethod, Instruction operation, ValueNodeList methodParams, out MultiValue methodReturnValue) + public override MultiValue HandleCall (MethodBody callingMethodBody, MethodReference calledMethod, Instruction operation, ValueNodeList methodParams) { var reflectionProcessed = _markStep.ProcessReflectionDependency (callingMethodBody, operation); if (reflectionProcessed) { - methodReturnValue = default; - return false; + return UnknownValue.Instance; } Debug.Assert (callingMethodBody.Method == _origin.Provider); var calledMethodDefinition = _context.TryResolve (calledMethod); if (calledMethodDefinition == null) { - methodReturnValue = default; - return false; + return UnknownValue.Instance; } _origin = _origin.WithInstructionOffset (operation.Offset); @@ -162,11 +159,10 @@ public override bool HandleCall (MethodBody callingMethodBody, MethodReference c diagnosticContext, _reflectionMarker, _context, - _markStep, - out methodReturnValue); + _markStep); } - public static bool HandleCall ( + public static MultiValue HandleCall ( Instruction operation, MethodReference calledMethod, MultiValue instanceValue, @@ -174,8 +170,7 @@ public static bool HandleCall ( DiagnosticContext diagnosticContext, ReflectionMarker reflectionMarker, LinkContext context, - MarkStep markStep, - out MultiValue methodReturnValue) + MarkStep markStep) { var origin = diagnosticContext.Origin; var calledMethodDefinition = context.TryResolve (calledMethod); @@ -184,203 +179,15 @@ public static bool HandleCall ( Debug.Assert (callingMethodDefinition != null); bool requiresDataFlowAnalysis = context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (calledMethodDefinition); - var annotatedMethodReturnValue = context.Annotations.FlowAnnotations.GetMethodReturnValue (calledMethodDefinition); + bool isNewObj = operation.OpCode.Code == Code.Newobj; + var annotatedMethodReturnValue = context.Annotations.FlowAnnotations.GetMethodReturnValue (calledMethodDefinition, isNewObj); Debug.Assert (requiresDataFlowAnalysis || annotatedMethodReturnValue.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.None); - MultiValue? maybeMethodReturnValue = null; - - var handleCallAction = new HandleCallAction (context, reflectionMarker, diagnosticContext, callingMethodDefinition); + var handleCallAction = new HandleCallAction (context, operation, markStep, reflectionMarker, diagnosticContext, callingMethodDefinition, calledMethod); var intrinsicId = Intrinsics.GetIntrinsicIdForMethod (calledMethodDefinition); - switch (intrinsicId) { - case IntrinsicId.IntrospectionExtensions_GetTypeInfo: - case IntrinsicId.TypeInfo_AsType: - case IntrinsicId.Type_get_UnderlyingSystemType: - case IntrinsicId.Type_GetTypeFromHandle: - case IntrinsicId.Type_get_TypeHandle: - case IntrinsicId.Type_GetInterface: - case IntrinsicId.Type_get_AssemblyQualifiedName: - case IntrinsicId.RuntimeHelpers_RunClassConstructor: - case IntrinsicId.Type_GetConstructors__BindingFlags: - case IntrinsicId.Type_GetMethods__BindingFlags: - case IntrinsicId.Type_GetFields__BindingFlags: - case IntrinsicId.Type_GetProperties__BindingFlags: - case IntrinsicId.Type_GetEvents__BindingFlags: - case IntrinsicId.Type_GetNestedTypes__BindingFlags: - case IntrinsicId.Type_GetMembers__BindingFlags: - case IntrinsicId.Type_GetField: - case IntrinsicId.Type_GetProperty: - case IntrinsicId.Type_GetEvent: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeEvent: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeField: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeMethod: - case IntrinsicId.RuntimeReflectionExtensions_GetRuntimeProperty: - case IntrinsicId.Type_GetMember: - case IntrinsicId.Type_GetMethod: - case IntrinsicId.Type_GetNestedType: - case IntrinsicId.Nullable_GetUnderlyingType: - case IntrinsicId.Expression_Property: - case IntrinsicId.Expression_Field: - case IntrinsicId.Type_get_BaseType: - case IntrinsicId.Type_GetConstructor: - case IntrinsicId.MethodBase_GetMethodFromHandle: - case IntrinsicId.MethodBase_get_MethodHandle: - case IntrinsicId.Type_MakeGenericType: - case IntrinsicId.MethodInfo_MakeGenericMethod: - case IntrinsicId.Expression_Call: - case IntrinsicId.Expression_New: - case IntrinsicId.Type_GetType: - case IntrinsicId.Activator_CreateInstance__Type: - case IntrinsicId.Activator_CreateInstance__AssemblyName_TypeName: - case IntrinsicId.Activator_CreateInstanceFrom: - case IntrinsicId.AppDomain_CreateInstance: - case IntrinsicId.AppDomain_CreateInstanceAndUnwrap: - case IntrinsicId.AppDomain_CreateInstanceFrom: - case IntrinsicId.AppDomain_CreateInstanceFromAndUnwrap: - case IntrinsicId.Assembly_CreateInstance: { - return handleCallAction.Invoke (calledMethodDefinition, instanceValue, argumentValues, intrinsicId, out methodReturnValue); - } - - case IntrinsicId.None: { - if (IsPInvokeDangerous (calledMethodDefinition, context, out bool comDangerousMethod)) { - Debug.Assert (comDangerousMethod); // Currently COM dangerous is the only one we detect - diagnosticContext.AddDiagnostic (DiagnosticId.CorrectnessOfCOMCannotBeGuaranteed, calledMethodDefinition.GetDisplayName ()); - } - if (context.Annotations.DoesMethodRequireUnreferencedCode (calledMethodDefinition, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCode)) - MarkStep.ReportRequiresUnreferencedCode (calledMethodDefinition.GetDisplayName (), requiresUnreferencedCode, diagnosticContext); - - return handleCallAction.Invoke (calledMethodDefinition, instanceValue, argumentValues, intrinsicId, out methodReturnValue); - } - - case IntrinsicId.TypeDelegator_Ctor: { - // This is an identity function for analysis purposes - if (operation.OpCode == OpCodes.Newobj) - AddReturnValue (argumentValues[0]); - } - break; - - case IntrinsicId.Array_Empty: { - AddReturnValue (ArrayValue.Create (0, ((GenericInstanceMethod) calledMethod).GenericArguments[0])); - } - break; - - case IntrinsicId.Array_CreateInstance: - case IntrinsicId.Enum_GetValues: - case IntrinsicId.Marshal_SizeOf: - case IntrinsicId.Marshal_OffsetOf: - case IntrinsicId.Marshal_PtrToStructure: - case IntrinsicId.Marshal_DestroyStructure: - case IntrinsicId.Marshal_GetDelegateForFunctionPointer: - case IntrinsicId.Assembly_get_Location: - case IntrinsicId.Assembly_GetFile: - case IntrinsicId.Assembly_GetFiles: - case IntrinsicId.AssemblyName_get_CodeBase: - case IntrinsicId.AssemblyName_get_EscapedCodeBase: - case IntrinsicId.RuntimeReflectionExtensions_GetMethodInfo: - case IntrinsicId.Delegate_get_Method: - // These intrinsics are not interesting for trimmer (they are interesting for AOT and that's why they are recognized) - break; - - // - // System.Object - // - // GetType() - // - case IntrinsicId.Object_GetType: { - foreach (var valueNode in instanceValue.AsEnumerable ()) { - // Note that valueNode can be statically typed in IL as some generic argument type. - // For example: - // void Method(T instance) { instance.GetType().... } - // Currently this case will end up with null StaticType - since there's no typedef for the generic argument type. - // But it could be that T is annotated with for example PublicMethods: - // void Method<[DAM(PublicMethods)] T>(T instance) { instance.GetType().GetMethod("Test"); } - // In this case it's in theory possible to handle it, by treating the T basically as a base class - // for the actual type of "instance". But the analysis for this would be pretty complicated (as the marking - // has to happen on the callsite, which doesn't know that GetType() will be used...). - // For now we're intentionally ignoring this case - it will produce a warning. - // The counter example is: - // Method(new Derived); - // In this case to get correct results, trimmer would have to mark all public methods on Derived. Which - // currently it won't do. - - TypeDefinition? staticType = (valueNode as IValueWithStaticType)?.StaticType?.Type; - if (staticType is null) { - // We don't know anything about the type GetType was called on. Track this as a usual result of a method call without any annotations - AddReturnValue (context.Annotations.FlowAnnotations.GetMethodReturnValue (calledMethodDefinition)); - } else if (staticType.IsSealed || staticType.IsTypeOf ("System", "Delegate") || staticType.IsTypeOf ("System", "Array")) { - // We can treat this one the same as if it was a typeof() expression - - // We can allow Object.GetType to be modeled as System.Delegate because we keep all methods - // on delegates anyway so reflection on something this approximation would miss is actually safe. - - // We can also treat all arrays as "sealed" since it's not legal to derive from Array type (even though it is not sealed itself) - - // We ignore the fact that the type can be annotated (see below for handling of annotated types) - // This means the annotations (if any) won't be applied - instead we rely on the exact knowledge - // of the type. So for example even if the type is annotated with PublicMethods - // but the code calls GetProperties on it - it will work - mark properties, don't mark methods - // since we ignored the fact that it's annotated. - // This can be seen a little bit as a violation of the annotation, but we already have similar cases - // where a parameter is annotated and if something in the method sets a specific known type to it - // we will also make it just work, even if the annotation doesn't match the usage. - AddReturnValue (new SystemTypeValue (staticType)); - } else { - // Make sure the type is marked (this will mark it as used via reflection, which is sort of true) - // This should already be true for most cases (method params, fields, ...), but just in case - reflectionMarker.MarkType (origin, staticType); - - var annotation = markStep.DynamicallyAccessedMembersTypeHierarchy - .ApplyDynamicallyAccessedMembersToTypeHierarchy (staticType); - - // Return a value which is "unknown type" with annotation. For now we'll use the return value node - // for the method, which means we're loosing the information about which staticType this - // started with. For now we don't need it, but we can add it later on. - AddReturnValue (context.Annotations.FlowAnnotations.GetMethodReturnValue (calledMethodDefinition, annotation)); - } - } - } - break; - - // Note about Activator.CreateInstance - // There are 2 interesting cases: - // - The generic argument for T is either specific type or annotated - in that case generic instantiation will handle this - // since from .NET 6+ the T is annotated with PublicParameterlessConstructor annotation, so the trimming tools would apply this as for any other method. - // - The generic argument for T is unannotated type - the generic instantiantion handling has a special case for handling PublicParameterlessConstructor requirement - // in such that if the generic argument type has the "new" constraint it will not warn (as it is effectively the same thing semantically). - // For all other cases, the trimming tools would have already produced a warning. - - default: + if (!handleCallAction.Invoke (calledMethodDefinition, instanceValue, argumentValues, intrinsicId, out MultiValue methodReturnValue)) throw new NotImplementedException ($"Unhandled intrinsic: {intrinsicId}"); - } - - // If we get here, we handled this as an intrinsic. As a convenience, if the code above - // didn't set the return value (and the method has a return value), we will set it to be an - // unknown value with the return type of the method. - bool returnsVoid = calledMethod.ReturnsVoid (); - methodReturnValue = maybeMethodReturnValue ?? (returnsVoid ? - MultiValueLattice.Top : - annotatedMethodReturnValue); - - // Validate that the return value has the correct annotations as per the method return value annotations - if (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes != 0) { - foreach (var uniqueValue in methodReturnValue.AsEnumerable ()) { - if (uniqueValue is ValueWithDynamicallyAccessedMembers methodReturnValueWithMemberTypes) { - if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag (annotatedMethodReturnValue.DynamicallyAccessedMemberTypes)) - throw new InvalidOperationException ($"Internal trimming error: processing of call from {callingMethodDefinition.GetDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); - } else if (uniqueValue is SystemTypeValue) { - // SystemTypeValue can fulfill any requirement, so it's always valid - // The requirements will be applied at the point where it's consumed (passed as a method parameter, set as field value, returned from the method) - } else { - throw new InvalidOperationException ($"Internal trimming error: processing of call from {callingMethodDefinition.GetDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds."); - } - } - } - - return true; - - void AddReturnValue (MultiValue value) - { - maybeMethodReturnValue = (maybeMethodReturnValue is null) ? value : MultiValueLattice.Meet ((MultiValue) maybeMethodReturnValue, value); - } + return methodReturnValue; } static bool IsComInterop (IMarshalInfoProvider marshalInfoProvider, TypeReference parameterType, LinkContext context) @@ -449,7 +256,7 @@ void HandleAssignmentPattern ( TrimAnalysisPatterns.Add (new TrimAnalysisAssignmentPattern (value, targetValue, origin)); } - private static bool IsPInvokeDangerous (MethodDefinition methodDefinition, LinkContext context, out bool comDangerousMethod) + internal static bool IsPInvokeDangerous (MethodDefinition methodDefinition, LinkContext context, out bool comDangerousMethod) { // The method in ILLink only detects one condition - COM Dangerous, but it's structured like this // so that the code looks very similar to AOT which has more than one condition. diff --git a/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisMethodCallPattern.cs b/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisMethodCallPattern.cs index a7b42a048c7c04..417e0240a9c0a1 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisMethodCallPattern.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/TrimAnalysisMethodCallPattern.cs @@ -69,8 +69,7 @@ public void MarkAndProduceDiagnostics (ReflectionMarker reflectionMarker, MarkSt diagnosticContext, reflectionMarker, context, - markStep, - out MultiValue _); + markStep); } } } diff --git a/src/tools/illink/src/linker/Linker.Steps/DescriptorMarker.cs b/src/tools/illink/src/linker/Linker.Steps/DescriptorMarker.cs index a527ca2e0df60b..f07200ab47e4b8 100644 --- a/src/tools/illink/src/linker/Linker.Steps/DescriptorMarker.cs +++ b/src/tools/illink/src/linker/Linker.Steps/DescriptorMarker.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; @@ -23,14 +24,24 @@ public class DescriptorMarker : ProcessLinkerXmlBase static readonly string[] _accessorsAll = new string[] { "all" }; static readonly char[] _accessorsSep = new char[] { ';' }; + protected readonly HashSet _preservedMembers; + public DescriptorMarker (LinkContext context, Stream documentStream, string xmlDocumentLocation) : base (context, documentStream, xmlDocumentLocation) { + _preservedMembers = new (); } public DescriptorMarker (LinkContext context, Stream documentStream, EmbeddedResource resource, AssemblyDefinition resourceAssembly, string xmlDocumentLocation = "") : base (context, documentStream, resource, resourceAssembly, xmlDocumentLocation) { + _preservedMembers = new (); + } + + protected void LogDuplicatePreserve(string memberName, XPathNavigator duplicatePosition) + { + var origin = GetMessageOriginForPosition (duplicatePosition); + _context.LogMessage (MessageContainer.CreateInfoMessage (origin, $"Duplicate preserve of '{memberName}'")); } public void Mark () @@ -147,16 +158,16 @@ protected static TypePreserve GetTypePreserve (XPathNavigator nav) protected override void ProcessField (TypeDefinition type, FieldDefinition field, XPathNavigator nav) { - if (_context.Annotations.IsMarked (field)) - LogWarning (nav, DiagnosticId.XmlDuplicatePreserveMember, field.FullName); + if (!_preservedMembers.Add (field)) + LogDuplicatePreserve (field.FullName, nav); _context.Annotations.Mark (field, new DependencyInfo (DependencyKind.XmlDescriptor, _xmlDocumentLocation), GetMessageOriginForPosition (nav)); } protected override void ProcessMethod (TypeDefinition type, MethodDefinition method, XPathNavigator nav, object? customData) { - if (_context.Annotations.IsMarked (method)) - LogWarning (nav, DiagnosticId.XmlDuplicatePreserveMember, method.GetDisplayName ()); + if (!_preservedMembers.Add (method)) + LogDuplicatePreserve (method.GetDisplayName (), nav); _context.Annotations.MarkIndirectlyCalledMethod (method); _context.Annotations.SetAction (method, MethodAction.Parse); @@ -212,8 +223,8 @@ public static string GetMethodSignature (MethodDefinition meth, bool includeGene protected override void ProcessEvent (TypeDefinition type, EventDefinition @event, XPathNavigator nav, object? customData) { - if (_context.Annotations.IsMarked (@event)) - LogWarning (nav, DiagnosticId.XmlDuplicatePreserveMember, @event.FullName); + if (!_preservedMembers.Add (@event)) + LogDuplicatePreserve(@event.FullName, nav); ProcessMethod (type, @event.AddMethod, nav, customData); ProcessMethod (type, @event.RemoveMethod, nav, customData); @@ -224,8 +235,8 @@ protected override void ProcessProperty (TypeDefinition type, PropertyDefinition { string[] accessors = fromSignature ? GetAccessors (nav) : _accessorsAll; - if (_context.Annotations.IsMarked (property)) - LogWarning (nav, DiagnosticId.XmlDuplicatePreserveMember, property.FullName); + if (!_preservedMembers.Add (property)) + LogDuplicatePreserve(property.FullName, nav); if (Array.IndexOf (accessors, "all") >= 0) { ProcessMethodIfNotNull (type, property.GetMethod, nav, customData); diff --git a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs index 876ca9da73122b..f26a176c304120 100644 --- a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs +++ b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs @@ -60,7 +60,7 @@ protected LinkContext Context { } protected Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> _methods; - protected Dictionary _virtual_methods; + protected Dictionary _interface_methods; protected Queue _assemblyLevelAttributes; protected Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> _lateMarkedAttributes; protected List<(TypeDefinition, MarkScopeStack.Scope)> _typesWithInterfaces; @@ -219,7 +219,7 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH public MarkStep () { _methods = new Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> (); - _virtual_methods = new Dictionary (); + _interface_methods = new Dictionary (); _assemblyLevelAttributes = new Queue (); _lateMarkedAttributes = new Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> (); _typesWithInterfaces = new List<(TypeDefinition, MarkScopeStack.Scope)> (); @@ -437,7 +437,7 @@ bool ProcessPrimaryQueue () while (!QueueIsEmpty ()) { ProcessQueue (); - ProcessVirtualMethods (); + ProcessInterfaceMethods (); ProcessMarkedTypesWithInterfaces (); ProcessDynamicCastableImplementationInterfaces (); ProcessPendingBodies (); @@ -530,11 +530,11 @@ protected virtual void EnqueueMethod (MethodDefinition method, in DependencyInfo _methods.Enqueue ((method, reason, origin)); } - void ProcessVirtualMethods () + void ProcessInterfaceMethods () { - foreach ((var method, var scope) in _virtual_methods) { + foreach ((var method, var scope) in _interface_methods) { using (ScopeStack.PushLocalScope (scope)) { - ProcessVirtualMethod (method); + ProcessInterfaceMethod (method); } } } @@ -568,7 +568,7 @@ void ProcessMarkedTypesWithInterfaces () continue; foreach (var ov in baseMethods) { if (ov.Base.DeclaringType is not null && ov.Base.DeclaringType.IsInterface && IgnoreScope (ov.Base.DeclaringType.Scope)) { - _virtual_methods.TryAdd (ov.Base, ScopeStack.CurrentScope); + MarkMethodAsVirtual (ov.Base, ScopeStack.CurrentScope); } } } @@ -651,28 +651,32 @@ void ProcessPendingBodies () } } } - - void ProcessVirtualMethod (MethodDefinition method) + void MarkMethodAsVirtual (MethodDefinition method, MarkScopeStack.Scope scope) { Annotations.EnqueueVirtualMethod (method); - if (method.DeclaringType.IsInterface) { - var defaultImplementations = Annotations.GetDefaultInterfaceImplementations (method); - if (defaultImplementations is not null) { - foreach (var dimInfo in defaultImplementations) { - ProcessDefaultImplementation (dimInfo); + _interface_methods.TryAdd (method, scope); + } + } - if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (dimInfo)) - MarkMethod (dimInfo.Override, new DependencyInfo (DependencyKind.Override, dimInfo.Base), ScopeStack.CurrentScope.Origin); - } + void ProcessInterfaceMethod (MethodDefinition method) + { + Debug.Assert (method.DeclaringType.IsInterface); + var defaultImplementations = Annotations.GetDefaultInterfaceImplementations (method); + if (defaultImplementations is not null) { + foreach (var dimInfo in defaultImplementations) { + ProcessDefaultImplementation (dimInfo); + + if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (dimInfo)) + MarkMethod (dimInfo.Override, new DependencyInfo (DependencyKind.Override, dimInfo.Base), ScopeStack.CurrentScope.Origin); } - List? overridingMethods = (List?)Annotations.GetOverrides (method); - if (overridingMethods is not null) { - for (int i = 0; i < overridingMethods.Count; i++) { - OverrideInformation ov = overridingMethods[i]; - if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (ov)) - MarkMethod (ov.Override, new DependencyInfo (DependencyKind.Override, ov.Base), ScopeStack.CurrentScope.Origin); - } + } + List? overridingMethods = (List?)Annotations.GetOverrides (method); + if (overridingMethods is not null) { + for (int i = 0; i < overridingMethods.Count; i++) { + OverrideInformation ov = overridingMethods[i]; + if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (ov)) + MarkMethod (ov.Override, new DependencyInfo (DependencyKind.Override, ov.Base), ScopeStack.CurrentScope.Origin); } } } @@ -3227,7 +3231,7 @@ protected virtual void ProcessMethod (MethodDefinition method, in DependencyInfo MarkMethodSpecialCustomAttributes (method); if (method.IsVirtual) - _virtual_methods.TryAdd (method, ScopeStack.CurrentScope); + MarkMethodAsVirtual (method, ScopeStack.CurrentScope); MarkNewCodeDependencies (method); @@ -3435,7 +3439,7 @@ void MarkBaseMethods (MethodDefinition method) // This will produce warnings for all interface methods and virtual methods regardless of whether the interface, interface implementation, or interface method is kept or not. if (ov.Base.DeclaringType.IsInterface && !method.DeclaringType.IsInterface) { // These are all virtual, no need to check IsVirtual before adding to list - _virtual_methods.TryAdd (ov.Base, ScopeStack.CurrentScope); + MarkMethodAsVirtual (ov.Base, ScopeStack.CurrentScope); continue; } diff --git a/src/tools/illink/src/linker/Linker/MessageContainer.cs b/src/tools/illink/src/linker/Linker/MessageContainer.cs index eb1fe94a53cfdf..0de844bd6e8002 100644 --- a/src/tools/illink/src/linker/Linker/MessageContainer.cs +++ b/src/tools/illink/src/linker/Linker/MessageContainer.cs @@ -253,6 +253,11 @@ public static MessageContainer CreateInfoMessage (string text) return new MessageContainer (MessageCategory.Info, text, null); } + internal static MessageContainer CreateInfoMessage (MessageOrigin origin, string text) + { + return new MessageContainer (MessageCategory.Info, text, null, "", origin); + } + /// /// Create a diagnostics message. /// diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs index c3ed28034906ad..c59afbfd8fd5f7 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs @@ -186,7 +186,7 @@ public Task InlineArrayDataflow () } [Fact] - public Task InterpolatedStringHandlerDataFlow () + public Task InterpolatedStringDataFlow () { return RunTest (); } @@ -289,6 +289,12 @@ public Task MemberTypesRelationships () return RunTest (nameof (MemberTypesRelationships)); } + [Fact] + public Task MethodOutParameterDataFlow () + { + return RunTest (); + } + [Fact] public Task MethodParametersDataFlow () { @@ -313,6 +319,12 @@ public Task NullableAnnotations () return RunTest (); } + [Fact] + public Task ObjectGetTypeDataflow () + { + return RunTest (); + } + [Fact] public Task PropertyDataFlow () { diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs index a06c8115c31584..fccb0de0d95e35 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs @@ -1309,7 +1309,9 @@ public static void Main() return VerifyDynamicallyAccessedMembersAnalyzer (Source, consoleApplication: false, // (12,34): error CS0103: The name 'type' does not exist in the current context - DiagnosticResult.CompilerError ("CS0103").WithSpan (12, 34, 12, 38).WithArguments ("type")); + DiagnosticResult.CompilerError ("CS0103").WithSpan (12, 34, 12, 38).WithArguments ("type"), + // (12,34): warning IL2063: Value returned from method 'C.GetTypeWithAll()' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic (DiagnosticId.MethodReturnValueCannotBeStaticallyDetermined).WithSpan(12, 34, 12, 38).WithArguments("C.GetTypeWithAll()")); } [Fact] @@ -1333,7 +1335,9 @@ public static void Main() return VerifyDynamicallyAccessedMembersAnalyzer (Source, consoleApplication: false, // (8,22): error CS0103: The name 'type' does not exist in the current context - DiagnosticResult.CompilerError ("CS0103").WithSpan (8, 22, 8, 26).WithArguments ("type")); + DiagnosticResult.CompilerError ("CS0103").WithSpan (8, 22, 8, 26).WithArguments ("type"), + // (8,3): warning IL2064: Value assigned to C.fieldRequiresAll can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements. + VerifyCS.Diagnostic(DiagnosticId.FieldValueCannotBeStaticallyDetermined).WithSpan(8, 3, 8, 26).WithArguments("C.fieldRequiresAll")); } [Fact] diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs index 7631b802fbcc87..c50d24f136051d 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text.RegularExpressions; @@ -66,7 +67,7 @@ public void Check (bool allowMissingWarnings) } if (message.Length > 0) { - Assert.Fail(message); + Assert.Fail (message); } } @@ -207,51 +208,62 @@ private void ValidateDiagnostics (CSharpSyntaxNode memberSyntax, SyntaxList arg.Key.StartsWith ('#')).Count () - 2; + if (args.TryGetValue ($"#{toolArg}", out var maybeProducedBy) && TryGetProducedBy (maybeProducedBy, out Tool producedByTool)) { + return producedByTool.HasFlag (Tool.Analyzer); + } return true; default: return false; } - static Tool GetProducedBy (ExpressionSyntax expression) + static bool TryGetProducedBy (ExpressionSyntax expression, out Tool producedBy) { - var producedBy = (Tool) 0x0; + producedBy = (Tool) 0x0; switch (expression) { - case BinaryExpressionSyntax binaryExpressionSyntax: + case BinaryExpressionSyntax binaryExpressionSyntax when binaryExpressionSyntax.Kind () == SyntaxKind.BitwiseOrExpression: if (!Enum.TryParse ((binaryExpressionSyntax.Left as MemberAccessExpressionSyntax)!.Name.Identifier.ValueText, out var besProducedBy)) - throw new ArgumentException ("Expression must be a ProducedBy value", nameof (expression)); + return false; producedBy |= besProducedBy; producedBy |= GetProducedBy (binaryExpressionSyntax.Right); break; case MemberAccessExpressionSyntax memberAccessExpressionSyntax: if (!Enum.TryParse (memberAccessExpressionSyntax.Name.Identifier.ValueText, out var maeProducedBy)) - throw new ArgumentException ("Expression must be a ProducedBy value", nameof (expression)); + return false; producedBy |= maeProducedBy; break; default: - break; + return false; } - return producedBy; + return true; + } + + static Tool GetProducedBy (ExpressionSyntax expression) + { + return TryGetProducedBy (expression, out var tool) ? tool : throw new ArgumentException ("Expression must be a ProducedBy value", nameof (expression)); } } bool TryValidateExpectedDiagnostic (AttributeSyntax attribute, List diagnostics, [NotNullWhen (true)] out int? matchIndex, [NotNullWhen (false)] out string? missingDiagnosticMessage) { - switch (attribute.Name.ToString ()) { - case "ExpectedWarning": + switch (attribute.Name.ToString () + "Attribute") { + case nameof (ExpectedWarningAttribute): + case nameof (UnexpectedWarningAttribute): return TryValidateExpectedWarningAttribute (attribute!, diagnostics, out matchIndex, out missingDiagnosticMessage); - case "LogContains": + case nameof (LogContainsAttribute): return TryValidateLogContainsAttribute (attribute!, diagnostics, out matchIndex, out missingDiagnosticMessage); default: throw new InvalidOperationException ($"Unsupported attribute type {attribute.Name}"); @@ -268,10 +280,29 @@ private bool TryValidateExpectedWarningAttribute (AttributeSyntax attribute, Lis if (!expectedWarningCode.StartsWith ("IL")) throw new InvalidOperationException ($"Expected warning code should start with \"IL\" prefix."); - List expectedMessages = args - .Where (arg => arg.Key.StartsWith ("#") && arg.Key != "#0") - .Select (arg => LinkerTestBase.GetStringFromExpression (arg.Value, _semanticModel)) - .ToList (); + List expectedMessages = ((IMethodSymbol) (_semanticModel.GetSymbolInfo (attribute).Symbol!)).Parameters switch { + // ExpectedWarningAttribute(string warningCode, params string[] expectedMessages) + [_, { IsParams: true }] + => args + .Where (arg => arg.Key.StartsWith ('#') && arg.Key != "#0") + .Select (arg => LinkerTestBase.GetStringFromExpression (arg.Value, _semanticModel)) + .ToList (), + // ExpectedWarningAttribute(string warningCode, string[] expectedMessages, Tool producedBy, string issueLink) + [_, { Type.TypeKind: TypeKind.Array }, _, _] + => ((CollectionExpressionSyntax) args["#1"]).Elements + .Select (arg => LinkerTestBase.GetStringFromExpression (((ExpressionElementSyntax) arg).Expression, _semanticModel)) + .ToList (), + // ExpectedWarningAttribute(string warningCode, string expectedMessage, Tool producedBy, string issueLink) + [_, { Type.SpecialType: SpecialType.System_String }, _, _] + => [LinkerTestBase.GetStringFromExpression (args["#1"], _semanticModel)], + // ExpectedWarningAttribute(string warningCode, string expectedMessage1, string expectedMessage2, Tool producedBy, string issueLink) + [_, { Type.SpecialType: SpecialType.System_String }, { Type.SpecialType: SpecialType.System_String }, _, _] + => [LinkerTestBase.GetStringFromExpression (args["#1"], _semanticModel), LinkerTestBase.GetStringFromExpression (args["#2"], _semanticModel)], + // ExpectedWarningAttribute(string warningCode, Tool producedBy, string issueLink) + [_, _, _] + => [], + _ => throw new UnreachableException (), + }; for (int i = 0; i < diagnostics.Count; i++) { if (Matches (diagnostics[i])) { @@ -318,7 +349,7 @@ private void ValidateLogDoesNotContainAttribute (AttributeSyntax attribute, IRea Assert.False (args.ContainsKey ("#1")); _ = LinkerTestBase.GetStringFromExpression (arg, _semanticModel); if (LogContains (attribute, diagnosticMessages, out var matchIndex, out var findText)) { - Assert.Fail($"LogDoesNotContain failure: Text\n\"{findText}\"\nfound in diagnostic:\n {diagnosticMessages[(int) matchIndex]}"); + Assert.Fail ($"LogDoesNotContain failure: Text\n\"{findText}\"\nfound in diagnostic:\n {diagnosticMessages[(int) matchIndex]}"); } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs index 0a390275ea81c4..8f435261c79396 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs @@ -19,24 +19,12 @@ public Task GenericParameterDataFlowMarking () return RunTest (allowMissingWarnings: true); } - [Fact] - public Task MakeGenericDataflowIntrinsics () - { - return RunTest (allowMissingWarnings: true); - } - [Fact] public Task MethodByRefParameterDataFlow () { return RunTest (allowMissingWarnings: true); } - [Fact] - public Task MethodOutParameterDataFlow () - { - return RunTest (allowMissingWarnings: true); - } - [Fact] public Task StaticInterfaceMethodDataflow () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs index 648241200ef16a..19b785adabcc06 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs @@ -9,8 +9,27 @@ namespace Mono.Linker.Tests.Cases.Expectations.Assertions AttributeTargets.Assembly | AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Event, AllowMultiple = true, Inherited = false)] + /// + /// An attribute applied to a member to indicate that a warning is expected in ideal behavior, and is present in all tools + /// public class ExpectedWarningAttribute : EnableLoggerAttribute { + public ExpectedWarningAttribute (string warningCode, string[] messageContains, Tool producedBy, string issueLinkOrReason) + { + } + + public ExpectedWarningAttribute (string warningCode, string messageContains, Tool producedBy, string issueLinkOrReason) + { + } + + public ExpectedWarningAttribute (string warningCode, string messageContains, string messageContains2, Tool producedBy, string issueLinkOrReason) + { + } + + public ExpectedWarningAttribute (string warningCode, Tool producedBy, string issueLinkOrReason) + { + } + public ExpectedWarningAttribute (string warningCode, params string[] messageContains) { } @@ -19,12 +38,6 @@ public ExpectedWarningAttribute (string warningCode, params string[] messageCont public int SourceLine { get; set; } public int SourceColumn { get; set; } - /// - /// Property used by the result checkers of trimmer and analyzers to determine whether - /// the tool should have produced the specified warning on the annotated member. - /// - public Tool ProducedBy { get; set; } = Tool.TrimmerAnalyzerAndNativeAot; - public bool CompilerGeneratedCode { get; set; } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/UnexpectedWarningAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/UnexpectedWarningAttribute.cs new file mode 100644 index 00000000000000..d745b61f3a1675 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Assertions/UnexpectedWarningAttribute.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage ( + AttributeTargets.Assembly | AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Event, + AllowMultiple = true, + Inherited = false)] + /// + /// An attribute applied to a member to indicate that a warning is raised in tests, but should not be present in ideal behavior + /// + public class UnexpectedWarningAttribute : ExpectedWarningAttribute + { + public UnexpectedWarningAttribute (string warningCode, string[] messageContains, Tool producedBy, string issueLinkOrReason) + : base (warningCode, messageContains, producedBy, issueLinkOrReason) { } + public UnexpectedWarningAttribute (string warningCode, string messageContains, Tool producedBy, string issueLinkOrReason) + : base (warningCode, messageContains, producedBy, issueLinkOrReason) { } + public UnexpectedWarningAttribute (string warningCode, string messageContains, string messageContains2, Tool producedBy, string issueLinkOrReason) + : base (warningCode, messageContains, messageContains2, producedBy, issueLinkOrReason) { } + public UnexpectedWarningAttribute (string warningCode, Tool producedBy, string issueLinkOrReason) + : base (warningCode, producedBy, issueLinkOrReason) { } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs index c2e77e98f8d445..8638267f26acc3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs @@ -5,7 +5,7 @@ namespace Mono.Linker.Tests.Cases.Expectations.Helpers { public static class PlatformAssemblies { -#if NETCOREAPP +#if NET public const string CoreLib = "System.Private.CoreLib.dll"; #else public const string CoreLib = "mscorlib.dll"; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTarget.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTarget.cs index ff3d0937d56137..f0c6c8cd4deefd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTarget.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTarget.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Debugger.KeepDebugMembers { [SetupLinkerTrimMode ("link")] -#if !NETCOREAPP +#if !NET [SetupLinkerKeepDebugMembers ("true")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInSameAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInSameAssembly.cs index 31a098588c05bf..e6da349605d78b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInSameAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInSameAssembly.cs @@ -9,7 +9,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Debugger.KeepDebugMembers { [SetupLinkerTrimMode ("link")] -#if !NETCOREAPP +#if !NET [SetupLinkerKeepDebugMembers ("true")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfGenericTypeInOtherAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfGenericTypeInOtherAssembly.cs index db44758dbb2acf..0f88184ecf3a70 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfGenericTypeInOtherAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfGenericTypeInOtherAssembly.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Debugger.KeepDebugMembers { [SetupLinkerTrimMode ("link")] -#if !NETCOREAPP +#if !NET [SetupLinkerKeepDebugMembers ("true")] #endif [SetupCompileBefore ("library.dll", new[] { "../Dependencies/DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInOtherAssembly_Lib.cs" })] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeThatIsNotUsed.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeThatIsNotUsed.cs index af5922ed8fe707..8e65562af475ce 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeThatIsNotUsed.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayAttributeOnTypeThatIsNotUsed.cs @@ -4,7 +4,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Debugger.KeepDebugMembers { -#if !NETCOREAPP +#if !NET [SetupLinkerKeepDebugMembers ("true")] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType.cs index 71ed65a23c0eb2..6e13271e867904 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType.cs @@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Debugger.KeepDebugMembers { -#if !NETCOREAPP +#if !NET [SetupLinkerKeepDebugMembers ("true")] #endif public class DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToMethodOnFieldType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToMethodOnFieldType.cs index 156bdb28e78c0f..e2fe84975f7c57 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToMethodOnFieldType.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes.Debugger/KeepDebugMembers/DebuggerDisplayOnTypeWithCallToMethodOnFieldType.cs @@ -4,7 +4,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Debugger.KeepDebugMembers { -#if !NETCOREAPP +#if !NET [SetupLinkerKeepDebugMembers ("true")] #endif public class DebuggerDisplayOnTypeWithCallToMethodOnFieldType diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs index e4d0bf419cc3d0..d86d4bf3fbd65a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/CoreLibraryAssemblyAttributesAreKept.cs @@ -13,7 +13,7 @@ namespace Mono.Linker.Tests.Cases.Attributes [SetupLinkerArgument ("--skip-unresolved", "true")] [KeptAttributeInAssembly (PlatformAssemblies.CoreLib, typeof (AssemblyDescriptionAttribute))] [KeptAttributeInAssembly (PlatformAssemblies.CoreLib, typeof (AssemblyCompanyAttribute))] -#if !NETCOREAPP +#if !NET [KeptAttributeInAssembly ("System.dll", typeof (AssemblyDescriptionAttribute))] [KeptAttributeInAssembly ("System.dll", typeof (AssemblyCompanyAttribute))] #endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs index 64e046ec77106d..44ab4218270abb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUnusedAssemblyAttributesAreRemoved.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed [SetupLinkerTrimMode ("link")] [SetupLinkerArgument ("--used-attrs-only", "true")] [RemovedAttributeInAssembly (PlatformAssemblies.CoreLib, typeof (AssemblyDescriptionAttribute))] -#if !NETCOREAPP +#if !NET [RemovedAttributeInAssembly ("System.dll", typeof (AssemblyDescriptionAttribute))] #endif public class CoreLibraryUnusedAssemblyAttributesAreRemoved diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs index bbbbe72db926d2..f3c70ec1a38dcf 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/CoreLibraryUsedAssemblyAttributesAreKept.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed [SetupLinkerTrimMode ("link")] [SetupLinkerArgument ("--used-attrs-only", "true")] [KeptAttributeInAssembly (PlatformAssemblies.CoreLib, typeof (AssemblyDescriptionAttribute))] -#if !NETCOREAPP +#if !NET [KeptAttributeInAssembly ("System.dll", typeof (AssemblyDescriptionAttribute))] #endif public class CoreLibraryUsedAssemblyAttributesAreKept diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/TypeWithDynamicInterfaceCastableImplementationAttributeIsKept.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/TypeWithDynamicInterfaceCastableImplementationAttributeIsKept.cs index c6dd27cb57553a..51be76c9f7fab1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/TypeWithDynamicInterfaceCastableImplementationAttributeIsKept.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Attributes/TypeWithDynamicInterfaceCastableImplementationAttributeIsKept.cs @@ -22,7 +22,7 @@ public class TypeWithDynamicInterfaceCastableImplementationAttributeIsKept { public static void Main () { -#if NETCOREAPP +#if NET Foo foo = new Foo (); GetBar (foo).Bar (); IReferenced baz = GetBaz (foo); @@ -32,7 +32,7 @@ public static void Main () #endif } -#if NETCOREAPP +#if NET [Kept] private static IReferencedAndCalled GetBar (object obj) { @@ -53,7 +53,7 @@ static IReferencedAssembly GetReferencedInterface (object obj) #endif } -#if NETCOREAPP +#if NET [Kept] [KeptMember (".ctor()")] [KeptInterface (typeof (IDynamicInterfaceCastable))] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/CoreLink/InvalidIsTrimmableAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/CoreLink/InvalidIsTrimmableAttribute.cs index 35463fd52d442f..57b000fe3d377e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/CoreLink/InvalidIsTrimmableAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/CoreLink/InvalidIsTrimmableAttribute.cs @@ -29,4 +29,4 @@ public static void Unused () { } } -} \ No newline at end of file +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs index d3fcbf32df47e5..f071090462b2e4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; +using System.Reflection; using System.Runtime.InteropServices; using Mono.Linker.Tests.Cases.DataFlow; using Mono.Linker.Tests.Cases.Expectations.Assertions; @@ -54,8 +55,8 @@ static void ReflectionReadOnly () typeof (AnnotatedField).GetField ("_annotatedField").GetValue (null); } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 - [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // DynamicDependency is not supported yet in the analyzer + [ExpectedWarning ("IL2110", nameof (_annotatedField), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (AnnotatedField))] static void DynamicDependency () { @@ -67,8 +68,8 @@ static void DynamicDependencySuppressedByRUC () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 - [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // DynamicDependency is not supported yet in the analyzer + [ExpectedWarning ("IL2110", nameof (_annotatedField), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] [DynamicDependency (nameof (_annotatedField), typeof (AnnotatedField))] static void DynamicDependencyByName () { @@ -128,8 +129,7 @@ static void PotentialWriteAccess (ref Type type) { } - // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2110", nameof (AnnotatedField._annotatedField), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2110", nameof (AnnotatedField._annotatedField), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/3172")] static void LdToken () { Expression a = () => PotentialWriteAccess (ref _annotatedField); @@ -177,7 +177,7 @@ void LdftnOnLambda () { var _ = new Action ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - () => MethodWithAnnotatedThisParameter ()); + () => MethodWithAnnotatedThisParameter ()); } [ExpectedWarning ("IL2111")] @@ -233,8 +233,8 @@ static void AnnotatedAttributeConstructor () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // DynamicDependency is not supported yet in the analyzer + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodParameters))] static void DynamicDependency () { @@ -246,8 +246,8 @@ static void DynamicDependencySuppressedByRUC () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // DynamicDependency is not supported yet in the analyzer + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] [DynamicDependency (nameof (MethodWithSingleAnnotatedParameter), typeof (AnnotatedMethodParameters))] static void DynamicDependencyByName () { @@ -278,7 +278,7 @@ static void LdftnSuppressedByRequiresUnreferencedCode () } [ExpectedWarning ("IL2111")] - static void + static void LdftnOnLambda () { var _ = new Action ( @@ -299,7 +299,7 @@ static void LdftnOnLambdaTriggersLamdaAnalysis () { var _ = new Action ( [ExpectedWarning ("IL2067", nameof (type), nameof (DataFlowTypeExtensions.RequiresAll))] - (Type type) => { type.RequiresAll (); }); + (Type type) => { type.RequiresAll (); }); } static void LdftnOnLocalMethodTriggersLocalMethodAnalysis () @@ -332,8 +332,8 @@ static void Ldvirtftn () [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))] [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))] - [ExpectedWarning ("IL2118", nameof (LdftnOnLambdaTriggersLamdaAnalysis), ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", nameof (LdftnOnLocalMethodTriggersLocalMethodAnalysis), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", nameof (LdftnOnLambdaTriggersLamdaAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")] + [ExpectedWarning ("IL2118", nameof (LdftnOnLocalMethodTriggersLocalMethodAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")] static void DynamicallyAccessedMembersAll1 () { typeof (AnnotatedMethodParameters).RequiresAll (); @@ -346,16 +346,15 @@ static void DynamicallyAccessedMembersAll1 () [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))] [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))] - [ExpectedWarning ("IL2118", nameof (LdftnOnLambdaTriggersLamdaAnalysis), ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", nameof (LdftnOnLocalMethodTriggersLocalMethodAnalysis), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", nameof (LdftnOnLambdaTriggersLamdaAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")] + [ExpectedWarning ("IL2118", nameof (LdftnOnLocalMethodTriggersLocalMethodAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")] static void DynamicallyAccessedMembersAll2 () { typeof (AnnotatedMethodParameters).RequiresAll (); } - // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2067", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/3172")] + [UnexpectedWarning ("IL2067", nameof (MethodWithSingleAnnotatedParameter), Tool.Analyzer, "https://github.com/dotnet/linker/issues/3172")] static void LdToken () { Expression> _ = (Type t) => MethodWithSingleAnnotatedParameter (t); @@ -420,8 +419,7 @@ static void ReflectionOnVirtualSuppressedByRUC () typeof (AnnotatedMethodReturnValue).GetMethod (nameof (VirtualMethodWithAnnotatedReturnValue)).Invoke (null, null); } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodReturnValue))] static void DynamicDependency () { @@ -443,8 +441,7 @@ static void DynamicDependencyByNameOnInstance () { } - // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] [DynamicDependency (nameof (VirtualMethodWithAnnotatedReturnValue), typeof (AnnotatedMethodReturnValue))] static void DynamicDependencyByNameOnVirtual () { @@ -483,8 +480,7 @@ static void LdTokenOnStatic () Expression _ = () => StaticMethodWithAnnotatedReturnValue (); } - // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/3172")] static void LdTokenOnVirtual () { Expression> _ = (a) => a.VirtualMethodWithAnnotatedReturnValue (); @@ -527,7 +523,7 @@ class AnnotatedProperty public virtual Type VirtualProperty4WithAnnotation { get => null; set { value.ToString (); } } public static Type Property5WithAnnotationOnMembers { - [ExpectedWarning ("IL2078", nameof (Property5WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2078", nameof (Property5WithAnnotationOnMembers) + ".get", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/101191")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] get; [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] @@ -596,13 +592,13 @@ static void AnnotatedAttributeProperty () } // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/runtime/issues/83080 - [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/83080")] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (AnnotatedProperty))] static void DynamicDependency () { @@ -685,15 +681,15 @@ static void DynamicallyAccessedMembersAll2 () typeof (AnnotatedProperty).RequiresAll (); } - // Analyzer doesn't produce this warning https://github.com/dotnet/linker/issues/2628 - [ExpectedWarning ("IL2110", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // Analyzer doesn't produce this warning + [ExpectedWarning ("IL2110", nameof (Property1WithAnnotation), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2628")] static void DynamicallyAccessedFields () { typeof (AnnotatedProperty).RequiresNonPublicFields (); } - // Action delegate is not handled correctly https://github.com/dotnet/runtime/issues/84918 - [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // Analyzer doesn't recognize Linq.Expressions + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/101148")] static void LdToken () { Expression> _ = () => Property1WithAnnotation; @@ -835,8 +831,7 @@ static void DynamicallyAccessedMembersAll2 () typeof (AnnotationOnGenerics).RequiresAll (); } - // https://github.com/dotnet/linker/issues/3172 - [ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2111", ["GenericWithAnnotatedMethod", "AnnotatedMethod"], Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/3172")] static void LdToken () { // Note that this should warn even though the code looks "Correct" @@ -867,13 +862,13 @@ struct ValueWithAnnotatedField public Type _typeField; } - // Analyzer doesn't take into account interop attributes https://github.com/dotnet/linker/issues/2562 - [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), ProducedBy = Tool.Trimmer)] + // Analyzer doesn't take into account interop attributes + [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), Tool.Trimmer, "https://github.com/dotnet/linker/issues/2562")] [DllImport ("nonexistent")] static extern ValueWithAnnotatedField GetValueWithAnnotatedField (); - // Analyzer doesn't take into account interop attributes https://github.com/dotnet/linker/issues/2562 - [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), ProducedBy = Tool.Trimmer)] + // Analyzer doesn't take into account interop attributes + [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), Tool.Trimmer, "https://github.com/dotnet/linker/issues/2562")] [DllImport ("nonexistent")] static extern void AcceptValueWithAnnotatedField (ValueWithAnnotatedField value); @@ -899,29 +894,28 @@ class DelegateCreation static void TestField () { var d = new UnannotatedDelegate (field); - d(typeof(int)); + d (typeof (int)); } static void TestProperty () { var d = new UnannotatedDelegate (Property); - d(typeof(int)); + d (typeof (int)); } [ExpectedWarning ("IL2111")] static void TestLambda () { var d = new UnannotatedDelegate ( - ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type t) => - { }); - d(typeof(int)); + ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type t) => { }); + d (typeof (int)); } [ExpectedWarning ("IL2111", "LocalMethod")] static void TestLocalMethod () { var d = new UnannotatedDelegate (LocalMethod); - d(typeof(int)); + d (typeof (int)); void LocalMethod ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) @@ -931,14 +925,14 @@ void LocalMethod ( static void TestMethodReturnValue () { var d = new UnannotatedDelegate (MethodReturnValue ()); - d(typeof(int)); + d (typeof (int)); } static void TestEvent () { var d = new UnannotatedDelegate (Event); - d(typeof(int)); + d (typeof (int)); } public static void Test () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaUnsafeAccessor.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaUnsafeAccessor.cs index 9b8cd8959651b0..eb016da603f4c6 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaUnsafeAccessor.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaUnsafeAccessor.cs @@ -54,7 +54,7 @@ private static void MethodWithAnnotationMismatch ([DynamicallyAccessedMembers (D private static Type FieldWithAnnotationMismatch; } - [ExpectedWarning ("IL2111", ProducedBy = Tool.Trimmer)] + [UnexpectedWarning ("IL2111", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/101195")] [UnsafeAccessor (UnsafeAccessorKind.StaticMethod)] extern static void MethodWithAnnotatedParameter (Target target, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type); @@ -63,23 +63,23 @@ private static void MethodWithAnnotationMismatch ([DynamicallyAccessedMembers (D [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] extern static Type StaticMethodWithAnnotatedReturnValue (Target target); - [ExpectedWarning ("IL2111", ProducedBy = Tool.Trimmer)] + [UnexpectedWarning ("IL2111", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/101195")] [UnsafeAccessor (UnsafeAccessorKind.Method)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] extern static Type VirtualMethodWithAnnotatedReturnValue (Target target); - [ExpectedWarning ("IL2110", ProducedBy = Tool.Trimmer)] + [UnexpectedWarning ("IL2110", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/101195")] [UnsafeAccessor (UnsafeAccessorKind.StaticField)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] extern static ref Type AnnotatedField (Target target); - [ExpectedWarning ("IL2111", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2067", ProducedBy = Tool.NativeAot)] + [UnexpectedWarning ("IL2111", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/101195")] + [ExpectedWarning ("IL2067", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/101195")] [UnsafeAccessor (UnsafeAccessorKind.StaticMethod)] extern static void MethodWithAnnotationMismatch (Target target, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type); - [ExpectedWarning ("IL2110", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2078", ProducedBy = Tool.NativeAot)] + [UnexpectedWarning ("IL2110", Tool.Trimmer, "https://github.com/dotnet/runtime/issues/101195")] + [ExpectedWarning ("IL2078", Tool.NativeAot, "https://github.com/dotnet/runtime/issues/101195")] [UnsafeAccessor (UnsafeAccessorKind.StaticField)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] extern static ref Type FieldWithAnnotationMismatch (Target target); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs index 1fc103037b3886..b819d459758530 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ArrayDataFlow.cs @@ -117,13 +117,10 @@ static void TestArraySetElementOneElementMix () arr[0].RequiresAll (); } - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), Tool.Analyzer, "")] // https://github.com/dotnet/linker/issues/2737 - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArraySetElementOneElementMerged () { Type[] arr = new Type[1]; @@ -210,14 +207,9 @@ static void TestGetElementAtUnknownIndex (int i = 0) arr[i].RequiresPublicFields (); } - // https://github.com/dotnet/runtime/issues/93416 tracks the discrepancy between - // the analyzer and ILLink/ILCompiler. - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (GetMethods), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetFields), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] + [UnexpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/93416")] + [ExpectedWarning ("IL2072", [nameof (GetMethods), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "https://github.com/dotnet/runtime/issues/93416")] + [ExpectedWarning ("IL2072", [nameof (GetFields), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "https://github.com/dotnet/runtime/issues/93416")] static void TestGetMergedArrayElement (bool b = true) { Type[] arr = new Type[] { GetMethods () }; @@ -227,8 +219,8 @@ static void TestGetMergedArrayElement (bool b = true) arr[0].RequiresAll (); } - // Trimmer code doesnt handle locals from different branches separetely, therefore merges incorrectly GetMethods with Unknown producing both warnings - [ExpectedWarning ("IL2072", nameof (ArrayDataFlow.GetMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // Trimmer code doesn't handle locals from different branches separately, therefore merges incorrectly GetMethods with Unknown producing both warnings + [UnexpectedWarning ("IL2072", nameof (ArrayDataFlow.GetMethods), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/93416")] [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll))] static void TestMergedArrayElementWithUnknownIndex (int i) { @@ -252,9 +244,9 @@ static void TestArrayResetStoreUnknownIndex (int i = 0) } // https://github.com/dotnet/linker/issues/2680 - analyzer doesn't reset array in this case - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] // https://github.com/dotnet/linker/issues/2680 - analyzer doesn't reset array in this case - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayResetGetElementOnByRefArray (int i = 0) { Type[] arr = new Type[] { typeof (TestType), typeof (TestType) }; @@ -286,7 +278,7 @@ static void TestArrayResetAfterCall () static void TakesTypesArray (Type[] types) { } // https://github.com/dotnet/linker/issues/2680 - // [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + // [ExpectedSharedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields))] static void TestArrayResetAfterAssignment () { Type[] arr = new Type[] { typeof (TestType) }; @@ -344,9 +336,9 @@ public static void Test () TestAddressOfElement (); } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayWithInitializerOneElementStaticType () { Type[,] arr = new Type[,] { { typeof (TestType) } }; @@ -354,9 +346,9 @@ static void TestArrayWithInitializerOneElementStaticType () arr[0, 1].RequiresPublicMethods (); // Should warn - unknown value at this index } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayWithInitializerOneElementParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) { Type[,] arr = new Type[,] { { type } }; @@ -364,11 +356,11 @@ static void TestArrayWithInitializerOneElementParameter ([DynamicallyAccessedMem arr[0, 1].RequiresPublicMethods (); // Should warn - unknown value at this index } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Below are because we do not handle Multi dimensional arrays - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayWithInitializerMultipleElementsStaticType () { Type[,] arr = new Type[,] { { typeof (TestType), typeof (TestType), typeof (TestType) } }; @@ -379,13 +371,13 @@ static void TestArrayWithInitializerMultipleElementsStaticType () } // Bug - // [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Below are because we do not handle Multi dimensional arrays - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayWithInitializerMultipleElementsMix<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] TProperties> ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeAll) { @@ -397,9 +389,9 @@ static void TestArrayWithInitializerMultipleElementsStaticType () arr[0, 3].RequiresPublicMethods (); // Should warn - unknown value at this index } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArraySetElementOneElementStaticType () { Type[,] arr = new Type[1, 1]; @@ -408,9 +400,9 @@ static void TestArraySetElementOneElementStaticType () arr[0, 1].RequiresPublicMethods (); // Should warn - unknown value at this index } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArraySetElementOneElementParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) { Type[,] arr = new Type[1, 1]; @@ -419,11 +411,11 @@ static void TestArraySetElementOneElementParameter ([DynamicallyAccessedMembers arr[0, 1].RequiresPublicMethods (); // Should warn - unknown value at this index } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Below are because we do not handle Multi dimensional arrays - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArraySetElementMultipleElementsStaticType () { Type[,] arr = new Type[1, 3]; @@ -437,13 +429,13 @@ static void TestArraySetElementMultipleElementsStaticType () } // Bug - // [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Below are because we do not handle Multi dimensional arrays - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArraySetElementMultipleElementsMix<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] TProperties> ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeAll) { @@ -459,13 +451,13 @@ static void TestArraySetElementMultipleElementsStaticType () } // Bug - // [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + // [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] // Below are because we do not handle Multi dimensional arrays - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArraySetElementAndInitializerMultipleElementsMix<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] TProperties> ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeAll) { @@ -479,16 +471,16 @@ static void TestArraySetElementMultipleElementsStaticType () arr[0, 3].RequiresPublicMethods (); // Should warn - unknown value at this index } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] static void TestGetElementAtUnknownIndex (int i = 0) { Type[,] arr = new Type[,] { { typeof (TestType) } }; arr[0, i].RequiresPublicFields (); } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayResetStoreUnknownIndex (int i = 0) { Type[,] arr = new Type[,] { { typeof (TestType) } }; @@ -500,11 +492,11 @@ static void TestArrayResetStoreUnknownIndex (int i = 0) } // https://github.com/dotnet/linker/issues/2680 - analyzer doesn't reset array in this case - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayResetGetElementOnByRefArray (int i = 0) { Type[,] arr = new Type[,] { { typeof (TestType) } }; @@ -519,9 +511,9 @@ static void TestArrayResetGetElementOnByRefArray (int i = 0) static void TakesTypeByRef (ref Type type) { } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayResetAfterCall () { Type[,] arr = new Type[,] { { typeof (TestType) } }; @@ -537,9 +529,9 @@ static void TestArrayResetAfterCall () static void TakesTypesArray (Type[,] types) { } // https://github.com/dotnet/linker/issues/2680 - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "")] // Multidimensional Arrays not handled -- assumed to be UnknownValue - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicProperties), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayResetAfterAssignment () { Type[,] arr = new Type[,] { { typeof (TestType) } }; @@ -553,7 +545,7 @@ static void TestArrayResetAfterAssignment () arr[0, 0].RequiresPublicFields (); // Should warn } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] static void TestAddressOfElement () { Type[,] arr = new Type[,] { { typeof (TestType) } }; @@ -566,13 +558,10 @@ static void TestAddressOfElement () class WriteCapturedArrayElement { - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), Tool.Analyzer, "")] // https://github.com/dotnet/linker/issues/2737 - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestNullCoalesce () { Type[] arr = new Type[1]; @@ -590,11 +579,9 @@ static void TestNullCoalescingAssignment () arr[0].RequiresAll (); } - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Analyzer, "")] // https://github.com/dotnet/linker/issues/2746 - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestNullCoalescingAssignmentToEmpty () { Type[] arr = new Type[1]; @@ -604,10 +591,8 @@ static void TestNullCoalescingAssignmentToEmpty () [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (DataFlowTypeExtensions.RequiresAll))] // https://github.com/dotnet/linker/issues/2746 (ILLink produces incomplete set of IL2072 warnings) - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), Tool.Analyzer, "")] static void TestNullCoalescingAssignmentComplex () { Type[] arr = new Type[1]; @@ -702,7 +687,7 @@ static void TestNullCoalesce (bool b = false) arr2[0].RequiresPublicFields (); } - [ExpectedWarning ("IL2087", nameof (T), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2087", [nameof (T), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] [ExpectedWarning ("IL2087", nameof (U), nameof (DataFlowTypeExtensions.RequiresPublicFields))] // Missing warnings for 'V' possibly assigned to arr or arr2 because write to temp // array isn't reflected back in the local variables. https://github.com/dotnet/linker/issues/2158 @@ -710,8 +695,8 @@ static void TestNullCoalesce (bool b = false) // possible assignment of arr2 to arr, without overwriting index '0'. And it produces a warning // for each possible value, unlike ILLink/ILCompiler, which produce an unknown value for a merged // array value: https://github.com/dotnet/runtime/issues/93416 - [ExpectedWarning ("IL2087", nameof (U), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2087", [nameof (U), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestNullCoalescingAssignment (bool b = true) { Type[]? arr = new Type[1] { typeof (T) }; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs index f2c0f5185f5cf2..c6dbd60598c608 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs @@ -58,10 +58,7 @@ static void TestConstructors () RequireNothing (type); } - [ExpectedWarning ("IL2105", - "Type 'System.Invalid.TypeName' was not found in the caller assembly nor in the base library. " + - "Type name strings used for dynamically accessing a type should be assembly qualified.", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2105", "Type 'System.Invalid.TypeName' was not found in the caller assembly nor in the base library. " + "Type name strings used for dynamically accessing a type should be assembly qualified.", Tool.Trimmer | Tool.NativeAot, "")] static void TestUnqualifiedTypeNameWarns () { RequirePublicConstructors ("System.Invalid.TypeName"); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs index 4611e06773df85..5f54d6dd471262 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs @@ -9,7 +9,7 @@ [assembly: KeptAttributeAttribute (typeof (AttributeConstructorDataflow.KeepsPublicPropertiesAttribute))] // https://github.com/dotnet/linker/issues/2273 -[assembly: ExpectedWarning ("IL2026", "--ClassWithKeptPublicProperties--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] +[assembly: ExpectedWarning ("IL2026", "--ClassWithKeptPublicProperties--", Tool.Trimmer | Tool.NativeAot, "")] [assembly: AttributeConstructorDataflow.KeepsPublicProperties (typeof (AttributeConstructorDataflow.ClassWithKeptPublicProperties))] namespace Mono.Linker.Tests.Cases.DataFlow @@ -27,7 +27,7 @@ class AttributeConstructorDataflow [KeepsPublicFields (null, null)] [TypeArray (new Type[] { typeof (AttributeConstructorDataflow) })] // https://github.com/dotnet/linker/issues/2273 - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "")] public static void Main () { typeof (AttributeConstructorDataflow).GetMethod ("Main").GetCustomAttribute (typeof (KeepsPublicConstructorAttribute)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs index e581797e234742..4807f7c039771d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs @@ -41,7 +41,7 @@ public static void TestKeepsPublicMethods () [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] // Trimmer/NativeAot only for now - https://github.com/dotnet/linker/issues/2273 - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "")] [KeepsPublicMethods (TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributeFieldDataflow+ClassWithKeptPublicMethods")] public static void TestKeepsPublicMethodsString () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs index f953784dc37537..a6c254a00ab4c4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs @@ -56,7 +56,7 @@ public static void TestKeepsPublicMethods () [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] // Trimmer/NativeAot only for now - https://github.com/dotnet/runtime/issues/95118 - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethodsKeptByName--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethodsKeptByName--", Tool.Trimmer | Tool.NativeAot, "")] [KeepsPublicMethods (TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributesOnMethod+ClassWithKeptPublicMethodsKeptByName")] public static void TestKeepsPublicMethodsByName () { @@ -212,7 +212,7 @@ class AttributeWithConditionalExpression [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] // Trimmer/NativeAot only for now - https://github.com/dotnet/linker/issues/2273 - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "")] [KeepsPublicMethods (TypeName = 1 + 1 == 2 ? "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributeWithConditionalExpression+ClassWithKeptPublicMethods" : null)] public static void Test () { @@ -224,7 +224,7 @@ public static void Test () // where the owning symbol is not a method. [Kept] [KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))] - [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethods--", Tool.Trimmer | Tool.NativeAot, "")] [KeepsPublicMethods (TypeName = 1 + 1 == 2 ? "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributeWithConditionalExpression+ClassWithKeptPublicMethods" : null)] public static int field; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs index d00af37b2bebb1..08cb41710cb151 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs @@ -46,12 +46,12 @@ public static void Main () [Kept] // Trimmer and analyzer use different formats for ref parameters: https://github.com/dotnet/linker/issues/2406 - [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2069", nameof (s_typeWithPublicParameterlessConstructor), "parameter 'type'", nameof (MethodWithRefParameter), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", Tool.Analyzer, "")] + [ExpectedWarning ("IL2069", [nameof (s_typeWithPublicParameterlessConstructor), "parameter 'type'", nameof (MethodWithRefParameter)], Tool.Trimmer | Tool.NativeAot, "")] // MethodWithRefParameter (ref x) - [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", Tool.Analyzer, "")] public static void PassRefToField () { MethodWithRefParameter (ref s_typeWithPublicParameterlessConstructor); @@ -61,8 +61,8 @@ public static void PassRefToField () [Kept] // Trimmer and analyzer use different formats for ref parameters: https://github.com/dotnet/linker/issues/2406 - [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", Tool.Analyzer, "")] public static void PassRefToParameter (Type parameter) { MethodWithRefParameter (ref parameter); @@ -182,8 +182,8 @@ static void TwoOutRefs ( [Kept] // https://github.com/dotnet/runtime/issues/85464 - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2069", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2069", Tool.Trimmer | Tool.NativeAot, "")] public static void Test () { TwoOutRefs (out _publicMethodsField, out _publicPropertiesField); @@ -243,13 +243,13 @@ static void TestLocalAssignment (bool b = true) } [Kept] - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", [nameof (GetUnknownType), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", [nameof (GetTypeWithPublicConstructors), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", [nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", [nameof (GetTypeWithPublicFields), nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] // ILLink/ILCompiler produce different warning code: https://github.com/dotnet/linker/issues/2737 - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll), Tool.Trimmer | Tool.NativeAot, "")] static void TestArrayElementReferenceAssignment (bool b = true) { var arr1 = new Type[] { GetUnknownType () }; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs index cb609bc5906025..17924d0f3a2437 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs @@ -39,10 +39,8 @@ public static IEnumerable BaseIteratorWithCorrectDataflow () } } - [ExpectedWarning ("IL2120", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2120", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2120", ["<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "MoveNext"], Tool.Trimmer, "")] + [ExpectedWarning ("IL2120", ["<" + nameof (BaseIteratorWithCorrectDataflow) + ">", ""], Tool.Trimmer, "")] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] class IteratorStateMachines : BaseTypeWithIteratorStateMachines { @@ -52,22 +50,17 @@ public static IEnumerable IteratorWithoutDataflow () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", - ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", - ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL2119", "<" + nameof (IteratorCallsMethodWithRequires) + ">", "MoveNext", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2119", "<" + nameof (IteratorCallsMethodWithRequires) + ">", "MoveNext", Tool.Trimmer, "", CompilerGeneratedCode = true)] public static IEnumerable IteratorCallsMethodWithRequires () { yield return 0; MethodWithRequires (); } - [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithCorrectDataflow) + ">", "MoveNext", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2119", "", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithCorrectDataflow) + ">", "MoveNext", Tool.Trimmer, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2119", "", Tool.Trimmer, "", CompilerGeneratedCode = true)] public static IEnumerable IteratorWithCorrectDataflow () { var t_IteratorWithCorrectDataflow = GetAll (); @@ -75,10 +68,8 @@ public static IEnumerable IteratorWithCorrectDataflow () t_IteratorWithCorrectDataflow.RequiresAll (); } - [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithIntegerDataflow) + ">", "MoveNext", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2119", "", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithIntegerDataflow) + ">", "MoveNext", Tool.Trimmer, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2119", "", Tool.Trimmer, "", CompilerGeneratedCode = true)] public static IEnumerable IteratorWithIntegerDataflow () { int integerLocal = 0; @@ -87,10 +78,8 @@ public static IEnumerable IteratorWithIntegerDataflow () types[integerLocal].RequiresPublicMethods (); } - [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithProblematicDataflow) + ">", "MoveNext", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2119", "", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithProblematicDataflow) + ">", "MoveNext", Tool.Trimmer, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2119", "", Tool.Trimmer, "", CompilerGeneratedCode = true)] [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true)] public static IEnumerable IteratorWithProblematicDataflow () { @@ -99,25 +88,22 @@ public static IEnumerable IteratorWithProblematicDataflow () t_IteratorWithProblematicDataflow.RequiresAll (); } - [ExpectedWarning ("IL2112", nameof (RUCTypeWithIterators) + "()", "--RUCTypeWithIterators--", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // warning about .ctor + [ExpectedWarning ("IL2112", nameof (RUCTypeWithIterators) + "()", "--RUCTypeWithIterators--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] // warning about .ctor [RequiresUnreferencedCode ("--RUCTypeWithIterators--")] class RUCTypeWithIterators { - [ExpectedWarning ("IL2112", nameof (StaticIteratorCallsMethodWithRequires) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2112", nameof (StaticIteratorCallsMethodWithRequires) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static IEnumerable StaticIteratorCallsMethodWithRequires () { yield return 0; MethodWithRequires (); } - [ExpectedWarning ("IL2112", nameof (InstanceIteratorCallsMethodWithRequires) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2112", nameof (InstanceIteratorCallsMethodWithRequires) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public IEnumerable InstanceIteratorCallsMethodWithRequires () { yield return 0; @@ -125,32 +111,23 @@ public IEnumerable InstanceIteratorCallsMethodWithRequires () } } - [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithProblematicDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (IteratorCallsMethodWithRequires) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithCorrectDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithIntegerDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithProblematicDataflow) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorCallsMethodWithRequires) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithCorrectDataflow) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithIntegerDataflow) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "MoveNext", Tool.Trimmer, "")] [ExpectedWarning ("IL2026", nameof (RUCTypeWithIterators) + "()", "--RUCTypeWithIterators--")] // Expect to see warnings about RUC on type, for all static state machine members. [ExpectedWarning ("IL2026", nameof (RUCTypeWithIterators.StaticIteratorCallsMethodWithRequires) + "()", "--RUCTypeWithIterators--")] [ExpectedWarning ("IL2026", nameof (RUCTypeWithIterators.InstanceIteratorCallsMethodWithRequires) + "()")] - [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithCorrectDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithProblematicDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithCorrectDataflow) + ">", "", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithProblematicDataflow) + ">", "", Tool.Trimmer, "")] // Technically the access to IteratorWithIntegerDataflow should warn about access to the integer // field integerLocal, but our heuristics only warn if the field type satisfies the // "IsTypeInterestingForDatafllow" check. This is likely good enough because in most cases the // compiler-generated code will have other hoisted fields with types that _are_ interesting for dataflow. - [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithIntegerDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithIntegerDataflow) + ">", "", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "", Tool.Trimmer, "")] public static void Test (IteratorStateMachines test = null) { typeof (IteratorStateMachines).RequiresAll (); @@ -166,8 +143,8 @@ public static async Task AsyncWithoutDataflow () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static async Task AsyncCallsMethodWithRequires () { MethodWithRequires (); @@ -186,16 +163,11 @@ public static async Task AsyncWithProblematicDataflow () t_AsyncWithProblematicDataflow.RequiresAll (); } - [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithProblematicDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncCallsMethodWithRequires) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithCorrectDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithCorrectDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithProblematicDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithProblematicDataflow) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncCallsMethodWithRequires) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithCorrectDataflow) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithCorrectDataflow) + ">", "", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithProblematicDataflow) + ">", "", Tool.Trimmer, "")] public static void Test () { typeof (AsyncStateMachines).RequiresAll (); @@ -210,8 +182,8 @@ public static async IAsyncEnumerable AsyncIteratorWithoutDataflow () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static async IAsyncEnumerable AsyncIteratorCallsMethodWithRequires () { yield return await MethodAsync (); @@ -233,16 +205,11 @@ public static async IAsyncEnumerable AsyncIteratorWithProblematicDataflow ( t.RequiresAll (); } - [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithProblematicDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorCallsMethodWithRequires) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithCorrectDataflow) + ">", "MoveNext", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithCorrectDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithProblematicDataflow) + ">", "", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithProblematicDataflow) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorCallsMethodWithRequires) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithCorrectDataflow) + ">", "MoveNext", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithCorrectDataflow) + ">", "", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithProblematicDataflow) + ">", "", Tool.Trimmer, "")] public static void Test () { typeof (AsyncIteratorStateMachines).RequiresAll (); @@ -262,10 +229,9 @@ static void LambdaCallsMethodWithRequires () { var lambda = [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL2119", "<" + nameof (LambdaCallsMethodWithRequires) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2119", "<" + nameof (LambdaCallsMethodWithRequires) + ">", Tool.Trimmer, "")] () => MethodWithRequires (); lambda (); } @@ -273,8 +239,7 @@ static void LambdaCallsMethodWithRequires () static void LambdaWithCorrectDataflow () { var lambda = - [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithCorrectDataflow) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithCorrectDataflow) + ">", Tool.Trimmer, "")] () => { var t = GetAll (); t.RequiresAll (); @@ -295,8 +260,7 @@ static void LambdaWithCorrectParameter () static void LambdaWithProblematicDataflow () { var lambda = - [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithProblematicDataflow) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithProblematicDataflow) + ">", Tool.Trimmer, "")] [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll))] () => { var t = GetWithPublicMethods (); @@ -309,8 +273,7 @@ static void LambdaWithCapturedTypeToDAM () { var t = GetWithPublicMethods (); var lambda = - [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithCapturedTypeToDAM) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithCapturedTypeToDAM) + ">", Tool.Trimmer, "")] [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (DataFlowTypeExtensions.RequiresAll))] () => { t.RequiresAll (); @@ -337,29 +300,27 @@ static void LambdaCallsPInvokeTakingObject () { var lambda = [ExpectedWarning ("IL2050")] - [ExpectedWarning ("IL2119", "<" + nameof (LambdaCallsPInvokeTakingObject) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LambdaCallsPInvokeTakingObject) + ">", Tool.Trimmer, "")] () => MethodTakingObject (null); lambda (); } - [ExpectedWarning ("IL2112", nameof (RUCTypeWithLambdas) + "()", "--RUCTypeWithLambdas--", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", nameof (RUCTypeWithLambdas) + "()", "--RUCTypeWithLambdas--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] [RequiresUnreferencedCode ("--RUCTypeWithLambdas--")] class RUCTypeWithLambdas { - [ExpectedWarning ("IL2112", nameof (MethodWithLambdas), "--RUCTypeWithLambdas--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", [nameof (MethodWithLambdas), "--RUCTypeWithLambdas--"], Tool.Trimmer | Tool.NativeAot, "")] public void MethodWithLambdas () { var lambda = - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] () => MethodWithRequires (); int i = 0; var lambdaWithCapturedState = - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] () => { i++; MethodWithRequires (); @@ -370,16 +331,11 @@ public void MethodWithLambdas () } } - [ExpectedWarning ("IL2118", "<" + nameof (LambdaCallsPInvokeTakingObject) + ">", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (LambdaCallsMethodWithRequires) + ">", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithCorrectDataflow) + ">", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithProblematicDataflow) + ">", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithCapturedTypeToDAM) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaCallsPInvokeTakingObject) + ">", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaCallsMethodWithRequires) + ">", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithCorrectDataflow) + ">", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithProblematicDataflow) + ">", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithCapturedTypeToDAM) + ">", Tool.Trimmer, "")] [ExpectedWarning ("IL2026", nameof (RUCTypeWithLambdas) + "()", "--RUCTypeWithLambdas--")] [ExpectedWarning ("IL2026", nameof (RUCTypeWithLambdas.MethodWithLambdas) + "()", "--RUCTypeWithLambdas--")] public static void Test (Lambdas test = null) @@ -402,18 +358,16 @@ static void LocalFunctionWithoutDataflow () static void LocalFunctionCallsMethodWithRequires () { [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionCallsMethodWithRequires) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionCallsMethodWithRequires) + ">", Tool.Trimmer, "")] void LocalFunction () => MethodWithRequires (); LocalFunction (); } static void LocalFunctionWithCorrectDataflow () { - [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithCorrectDataflow) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithCorrectDataflow) + ">", Tool.Trimmer, "")] void LocalFunction () { var t = GetAll (); @@ -425,8 +379,7 @@ void LocalFunction () static void LocalFunctionWithProblematicDataflow () { [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll))] - [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithProblematicDataflow) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithProblematicDataflow) + ">", Tool.Trimmer, "")] void LocalFunction () { var t = GetWithPublicMethods (); @@ -438,8 +391,7 @@ void LocalFunction () static void LocalFunctionWithCapturedTypeToDAM () { var t = GetAll (); - [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithCapturedTypeToDAM) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithCapturedTypeToDAM) + ">", Tool.Trimmer, "")] void LocalFunction () { t.RequiresAll (); @@ -464,32 +416,29 @@ static void LocalFunctionCallsPInvokeTakingPrimitiveType () static void LocalFunctionCallsPInvokeTakingObject () { [ExpectedWarning ("IL2050")] - [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionCallsPInvokeTakingObject) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionCallsPInvokeTakingObject) + ">", Tool.Trimmer, "")] void LocalFunction () => MethodTakingObject (null); LocalFunction (); } - [ExpectedWarning ("IL2112", nameof (RUCTypeWithLocalFunctions) + "()", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", nameof (RUCTypeWithLocalFunctions) + "()", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] [RequiresUnreferencedCode ("--RUCTypeWithLocalFunctions--")] class RUCTypeWithLocalFunctions { - [ExpectedWarning ("IL2112", nameof (MethodWithLocalFunctions), "--RUCTypeWithLocalFunctions--", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", nameof (MethodWithLocalFunctions), "--RUCTypeWithLocalFunctions--", Tool.Trimmer | Tool.NativeAot, "")] public void MethodWithLocalFunctions () { - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunction () => MethodWithRequires (); - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void StaticLocalFunction () => MethodWithRequires (); int i = 0; - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunctionWithCapturedState () { i++; @@ -502,16 +451,11 @@ void LocalFunctionWithCapturedState () } } - [ExpectedWarning ("IL2118", nameof (LocalFunctionCallsPInvokeTakingObject), - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", nameof (LocalFunctionCallsMethodWithRequires), - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", nameof (LocalFunctionWithCorrectDataflow), - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", nameof (LocalFunctionWithProblematicDataflow), - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", nameof (LocalFunctionWithCapturedTypeToDAM), - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", nameof (LocalFunctionCallsPInvokeTakingObject), Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", nameof (LocalFunctionCallsMethodWithRequires), Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", nameof (LocalFunctionWithCorrectDataflow), Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", nameof (LocalFunctionWithProblematicDataflow), Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", nameof (LocalFunctionWithCapturedTypeToDAM), Tool.Trimmer, "")] // Expect RUC warnings for static, compiler-generated code warnings for instance. [ExpectedWarning ("IL2026", nameof (RUCTypeWithLocalFunctions) + "()", "--RUCTypeWithLocalFunctions--")] [ExpectedWarning ("IL2026", nameof (RUCTypeWithLocalFunctions.MethodWithLocalFunctions) + "()")] @@ -648,7 +592,7 @@ static void TestLocalFunctionThroughDelegate () Action a = LocalFunction; a (null); - void LocalFunction ([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + void LocalFunction ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } } @@ -658,7 +602,7 @@ static void TestGenericLocalFunctionThroughDelegate () Action a = LocalFunction; a (); - void LocalFunction <[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () + void LocalFunction<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { } } @@ -685,10 +629,10 @@ static void Lambda () a (typeof (string)); } - static void LambdaOnGeneric<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T> () + static void LambdaOnGeneric<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { Action a = () => { - typeof(T).GetMethods (); + typeof (T).GetMethods (); }; a (); @@ -698,23 +642,23 @@ static void LocalFunction () { LocalFunctionInner (typeof (string)); - static void LocalFunctionInner ([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + static void LocalFunctionInner ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { type.GetMethods (); } } - static void LocalFunctionOnGeneric<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + static void LocalFunctionOnGeneric<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { LocalFunctionInner (); static void LocalFunctionInner () { - typeof(T).GetMethods (); + typeof (T).GetMethods (); } } - static IEnumerable IteratorOnGeneric<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + static IEnumerable IteratorOnGeneric<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { yield return 0; } @@ -730,8 +674,8 @@ static void LocalFunctionInner () await Task.Delay (100); } - [ExpectedWarning ("IL2118", "<" + nameof (LambdaOnGeneric) + ">", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", "<" + nameof (LocalFunctionOnGeneric) + ">", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaOnGeneric) + ">", Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", "<" + nameof (LocalFunctionOnGeneric) + ">", Tool.Trimmer, "")] public static void Test () { typeof (DAMReflectionAccessToCompilerGeneratedCode).RequiresAll (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs index bae9341ecde8bf..e0bb05872b8445 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs @@ -38,10 +38,8 @@ static IEnumerable FlowAcrossYieldReturn () } // Trimmer tracks all assignments of hoisted locals, so this produces warnings. - [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (DataFlowTypeExtensions.RequiresPublicFields), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (GetWithPublicFields), nameof (DataFlowTypeExtensions.RequiresPublicMethods), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2072", [nameof (GetWithPublicFields), nameof (DataFlowTypeExtensions.RequiresPublicMethods)], Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static IEnumerable NoFlowAcrossYieldReturn () { Type t = GetWithPublicMethods (); @@ -227,10 +225,8 @@ static async void FlowAcrossAwait () } // Trimmer tracks all assignments of hoisted locals, so this produces warnings. - [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (DataFlowTypeExtensions.RequiresPublicFields), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (GetWithPublicFields), nameof (DataFlowTypeExtensions.RequiresPublicMethods), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2072", nameof (GetWithPublicFields), nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async void NoFlowAcrossAwait () { Type t = GetWithPublicMethods (); @@ -447,7 +443,7 @@ public static void ReadCapturedParameterAfterWrite (Type tParameter = null) void LocalFunction () => tParameter.RequiresPublicMethods (); } - [ExpectedWarning ("IL2072", "tParameter", nameof (GetWithPublicFields), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", ["tParameter", nameof (GetWithPublicFields)], Tool.Analyzer, "")] public static void ReadCapturedParameterAfterWriteMismatch ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type tParameter = null) { tParameter = GetWithPublicFields (); @@ -576,7 +572,7 @@ public static void ReadCapturedParameterAfterWrite (Type tParameter = null) lambda (); } - [ExpectedWarning ("IL2072", "tParameter", nameof (GetWithPublicFields), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", ["tParameter", nameof (GetWithPublicFields)], Tool.Analyzer, "")] public static void ReadCapturedParameterAfterWriteMismatch ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type tParameter = null) { tParameter = GetWithPublicFields (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs index 2cd0f49317f17b..83ae5834cdc96b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssembly.cs @@ -42,7 +42,7 @@ public static void WithLocalFunctionInner () // Analyzer doesn't implement constant propagation and branch removal, so it reaches this code // NativeAOT behavioral difference: // https://github.com/dotnet/runtime/issues/85161 - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Analyzer | Tool.NativeAot, "")] void LocalWithWarning () { // No warning @@ -64,7 +64,7 @@ public static void WithLocalFunction () // Analyzer doesn't implement constant propagation and branch removal, so it reaches this code // NativeAOT behavioral difference: // https://github.com/dotnet/runtime/issues/85161 - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Analyzer | Tool.NativeAot, "")] void LocalWithWarning () { Requires (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssemblyWithWarning.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssemblyWithWarning.cs index 2023c19aaa85b1..58af92cb3e179b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssemblyWithWarning.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeInPreservedAssemblyWithWarning.cs @@ -38,7 +38,7 @@ public static void WithLocalFunctionInner () } // https://github.com/dotnet/linker/issues/2937 - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] void LocalWithWarning () { // Warning! @@ -55,7 +55,7 @@ public static void WithLocalFunction () } // https://github.com/dotnet/linker/issues/2937 - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] void LocalWithWarning () { // No warning diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs index ad29941cae2ce8..36d22c3ff904c2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs @@ -151,7 +151,7 @@ public ArrayCreateInstanceByNameElement () } [Kept] - [ExpectedWarning ("IL2032", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/82447 + [ExpectedWarning ("IL2032", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/82447 static void TestArrayCreateInstanceByName () { Activator.CreateInstance ("test", "Mono.Linker.Tests.Cases.DataFlow.ComplexTypeHandling+ArrayCreateInstanceByNameElement[]"); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs index abeed77e1bc0ed..d2dbbc2f416977 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructedTypesDataFlow.cs @@ -21,7 +21,7 @@ public static void Main () class DeconstructedVariable { // https://github.com/dotnet/linker/issues/3158 - [ExpectedWarning ("IL2077", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2077", Tool.Trimmer | Tool.NativeAot, "")] static void DeconstructVariableNoAnnotation ((Type type, object instance) input) { var (type, instance) = input; @@ -31,7 +31,7 @@ static void DeconstructVariableNoAnnotation ((Type type, object instance) input) static (Type type, object instance) GetInput (int unused) => (typeof (string), null); // https://github.com/dotnet/linker/issues/3158 - [ExpectedWarning ("IL2077", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2077", Tool.Trimmer | Tool.NativeAot, "")] static void DeconstructVariableFlowCapture (bool b = true) { // This creates a control-flow graph where the tuple elements assigned to @@ -51,8 +51,8 @@ static void DeconstructVariableFlowCapture (bool b = true) static ref Type AnnotatedProperty => ref annotatedfield; // https://github.com/dotnet/linker/issues/3158 - [ExpectedWarning ("IL2062", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2078", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2062", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2078", Tool.Trimmer | Tool.NativeAot, "")] static void DeconstructVariablePropertyReference ((Type type, object instance) input) { object instance; @@ -72,7 +72,7 @@ record TypeAndInstance ( // For analyzer, this is currently // https://github.com/dotnet/linker/issues/3158 // But it's possible that with that fixed there won't be a warning from the analyzer anyway (depends on the implementation) - [ExpectedWarning ("IL2067", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2067", Tool.Trimmer | Tool.NativeAot, "")] static void DeconstructRecordWithAnnotation (TypeAndInstance value) { var (type, instance) = value; @@ -119,7 +119,7 @@ static void DeconstructRecordManualWithAnnotation (TypeAndInstanceRecordManual v } // https://github.com/dotnet/linker/issues/3158 - [ExpectedWarning ("IL2067", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2067", Tool.Trimmer | Tool.NativeAot, "")] static void DeconstructRecordManualWithMismatchAnnotation (TypeAndInstanceRecordManual value) { var (type, instance) = value; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructorDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructorDataFlow.cs index fe0d1af1f62c7c..f1a3788aaa11bd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructorDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ConstructorDataFlow.cs @@ -39,13 +39,11 @@ public DataFlowInConstructor () [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type annotatedField = GetUnknown (); - [ExpectedWarning ("IL2074", nameof (GetUnknown), nameof (AnnotatedProperty), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/93277 + [ExpectedWarning ("IL2074", nameof (GetUnknown), nameof (AnnotatedProperty), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] // https://github.com/dotnet/runtime/issues/93277 [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type AnnotatedProperty { get; } = GetUnknown (); - [ExpectedWarning ("IL2074", nameof (GetUnknown), nameof (AnnotatedPropertyWithSetter), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/93277 + [ExpectedWarning ("IL2074", nameof (GetUnknown), nameof (AnnotatedPropertyWithSetter), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] // https://github.com/dotnet/runtime/issues/93277 [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type AnnotatedPropertyWithSetter { get; set; } = GetUnknown (); @@ -81,12 +79,10 @@ public DataFlowInConstructor () int PropertyWithThrowStatementInInitializer { get; } = string.Empty.Length == 0 ? throw new Exception() : 0; - [ExpectedWarning ("IL2067", nameof (TryGetUnknown), nameof (RequireAll), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // https://github.com/dotnet/linker/issues/2158 + [ExpectedWarning ("IL2067", nameof (TryGetUnknown), nameof (RequireAll), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] // https://github.com/dotnet/linker/issues/2158 int fieldWithLocalReferenceInInitializer = TryGetUnknown (out var type) ? RequireAll (type) : 0; - [ExpectedWarning ("IL2067", nameof (TryGetUnknown), nameof (RequireAll), CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // https://github.com/dotnet/linker/issues/2158 + [ExpectedWarning ("IL2067", nameof (TryGetUnknown), nameof (RequireAll), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] // https://github.com/dotnet/linker/issues/2158 int PropertyWithLocalReferenceInInitializer { get; } = TryGetUnknown (out var type) ? RequireAll (type) : 0; public static void Test () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs index d048bec91e5d29..01a5ecb9cb3657 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/DynamicObjects.cs @@ -29,7 +29,7 @@ public static void Main () class InvocationOnDynamicType { [ExpectedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 static void DynamicArgument () { dynamic dynamicObject = "Some string"; @@ -48,15 +48,15 @@ static void MethodWithDynamicParameterDoNothing (dynamic arg) } [ExpectedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 static void MethodWithDynamicParameter (dynamic arg) { arg.MethodWithDynamicParameter (arg); } // Roslyn codegen no longer produces a call to Binder.InvokeConstructor. - // [ExpectedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.InvokeConstructor")] - // [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + // [ExpectedSharedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.InvokeConstructor")] + // [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 // static void ObjectCreationDynamicArgument () // { // dynamic dynamicObject = "Some string"; @@ -81,14 +81,14 @@ public static void Test () class DynamicMemberReference { [ExpectedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.GetMember")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 static void Read (dynamic d) { var x = d.Member; } [ExpectedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.SetMember")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 static void Write (dynamic d) { d.Member = 0; @@ -104,14 +104,14 @@ public static void Test () class DynamicIndexerAccess { [ExpectedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.GetIndex")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 static void Read (dynamic d) { var x = d[0]; } [ExpectedWarning ("IL2026", "Microsoft.CSharp.RuntimeBinder.Binder.SetIndex")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 static void Write (dynamic d) { d[0] = 0; @@ -129,7 +129,7 @@ class DynamicInRequiresUnreferencedCodeClass [RequiresUnreferencedCode("message")] class ClassWithRequires { - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] // https://github.com/dotnet/runtime/issues/94427 + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/94427 public static void MethodWithDynamicArg (dynamic arg) { arg.DynamicInvocation (); @@ -154,7 +154,7 @@ static void MethodWithRequires () } [ExpectedWarning ("IL2026", nameof (MethodWithRequires))] - [ExpectedWarning ("IL3050", nameof (MethodWithRequires), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (MethodWithRequires), Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { MethodWithRequires (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs index beaf3237c7c4d3..8cc5bf9b6c1a7e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs @@ -46,10 +46,8 @@ public static void Main () ExceptionFilterWithException (); } - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void TryFlowsToFinally () { @@ -109,12 +107,9 @@ public static void MultipleTryExits () // On each path, only one state is possible, but we conservatively merge the (non-exceptional) // finally states for each path and expect the warnings to reflect this merged state. [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicEvents) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicEvents) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] @@ -124,12 +119,9 @@ public static void MultipleTryExits () [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicEvents) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicProperties) + "()", Tool.Trimmer | Tool.NativeAot, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] public static Type MultipleFinallyPaths () { @@ -160,14 +152,11 @@ public static Type MultipleFinallyPaths () throw new Exception (); } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void FinallyChain () { @@ -184,16 +173,12 @@ public static void FinallyChain () } } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] - + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicProperties) + "()")] @@ -218,10 +203,8 @@ public static void FinallyChainWithPostFinallyState () RequireAll4 (t); } - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void TryFlowsToCatch () { @@ -235,10 +218,8 @@ public static void TryFlowsToCatch () } } - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void CatchFlowsToFinally () { @@ -253,8 +234,7 @@ public static void CatchFlowsToFinally () } } - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void CatchFlowsToAfterTry () { @@ -268,8 +248,7 @@ public static void CatchFlowsToAfterTry () RequireAll (t); } - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void CatchFlowsToAfterFinally () { @@ -303,20 +282,17 @@ public class Exception2 : Exception { } [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicFields) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll5) + "(Type)", nameof (GetWithPublicEvents) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicFields) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicProperties) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicEvents) + "()")] @@ -326,26 +302,16 @@ public class Exception2 : Exception { } [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicConstructors) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll5) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll5) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll7) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll7) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll7) + "(Type)", nameof (GetWithPublicEvents) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicEvents) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll5) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll5) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll7) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll7) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll7) + "(Type)", nameof (GetWithPublicEvents) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicEvents) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void TryFlowsToMultipleCatchAndFinally () { @@ -370,20 +336,15 @@ public static void TryFlowsToMultipleCatchAndFinally () } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicConstructors) + "()")] public static void NestedWithFinally () @@ -408,17 +369,14 @@ public static void NestedWithFinally () } } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()")] @@ -446,22 +404,16 @@ public static void ControlFlowsOutOfMultipleFinally () } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicConstructors) + "()")] public static void NestedWithCatch () @@ -488,8 +440,7 @@ public static void NestedWithCatch () [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void CatchInTry () { try { @@ -510,11 +461,10 @@ public static void CatchInTry () [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] // The bug was producing this warning: - // [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + // [ExpectedSharedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void CatchInTryWithFinally () { Type t = GetWithPublicConstructors (); @@ -540,12 +490,10 @@ public static void CatchInTryWithFinally () } } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicConstructors) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicConstructors) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] static void CatchInFinally () { @@ -565,8 +513,7 @@ static void CatchInFinally () { [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void TestCatchesHaveSeparateState () { Type t = GetWithPublicMethods (); @@ -581,8 +528,7 @@ public static void TestCatchesHaveSeparateState () } [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] public static void FinallyWithBranchToFirstBlock () { Type t = GetWithPublicMethods (); @@ -596,8 +542,7 @@ public static void FinallyWithBranchToFirstBlock () } [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] public static void FinallyWithBranchToFirstBlockAndEnclosingTryCatchState () { try { @@ -619,8 +564,7 @@ public static void FinallyWithBranchToFirstBlockAndEnclosingTryCatchState () } [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] public static void CatchWithBranchToFirstBlock () { Type t = GetWithPublicMethods (); @@ -634,8 +578,7 @@ public static void CatchWithBranchToFirstBlock () } [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] public static void CatchWithBranchToFirstBlockAndReassignment () { Type t = GetWithPublicMethods (); @@ -651,10 +594,8 @@ public static void CatchWithBranchToFirstBlockAndReassignment () [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void CatchWithNonSimplePredecessor () { @@ -676,10 +617,8 @@ public static void CatchWithNonSimplePredecessor () [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void FinallyWithNonSimplePredecessor () { @@ -701,10 +640,8 @@ public static void FinallyWithNonSimplePredecessor () [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] public static void FinallyInTryWithPredecessor () { @@ -724,20 +661,17 @@ public static void FinallyInTryWithPredecessor () } } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void NestedFinally () { Type t = GetWithPublicMethods (); @@ -760,10 +694,8 @@ public static void NestedFinally () [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicFields) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void ChangeInFinallyNestedInFinally () { Type t = GetWithPublicMethods (); @@ -780,20 +712,17 @@ public static void ChangeInFinallyNestedInFinally () RequireAll4 (t); // fields only } - [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void NestedFinallyWithPredecessor () { Type t = GetWithPublicMethods (); @@ -811,11 +740,9 @@ public static void NestedFinallyWithPredecessor () } } - [ExpectedWarning ("IL2072", nameof (RequireAllTrue) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAllTrue) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAllTrue) + "(Type)", nameof (GetWithPublicFields) + "()")] - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()")] public static void ExceptionFilter () { @@ -833,8 +760,7 @@ public static void ExceptionFilter () [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void ExceptionFilterStateChange () { Type t = GetWithPublicMethods (); @@ -872,12 +798,9 @@ public static void ExceptionFilterStateChange () [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicProperties) + "()")] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", Tool.Trimmer | Tool.NativeAot, "")] public static void ExceptionMultipleFilters () { Type t = GetWithPublicMethods (); @@ -908,8 +831,7 @@ public static void ExceptionMultipleFilters () [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties))] // Trimmer merges branches going forward. - [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods), Tool.Trimmer | Tool.NativeAot, "")] public static void ExceptionFilterWithBranch () { Type t = GetWithPublicMethods (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs index 2f749beae0f813..a7715c507f2a32 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ExponentialDataFlow.cs @@ -58,7 +58,7 @@ class GenericTypeWithRequires<[DynamicallyAccessedMembers (DynamicallyAccessedMe { } - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", Tool.Analyzer, "")] [ExpectedWarning ("IL2090", "'T'")] public static void Test () { @@ -94,32 +94,32 @@ class GenericTypeWithRequires< { } - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] // The way we track arrays causes the analyzer to track exponentially many // ArrayValues in the ValueSet for the pattern in this method, hitting the limit. // When this happens, we replace the ValueSet with an unknown value, producing // this warning. - [ExpectedWarning ("IL2055", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2090", "'T'", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2055", Tool.Analyzer, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2090", "'T'", Tool.Trimmer | Tool.NativeAot, "")] public static void Test () { Type[] types = new Type[20] { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureCheckDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureCheckDataFlow.cs index 8c8c3baf5ab5c6..ab94f5052d4294 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureCheckDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureCheckDataFlow.cs @@ -40,8 +40,8 @@ public static void Main () class CallFeatureUnguarded { [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer | Tool.NativeAot, "")] static void Unguarded () { RequiresUnreferencedCode (); @@ -50,8 +50,8 @@ static void Unguarded () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer | Tool.NativeAot, "")] static void UnguardedIf () { if (!TestFeatures.IsUnreferencedCodeSupported) { @@ -62,8 +62,8 @@ static void UnguardedIf () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer | Tool.NativeAot, "")] static void UnguardedElse () { if (TestFeatures.IsUnreferencedCodeSupported) @@ -99,8 +99,8 @@ static void UnguardedTernary () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer | Tool.NativeAot, "")] static void UnguardedThrow () { if (TestFeatures.IsUnreferencedCodeSupported) @@ -114,8 +114,8 @@ static void UnguardedThrow () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer | Tool.NativeAot, "")] static void UnguardedReturn () { if (TestFeatures.IsUnreferencedCodeSupported) @@ -205,8 +205,8 @@ public static void Test () GuardedDoesNotReturnIfFalseCtor (); } - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer, "")] static void GuardedIf () { if (TestFeatures.IsUnreferencedCodeSupported) { @@ -216,8 +216,8 @@ static void GuardedIf () } } - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer, "")] static void GuardedElse () { if (!TestFeatures.IsUnreferencedCodeSupported) @@ -248,8 +248,8 @@ static void GuardedTernary () var b = !TestFeatures.IsUnreferencedCodeSupported ? true : RequiresUnreferencedCodeBool (); } - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer, "")] static void GuardedThrow () { if (!TestFeatures.IsUnreferencedCodeSupported) @@ -262,8 +262,8 @@ static void GuardedThrow () RequiresAssemblyFiles (); } - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer, "")] static void GuardedReturn () { if (!TestFeatures.IsUnreferencedCodeSupported) @@ -277,7 +277,7 @@ static void GuardedReturn () } // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] static void GuardedAssert () { Debug.Assert (TestFeatures.IsUnreferencedCodeSupported); @@ -286,7 +286,7 @@ static void GuardedAssert () } // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] static void GuardedDoesNotReturnIfTrue () { DoesNotReturnIfTrue (!TestFeatures.IsUnreferencedCodeSupported); @@ -295,7 +295,7 @@ static void GuardedDoesNotReturnIfTrue () } // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] static void GuardedDoesNotReturnIfFalse () { DoesNotReturnIfFalse (TestFeatures.IsUnreferencedCodeSupported); @@ -304,7 +304,7 @@ static void GuardedDoesNotReturnIfFalse () } // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] static void GuardedDoesNotReturn () { if (!TestFeatures.IsUnreferencedCodeSupported) @@ -314,7 +314,7 @@ static void GuardedDoesNotReturn () } // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] static void GuardedDoesNotReturnIfFalseCtor () { new DoesNotReturnIfFalseCtor (TestFeatures.IsUnreferencedCodeSupported); @@ -326,8 +326,8 @@ static void GuardedDoesNotReturnIfFalseCtor () class FeatureCheckBooleanExpressions { // Trimmer/NativeAot aren't able to optimize away the branch in this case. - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.NativeAot, "")] static void And () { if (TestFeatures.IsUnreferencedCodeSupported && RuntimeFeature.IsDynamicCodeSupported) { @@ -337,7 +337,7 @@ static void And () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] static void AndNot () { if (!TestFeatures.IsUnreferencedCodeSupported && !RuntimeFeature.IsDynamicCodeSupported) @@ -348,8 +348,8 @@ static void AndNot () } // Trimmer/NativeAot aren't able to optimize away the branch in this case. - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.NativeAot, "")] static void NotAnd () { if (!(TestFeatures.IsUnreferencedCodeSupported && RuntimeFeature.IsDynamicCodeSupported)) @@ -360,7 +360,7 @@ static void NotAnd () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] static void Or () { if (TestFeatures.IsUnreferencedCodeSupported || RuntimeFeature.IsDynamicCodeSupported) { @@ -370,8 +370,8 @@ static void Or () } // Trimmer/NativeAot aren't able to optimize away the branch in this case. - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.NativeAot, "")] static void OrNot () { if (!TestFeatures.IsUnreferencedCodeSupported || !RuntimeFeature.IsDynamicCodeSupported) @@ -382,7 +382,7 @@ static void OrNot () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] static void NotOr () { if (!(TestFeatures.IsUnreferencedCodeSupported || RuntimeFeature.IsDynamicCodeSupported)) @@ -477,7 +477,7 @@ static void IsNotFalse () } [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode))] - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "")] static void Contradiction () { if (TestFeatures.IsUnreferencedCodeSupported && !TestFeatures.IsUnreferencedCodeSupported) { @@ -532,7 +532,7 @@ static void CallTestDynamicCodeGuarded () RequiresDynamicCode (); } - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer | Tool.NativeAot, "")] static void CallTestDynamicCodeUnguarded () { RequiresDynamicCode (); @@ -545,7 +545,7 @@ static void CallTestAssemblyFilesGuarded () } } - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer | Tool.NativeAot, "")] static void CallTestAssemblyFilesUnguarded () { RequiresAssemblyFiles (); @@ -564,9 +564,9 @@ public static void Test () class FeatureCheckCombinations { - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer, "")] // Trimmer warns because IsDynamicCodeSupported is not a constant, so the call is reachable. - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Analyzer | Tool.Trimmer)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Analyzer | Tool.Trimmer, "")] static void MeetFeaturesEmptyIntersection (bool b = true) { if (b) { @@ -582,7 +582,7 @@ static void MeetFeaturesEmptyIntersection (bool b = true) // Shows that ILLink has the same branch removal as NativeAot for this pattern, when // the branches both use a feature check that's substituted by ILLink. - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer, "")] static void MeetFeaturesEmptyIntersection_IdenticalBranches (bool b = true) { if (b) { @@ -596,7 +596,7 @@ static void MeetFeaturesEmptyIntersection_IdenticalBranches (bool b = true) RequiresDynamicCode (); } - [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (RequiresDynamicCode), Tool.Analyzer, "")] static void MeetFeaturesIntersection (bool b = true) { if (b) { @@ -622,7 +622,7 @@ static void IntroduceFeature () } } - [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3002", nameof (RequiresAssemblyFiles), Tool.Analyzer, "")] static void RemoveFeature () { if (TestFeatures.IsUnreferencedCodeSupported) { @@ -787,7 +787,7 @@ static void NestedTryInCheckInFinally () [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInTryNoCatch () { try { Debug.Assert (TestFeatures.IsUnreferencedCodeSupported); @@ -828,7 +828,7 @@ static void AssertInCatch () { [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1))] // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInFinally () { try { RequiresUnreferencedCode0 (); @@ -843,8 +843,8 @@ static void AssertInFinally () { [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2))] // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInTryNestedInTry () { try { @@ -885,8 +885,8 @@ static void AssertInTryWithCatchNestedInTry () [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1))] // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInTryNestedInFinally () { try { @@ -925,8 +925,8 @@ static void AssertInTryWithCatchNestedInFinally () [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2))] // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInFinallyNestedInTry () { try { try { @@ -944,8 +944,8 @@ static void AssertInFinallyNestedInTry () { [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2))] // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInFinallyWithCatchNestedInTry () { try { try { @@ -965,8 +965,8 @@ static void AssertInFinallyWithCatchNestedInTry () { [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1))] // Trimmer/NativeAot don't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInFinallyNestedInFinally () { try { @@ -985,8 +985,8 @@ static void AssertInFinallyNestedInFinally () [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode0))] [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode1))] // Trimmer/NativeAot doesn't optimize branches away based on DoesNotReturnIfAttribute - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode2), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode3), Tool.Trimmer | Tool.NativeAot, "")] static void AssertInFinallyWithCatchNestedInFinally () { try { @@ -1056,8 +1056,7 @@ static IEnumerable GuardInIterator () } } - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer, - CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer, "", CompilerGeneratedCode = true)] static IEnumerable StateFlowsAcrossYield () { if (!TestFeatures.IsUnreferencedCodeSupported) @@ -1076,8 +1075,7 @@ static async Task GuardInAsync () } } - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot, - CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async Task StateFlowsAcrossAwait () { if (!TestFeatures.IsUnreferencedCodeSupported) @@ -1097,8 +1095,7 @@ static async IAsyncEnumerable GuardInAsyncIterator () } } - [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), ProducedBy = Tool.Trimmer | Tool.NativeAot, - CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2026", nameof (RequiresUnreferencedCode), Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async IAsyncEnumerable StateFlowsAcrossAwaitAndYield () { if (!TestFeatures.IsUnreferencedCodeSupported) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs index f4daacec7a0e1d..6b0e605ac7730d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs @@ -65,7 +65,7 @@ static void TestIndirectGuard () // // The analyzer doesn't do constant propagation of the boolean, so it doesn't know that // the return value is always false when TestFeatures.IsUnreferencedCodeSupported is false. - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool AndGuard => TestFeatures.IsUnreferencedCodeSupported && OtherCondition (); @@ -138,7 +138,7 @@ static void TestIsNotFalseGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool IfReturnTrueGuard { get { @@ -148,7 +148,7 @@ static bool IfReturnTrueGuard { } } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool ElseReturnTrueGuard { get { @@ -199,7 +199,7 @@ static void TestAssertNotReturnFalseGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool AssertReturnTrueGuard { get { @@ -229,7 +229,7 @@ static void TestThrowGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool TernaryIfGuard => TestFeatures.IsUnreferencedCodeSupported ? true : false; @@ -239,7 +239,7 @@ static void TestTernaryIfGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool TernaryElseGuard => !TestFeatures.IsUnreferencedCodeSupported ? false : true; @@ -275,7 +275,7 @@ public static void Test () } class InvalidGuardBodies { - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool ReturnTrueGuard => true; @@ -285,7 +285,7 @@ static void TestReturnTrueGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool OtherConditionGuard => OtherCondition (); @@ -295,7 +295,7 @@ static void TestOtherConditionGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool OrGuard => TestFeatures.IsUnreferencedCodeSupported || OtherCondition (); @@ -305,7 +305,7 @@ static void TestOrGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool NotGuard => !TestFeatures.IsUnreferencedCodeSupported; @@ -315,7 +315,7 @@ static void TestNotGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool EqualsFalseGuard => TestFeatures.IsUnreferencedCodeSupported == false; @@ -325,7 +325,7 @@ static void TestEqualsFalseGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool FalseEqualsGuard => false == TestFeatures.IsUnreferencedCodeSupported; @@ -335,7 +335,7 @@ static void TestFalseEqualsGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool NotEqualsTrueGuard => TestFeatures.IsUnreferencedCodeSupported != true; @@ -345,7 +345,7 @@ static void TestNotEqualsTrueGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool TrueNotEqualsGuard => true != TestFeatures.IsUnreferencedCodeSupported; @@ -355,7 +355,7 @@ static void TestTrueNotEqualsGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool IsNotTrueGuard => TestFeatures.IsUnreferencedCodeSupported is not true; @@ -365,7 +365,7 @@ static void TestIsNotTrueGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool IsFalseGuard => TestFeatures.IsUnreferencedCodeSupported is false; @@ -375,7 +375,7 @@ static void TestIsFalseGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool IfReturnFalseGuard { get { @@ -391,7 +391,7 @@ static void TestIfReturnFalseGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool ElseReturnFalseGuard { get { @@ -408,7 +408,7 @@ static void TestElseReturnFalseGuard () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool AssertNotReturnTrueGuard { get { @@ -443,7 +443,7 @@ public static void Test () } class InvalidFeatureGuards { - [ExpectedWarning ("IL4001", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4001", Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static int NonBooleanProperty => 0; @@ -454,7 +454,7 @@ static void TestNonBooleanProperty () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4001", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4001", Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] bool NonStaticProperty => true; @@ -476,7 +476,7 @@ static void TestSetOnlyProperty () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4001", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4001", Tool.Analyzer, "")] [FeatureGuard (typeof(RequiresUnreferencedCodeAttribute))] static bool GetAndSetProperty { get => true; set => throw null; } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs index 26e880378057a3..46f9e9844c3564 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs @@ -230,24 +230,21 @@ class AccessReturnedInstanceField static AccessReturnedInstanceField GetInstance ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type unused) => null; - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (GetInstance), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // https://github.com/dotnet/linker/issues/2832 + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (GetInstance), Tool.Trimmer | Tool.NativeAot, "")] // https://github.com/dotnet/linker/issues/2832 [ExpectedWarning ("IL2077", nameof (field), nameof (DataFlowTypeExtensions.RequiresAll))] static void TestRead () { GetInstance (GetUnknownType ()).field.RequiresAll (); } - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (GetInstance), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // https://github.com/dotnet/linker/issues/2832 + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (GetInstance), Tool.Trimmer | Tool.NativeAot, "")] // https://github.com/dotnet/linker/issues/2832 [ExpectedWarning ("IL2074", nameof (GetUnknownType), nameof (field))] static void TestWrite () { GetInstance (GetUnknownType ()).field = GetUnknownType (); } - [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (GetInstance), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] // https://github.com/dotnet/linker/issues/2832 + [ExpectedWarning ("IL2072", nameof (GetUnknownType), nameof (GetInstance), Tool.Trimmer | Tool.NativeAot, "")] // https://github.com/dotnet/linker/issues/2832 [ExpectedWarning ("IL2074", nameof (GetUnknownType), nameof (field))] static void TestNullCoalescingAssignment () { @@ -341,13 +338,13 @@ static void RequirePublicFields ( { } - [ExpectedWarning ("IL2077", ProducedBy = Tool.Analyzer)] // https://github.com/dotnet/runtime/issues/101211 + [ExpectedWarning ("IL2077", Tool.Analyzer, "")] // https://github.com/dotnet/runtime/issues/101211 static void TestFlowOutOfField () { RequirePublicFields (unsupportedTypeInstance); } - [ExpectedWarning ("IL2074", ProducedBy = Tool.Analyzer)] // https://github.com/dotnet/runtime/issues/101211 + [ExpectedWarning ("IL2074", Tool.Analyzer, "")] // https://github.com/dotnet/runtime/issues/101211 public static void Test () { var t = GetUnsupportedTypeInstance (); unsupportedTypeInstance = t; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs index e7b96db55e6893..2cbd62f6d43432 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs @@ -408,7 +408,7 @@ class TypeGenericRequirementsOnMembers<[DynamicallyAccessedMembers (DynamicallyA { public TypeRequiresPublicFields PublicFieldsField; - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType public TypeRequiresPublicMethods PublicMethodsField; public TypeRequiresPublicFields PublicFieldsProperty { @@ -417,23 +417,23 @@ public TypeRequiresPublicFields PublicFieldsProperty { } public TypeRequiresPublicMethods PublicMethodsProperty { - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType get => null; - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType set { } } - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer, CompilerGeneratedCode = true)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "", CompilerGeneratedCode = true)] // NativeAOT_StorageSpaceType public TypeRequiresPublicMethods PublicMethodsImplicitGetter => null; public void PublicFieldsMethodParameter (TypeRequiresPublicFields param) { } - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType public void PublicMethodsMethodParameter (TypeRequiresPublicMethods param) { } public TypeRequiresPublicFields PublicFieldsMethodReturnValue () { return null; } - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType public TypeRequiresPublicMethods PublicMethodsMethodReturnValue () { return null; } public void PublicFieldsMethodLocalVariable () @@ -442,7 +442,7 @@ public void PublicFieldsMethodLocalVariable () } // The analyzer matches NativeAot behavior for local variables - it doesn't warn on generic types of local variables. - [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType public void PublicMethodsMethodLocalVariable () { TypeRequiresPublicMethods t = null; @@ -711,17 +711,15 @@ public static void StaticPartialInstantiation () } [ExpectedWarning ("IL2091", - nameof (TOuter), + [nameof (TOuter), "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter", "TMethods", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams()", - ProducedBy = Tool.Analyzer)] + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams()"], Tool.Analyzer, "")] [ExpectedWarning ("IL2091", - "'TOuter'", + ["'TOuter'", "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter", "'TMethods'", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams"], Tool.Trimmer | Tool.NativeAot, "")] public static void StaticPartialInstantiationUnrecognized () { StaticRequiresMultipleGenericParams (); @@ -833,10 +831,10 @@ static void TestNoWarningsInRUCMethod () [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields")] // StaticMethodRequiresPublicMethods [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields")] // StaticMethodRequiresPublicMethods [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields")] // RUCTypeRequiresPublicFields ctor - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields", ProducedBy = Tool.Trimmer)] // RUCTypeRequiresPublicFields local, // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields", ProducedBy = Tool.Trimmer)] // InstanceMethod, // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields", Tool.Trimmer, "")] // RUCTypeRequiresPublicFields local, // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields", Tool.Trimmer, "")] // InstanceMethod, // NativeAOT_StorageSpaceType [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields")] // InstanceMethodRequiresPublicMethods - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields", ProducedBy = Tool.Trimmer)] // VirtualMethod, // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields", Tool.Trimmer, "")] // VirtualMethod, // NativeAOT_StorageSpaceType [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields")] // VirtualMethodRequiresPublicMethods static void TestNoWarningsInRUCType () { @@ -908,9 +906,9 @@ static void TestGenericParameterFlowsToDelegateMethodDeclaringType () [ExpectedWarning ("IL2091", nameof (DelegateMethodTypeRequiresFields))] // NativeAOT_StorageSpaceType: illink warns about the type of 'instance' local variable - [ExpectedWarning ("IL2091", nameof (DelegateMethodTypeRequiresFields), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2091", nameof (DelegateMethodTypeRequiresFields), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType: illink warns about the declaring type of 'InstanceMethod' on ldftn - [ExpectedWarning ("IL2091", nameof (DelegateMethodTypeRequiresFields), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2091", nameof (DelegateMethodTypeRequiresFields), Tool.Trimmer, "")] static void TestGenericParameterFlowsToDelegateMethodDeclaringTypeInstance () { var instance = new DelegateMethodTypeRequiresFields (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs index d3aa2e17ac021b..560560df1223d0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs @@ -190,11 +190,11 @@ interface IWithTwo< static void MethodWithSpecificType (TypeWithPublicMethods one, IWithTwo two) { } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void MethodWithOneMismatch (TypeWithPublicMethods one) { } - [ExpectedWarning ("IL2091", nameof (IWithTwo), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", nameof (TypeWithPublicMethods), ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (IWithTwo), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", nameof (TypeWithPublicMethods), Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void MethodWithTwoMismatches< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -205,11 +205,11 @@ static void MethodWithTwoMismatches< static TypeWithPublicMethods MethodWithMatchingReturn<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () => null; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static TypeWithPublicMethods MethodWithOneMismatchReturn () => null; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static IWithTwo MethodWithTwoMismatchesInReturn< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -217,7 +217,7 @@ static IWithTwo MethodWithTwoMismatchesInReturn< class ConstructorWithOneMatchAndOneMismatch<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods> { - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType public ConstructorWithOneMatchAndOneMismatch (IWithTwo two) { } } @@ -252,11 +252,11 @@ interface IWithTwo< static void MethodWithSpecificType (TypeWithPublicMethods one, IWithTwo two) { } - [ExpectedWarning ("IL2091", ProducedBy = Tool.NativeAot | Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.NativeAot | Tool.Trimmer, "")] static void MethodWithOneMismatch (TypeWithPublicMethods one) { } - [ExpectedWarning ("IL2091", nameof (IWithTwo), ProducedBy = Tool.NativeAot | Tool.Trimmer)] - [ExpectedWarning ("IL2091", nameof (TypeWithPublicMethods), ProducedBy = Tool.NativeAot | Tool.Trimmer)] + [ExpectedWarning ("IL2091", nameof (IWithTwo), Tool.NativeAot | Tool.Trimmer, "")] + [ExpectedWarning ("IL2091", nameof (TypeWithPublicMethods), Tool.NativeAot | Tool.Trimmer, "")] static void MethodWithTwoMismatches< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -267,11 +267,11 @@ static void MethodWithTwoMismatches< static TypeWithPublicMethods MethodWithMatchingReturn<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () => null; - [ExpectedWarning ("IL2091", ProducedBy = Tool.NativeAot | Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.NativeAot | Tool.Trimmer, "")] static TypeWithPublicMethods MethodWithOneMismatchReturn () => null; - [ExpectedWarning ("IL2091", ProducedBy = Tool.NativeAot | Tool.Trimmer)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.NativeAot | Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.NativeAot | Tool.Trimmer, "")] + [ExpectedWarning ("IL2091", Tool.NativeAot | Tool.Trimmer, "")] static IWithTwo MethodWithTwoMismatchesInReturn< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -279,7 +279,7 @@ static IWithTwo MethodWithTwoMismatchesInReturn< class ConstructorWithOneMatchAndOneMismatch<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods> { - [ExpectedWarning ("IL2091", ProducedBy = Tool.NativeAot | Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.NativeAot | Tool.Trimmer, "")] public ConstructorWithOneMatchAndOneMismatch (IWithTwo two) { } } @@ -325,10 +325,10 @@ public static void Test () class MultipleReferencesToTheSameType<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> { - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static TypeWithPublicMethods _field1; static TypeWithPublicMethods _field2; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static TypeWithPublicMethods _field3; public static void Test () @@ -343,8 +343,8 @@ class TwoMismatchesInOne< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> { - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static IWithTwo _field; public static void Test () @@ -388,10 +388,10 @@ class OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemb class MultipleReferencesToTheSameType<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> { - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static TypeWithPublicMethods _field1; static TypeWithPublicMethods _field2; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static TypeWithPublicMethods _field3; } @@ -399,8 +399,8 @@ class TwoMismatchesInOne< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> { - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static IWithTwo _field; } @@ -450,12 +450,12 @@ public static void Test () class MultipleReferencesToTheSameType<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> { // The warning is generated on the backing field - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "", CompilerGeneratedCode = true)] // NativeAOT_StorageSpaceType static TypeWithPublicMethods Property1 { - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType get; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType set; } @@ -465,12 +465,12 @@ static TypeWithPublicMethods Property2 { } // The warning is generated on the backing field - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "", CompilerGeneratedCode = true)] // NativeAOT_StorageSpaceType static TypeWithPublicMethods Property3 { - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType get; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType set; } @@ -487,14 +487,14 @@ class TwoMismatchesInOne< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> { // The warnings are generated on the backing field - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "", CompilerGeneratedCode = true)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "", CompilerGeneratedCode = true)] // NativeAOT_StorageSpaceType static IWithTwo Property { // Getter is trimmed and doesn't produce any warning get; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType set; } @@ -554,7 +554,7 @@ static void MethodWithTwo< static MethodBody GetInstance () => null; - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // return type // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // return type // NativeAOT_StorageSpaceType static TypeWithPublicMethods GetInstanceForTypeWithPublicMethods () => null; class TypeOf @@ -578,8 +578,8 @@ static void SpecificType () } // Analyzer doesn't warn on typeof - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void MultipleReferencesToTheSameType< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -590,8 +590,8 @@ static void MultipleReferencesToTheSameType< } // Analyzer doesn't warn on typeof - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -694,8 +694,8 @@ static void TwoMismatchesInOneStatement< IWithTwo.Method (); } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // local variable // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // local variable // NativeAOT_StorageSpaceType static void InstanceMethodMismatch () { TypeWithPublicMethods instance = GetInstanceForTypeWithPublicMethods (); @@ -746,8 +746,8 @@ static void TwoMismatchesInOneStatement< _ = IWithTwo.Field; } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // access to the field // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // access to the field // NativeAOT_StorageSpaceType static void InstanceFieldMismatch () { TypeWithPublicMethods instance = GetInstanceForTypeWithPublicMethods (); @@ -779,8 +779,8 @@ static void SpecificType () TypeWithPublicMethods t = null; } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void MultipleReferencesToTheSameType< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -790,8 +790,8 @@ static void MultipleReferencesToTheSameType< TypeWithPublicMethods t3 = null; // Warn } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -952,9 +952,9 @@ static void SpecificType () // ldtoken owningtype // In order to call the right Expression APIs. [ExpectedWarning ("IL2091")] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] [ExpectedWarning ("IL2091")] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void MultipleReferencesToTheSameMethod< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -969,9 +969,9 @@ static void MultipleReferencesToTheSameMethod< // ldtoken owningtype // In order to call the right Expression APIs. [ExpectedWarning ("IL2091")] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] [ExpectedWarning ("IL2091")] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -1007,8 +1007,8 @@ static void SpecificType () // ldtoken field // ldtoken owningtype // In order to call the right Expression APIs. - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void MultipleReferencesToTheSameField< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -1024,8 +1024,8 @@ static void MultipleReferencesToTheSameField< // ldtoken field // ldtoken owningtype // In order to call the right Expression APIs. - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -1061,8 +1061,8 @@ static void SpecificType () // ldtoken method (getter) // ldtoken owningtype // In order to call the right Expression APIs. - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void MultipleReferencesToTheSameProperty< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -1078,8 +1078,8 @@ static void MultipleReferencesToTheSameProperty< // ldtoken method (getter) // ldtoken owningtype // In order to call the right Expression APIs. - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2091", Tool.Trimmer | Tool.NativeAot, "")] static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -1155,8 +1155,8 @@ static void SpecificType () bool a = _value is TypeWithPublicMethods; } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void MultipleReferencesToTheSameMethod< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -1166,8 +1166,8 @@ static void MultipleReferencesToTheSameMethod< bool a3 = _value is TypeWithPublicMethods; // Warn } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -1200,8 +1200,8 @@ static void SpecificType () object a = _value as TypeWithPublicMethods; } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void MultipleReferencesToTheSameMethod< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -1211,8 +1211,8 @@ static void MultipleReferencesToTheSameMethod< object a3 = _value as TypeWithPublicMethods; // Warn } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -1251,8 +1251,8 @@ static void SpecificType () } } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void MultipleReferencesToTheSameType< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -1273,8 +1273,8 @@ static void MultipleReferencesToTheSameType< } } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -1314,8 +1314,8 @@ static void SpecificType () } } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void MultipleReferencesToTheSameType< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> () @@ -1336,8 +1336,8 @@ static void MultipleReferencesToTheSameType< } } - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] // NativeAOT_StorageSpaceType static void TwoMismatchesInOneStatement< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> @@ -1373,14 +1373,14 @@ class AnnotatedString static void MethodWithAnnotatedParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] string typeName) { } // Analyzer: https://github.com/dotnet/runtime/issues/95118 - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "")] static void AnnotatedParameter () { MethodWithAnnotatedParameter ("Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithRUCMethod]]"); } // Analyzer: https://github.com/dotnet/runtime/issues/95118 - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static string AnnotatedReturnValue () { @@ -1391,7 +1391,7 @@ static string AnnotatedReturnValue () static string _annotatedField; // Analyzer: https://github.com/dotnet/runtime/issues/95118 - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "")] static void AnnotatedField () { _annotatedField = "Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithRUCMethod]]"; @@ -1408,7 +1408,7 @@ public static void Test () class TypeGetType { // Analyzer: https://github.com/dotnet/runtime/issues/95118 - [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "TypeWithRUCMethod.PrivateRUCMethod", Tool.Trimmer | Tool.NativeAot, "")] static void SpecificType () { Type.GetType ("Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithPrivateMethods`1[[Mono.Linker.Tests.Cases.DataFlow.GenericParameterWarningLocation+MethodBody+TypeWithRUCMethod]]"); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs index d99b7557a257a3..c5361f835534c9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs @@ -169,8 +169,8 @@ public void Method1 () { } public void Method2 () { } // https://github.com/dotnet/linker/issues/2273 - [ExpectedWarning ("IL2026", "--Method1--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2026", "--Method2--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--Method1--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "--Method2--", Tool.Trimmer | Tool.NativeAot, "")] public static void Test () { Type.GetType ("Mono.Linker.Tests.Cases.DataFlow." + nameof (GetTypeDataFlow) + "+" + nameof (TypeWithWarnings)).RequiresPublicMethods (); @@ -185,7 +185,7 @@ class OverConstTypeName public void Method1 () { } // https://github.com/dotnet/linker/issues/2273 - [ExpectedWarning ("IL2026", "--Method1--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--Method1--", Tool.Trimmer | Tool.NativeAot, "")] public static void Test () { Type.GetType (s_ConstTypeName).RequiresPublicMethods (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs index ea14e8b4f2867f..db2bc09e13e59b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs @@ -164,6 +164,9 @@ class TestType } [Kept] + // MyReflectOverType is not intrinsically understood by the analysis, so + // it doesn't satisfy the PublicFields | NonPublicFields requirement. + [ExpectedWarning ("IL2075")] public static void Test () { new MyReflectOverType (typeof (TestType)).GetFields (BindingFlags.Instance | BindingFlags.Public); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InlineArrayDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InlineArrayDataflow.cs index c7725fcdf2617c..5915bb2d45384c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InlineArrayDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InlineArrayDataflow.cs @@ -14,7 +14,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow [ExpectedNoWarnings] public class InlineArrayDataflow { - public static void Main() + public static void Main () { AccessPrimitiveTypeArray (); AccessUnannotatedTypeArray (); @@ -63,7 +63,7 @@ struct AnnotatedTypeArray } // Currently tracking of annotations on inline array values is not implemented - [ExpectedWarning("IL2065", "GetProperty")] + [ExpectedWarning ("IL2065", "GetProperty")] static void AccessAnnotatedTypeArray () { AnnotatedTypeArray a = new AnnotatedTypeArray (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InterpolatedStringHandlerDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InterpolatedStringDataFlow.cs similarity index 77% rename from src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InterpolatedStringHandlerDataFlow.cs rename to src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InterpolatedStringDataFlow.cs index 6e30b600d736a5..f862348ddec336 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InterpolatedStringHandlerDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/InterpolatedStringDataFlow.cs @@ -15,14 +15,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow [ExpectedNoWarnings] [SkipKeptItemsValidation] [Define ("DEBUG")] - public class InterpolatedStringHandlerDataFlow + public class InterpolatedStringDataFlow { public static void Main () { - Test (); + TestInterpolatedStringHandler (); + TestUnknownInterpolatedString (); } - static void Test(bool b = true) { + static void TestInterpolatedStringHandler (bool b = true) { // Creates a control-flow graph for the analyzer that has an // IFlowCaptureReferenceOperation that represents a capture // because it is used as an out param (so has IsInitialization = true). @@ -31,5 +32,10 @@ static void Test(bool b = true) { // where IsInitialization = true. Debug.Assert (b, $"Debug interpolated string handler {b}"); } + + [ExpectedWarning ("IL2057")] + static void TestUnknownInterpolatedString (string input = "test") { + Type.GetType ($"{input}"); + } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs index 788312c2c262df..71b08b3a6af17e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs @@ -218,8 +218,7 @@ public static void TestBranchMergeCatch () nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()")] // ILLink produces extraneous warnings [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)", - nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer)] + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", Tool.Trimmer, "")] public static void TestBranchMergeFinally () { string str = GetWithPublicMethods (); @@ -235,8 +234,7 @@ public static void TestBranchMergeFinally () } // Analyzer gets this right (no warning), but trimmer merges all branches going forward. - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)", Tool.Trimmer, "")] public static void TestBranchGoto () { string str = GetWithPublicMethods (); @@ -249,8 +247,7 @@ public static void TestBranchGoto () } // Analyzer gets this right (no warning), but trimmer merges all branches going forward. - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), Tool.Trimmer, "")] public static void TestBranchIf () { string str = GetWithPublicMethods (); @@ -261,8 +258,7 @@ public static void TestBranchIf () } // Analyzer gets this right (no warning), but trimmer merges all branches going forward. - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), Tool.Trimmer, "")] public static void TestBranchIfElse () { string str; @@ -278,18 +274,12 @@ public static void TestBranchIfElse () } // Analyzer gets this right (no warning), but trimmer merges all branches going forward. - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresNonPublicMethods) + "(String)", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresNonPublicMethods) + "(String)", Tool.Trimmer, "")] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", Tool.Trimmer, "")] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", Tool.Trimmer, "")] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", Tool.Trimmer, "")] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", Tool.Trimmer, "")] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", Tool.Trimmer, "")] public static void TestBranchSwitch () { string str = null; @@ -315,8 +305,7 @@ public static void TestBranchSwitch () // Analyzer gets this right (no warning), but trimmer merges all branches going forward. [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), - nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer)] + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", Tool.Trimmer, "")] public static void TestBranchTry () { string str = GetWithPublicMethods (); @@ -332,8 +321,7 @@ public static void TestBranchTry () // Analyzer gets this right (no warning), but trimmer merges all branches going forward. [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), - nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer)] + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", Tool.Trimmer, "")] public static void TestBranchCatch () { string str = GetWithPublicMethods (); @@ -348,8 +336,7 @@ public static void TestBranchCatch () // Analyzer gets this right (no warning), but trimmer merges all branches going forward. [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), - nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", - ProducedBy = Tool.Trimmer)] + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", Tool.Trimmer, "")] public static void TestBranchFinally () { string str = GetWithPublicMethods (); @@ -365,8 +352,7 @@ public static void TestBranchFinally () // Analyzer gets this right, but ILLink doesn't consider backwards branches. [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", - nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] public static void TestBackwardsEdgeLoop () { string str = GetWithPublicMethods (); @@ -382,8 +368,7 @@ public static void TestBackwardsEdgeLoop () // Analyzer gets this right, but ILLink doesn't consider backwards branches. [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", - nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()", - ProducedBy = Tool.Analyzer)] + nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()", Tool.Analyzer, "")] public static void TestBackwardsEdgeGoto () { string str = null; @@ -440,8 +425,8 @@ public virtual void VirtualMethod () // https://github.com/dotnet/linker/issues/2273 // Analyzer doesn't see through foreach over array at all - will not warn - [ExpectedWarning ("IL2063", ProducedBy = Tool.Trimmer)] // The types loaded from the array don't have annotations, so the "return" should warn - [ExpectedWarning ("IL2073", ProducedBy = Tool.Analyzer)] // Analyzer tracks resultType as the value from IEnumerable.Current.get() + [ExpectedWarning ("IL2063", Tool.Trimmer, "")] // The types loaded from the array don't have annotations, so the "return" should warn + [ExpectedWarning ("IL2073", Tool.Analyzer, "")] // Analyzer tracks resultType as the value from IEnumerable.Current.get() [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public static Type TestBackwardEdgeWithLdElem (Type[] types = null) { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs index 50451dcd3f1e4e..32342ee39eecbc 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs @@ -126,7 +126,7 @@ static void TestWithRequirementsFromParam ( } // https://github.com/dotnet/linker/issues/2428 - // [ExpectedWarning ("IL2071", "'T'")] + // [ExpectedSharedWarning ("IL2071", "'T'")] [ExpectedWarning ("IL2070", "'this'")] static void TestWithRequirementsFromParamWithMismatch ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) @@ -141,7 +141,7 @@ static void TestWithRequirementsFromGenericParam< } // https://github.com/dotnet/linker/issues/2428 - // [ExpectedWarning ("IL2091", "'T'")] + // [ExpectedSharedWarning ("IL2091", "'T'")] [ExpectedWarning ("IL2090", "'this'")] // Note that this actually produces a warning which should not be possible to produce right now static void TestWithRequirementsFromGenericParamWithMismatch< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TInput> () @@ -551,7 +551,7 @@ static void TestWithArrayUnknownIndexSet (int indexToSet) } // https://github.com/dotnet/linker/issues/2158 - analyzer doesn't work the same as ILLink, it simply doesn't handle refs - [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod), Tool.Trimmer | Tool.NativeAot, "")] static void TestWithArrayUnknownIndexSetByRef (int indexToSet) { Type[] types = new Type[1]; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataflowIntrinsics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataflowIntrinsics.cs index 4fe39ab6da1ca4..b1a67bd42dbdfe 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataflowIntrinsics.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataflowIntrinsics.cs @@ -34,10 +34,10 @@ public static void Test () public static void TestRecognizedGenericIntrinsic () => typeof (Gen<>).MakeGenericType (typeof (T)); [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))] - [ExpectedWarning ("IL3050", nameof (Type.MakeGenericType), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (Type.MakeGenericType), Tool.Analyzer | Tool.NativeAot, "")] public static void TestUnknownOwningType () => GrabUnknownType ().MakeGenericType (typeof (object)); - [ExpectedWarning ("IL3050", nameof (Type.MakeGenericType), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (Type.MakeGenericType), Tool.Analyzer | Tool.NativeAot, "")] public static void TestUnknownArgument () => typeof (Gen<>).MakeGenericType (GrabUnknownType ()); } @@ -62,10 +62,10 @@ public static void Test () public static void TestRecognizedGenericIntrinsic () => typeof (MakeGenericMethod).GetMethod (nameof (Gen)).MakeGenericMethod (typeof (T)); [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))] - [ExpectedWarning ("IL3050", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (MethodInfo.MakeGenericMethod), Tool.Analyzer | Tool.NativeAot, "")] public static void TestUnknownOwningMethod () => GrabUnknownMethod ().MakeGenericMethod (typeof (object)); - [ExpectedWarning ("IL3050", nameof (MethodInfo.MakeGenericMethod), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", nameof (MethodInfo.MakeGenericMethod), Tool.Analyzer | Tool.NativeAot, "")] public static void TestUnknownArgument () => typeof (MakeGenericMethod).GetMethod (nameof (Gen)).MakeGenericMethod (GrabUnknownType()); } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs index 7ea036c5c39bbd..4396d6c26e3b2f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefParameterDataFlow.cs @@ -123,7 +123,7 @@ static void TestReadFromRefParameter_MismatchOnOutput_PassedTwice () // https://github.com/dotnet/linker/issues/2632 // This second warning should not be generated, the value of typeWithMethods should have PublicMethods // after the call with out parameter. - [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Analyzer, "")] static void TestReadFromRefParameter_MismatchOnInput () { Type typeWithMethods = GetTypeWithFields (); @@ -136,7 +136,7 @@ static void TestReadFromRefParameter_MismatchOnInput () // https://github.com/dotnet/linker/issues/2632 // This third warning should not be generated, the value of typeWithMethods should have PublicMethods // after the call with ref parameter. - [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Analyzer, "")] static void TestReadFromRefParameter_MismatchOnInput_PassedTwice () { Type typeWithMethods = GetTypeWithFields (); @@ -269,7 +269,7 @@ static void TestPassingRefProperty_OutParameter () TryGetAnnotatedValueOut (out TypeWithMethodsProperty); } - [ExpectedWarning ("IL2072", nameof (TryGetAnnotatedValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", nameof (TryGetAnnotatedValue), Tool.Trimmer | Tool.NativeAot, "")] static void TestPassingRefProperty_Mismatch () { TryGetAnnotatedValue (ref TypeWithFieldsProperty); @@ -316,8 +316,8 @@ static void TestPassingRefIndexer_OutParameter () } // https://github.com/dotnet/linker/issues/2158 - [ExpectedWarning ("IL2068", nameof (TryGetAnnotatedValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2072", nameof (TryGetAnnotatedValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2068", nameof (TryGetAnnotatedValue), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2072", nameof (TryGetAnnotatedValue), Tool.Trimmer | Tool.NativeAot, "")] static void TestPassingRefIndexer_Mismatch () { var indexer = new RefIndexer_PublicFields (); @@ -325,7 +325,7 @@ static void TestPassingRefIndexer_Mismatch () } // https://github.com/dotnet/linker/issues/2158 - [ExpectedWarning ("IL2068", nameof (TryGetAnnotatedValue), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2068", nameof (TryGetAnnotatedValue), Tool.Trimmer | Tool.NativeAot, "")] static void TestPassingRefIndexer_OutParameter_Mismatch () { var indexer = new RefIndexer_PublicFields (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefReturnDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefReturnDataFlow.cs index 7220a83d3ce2dd..99978295d67570 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefReturnDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodByRefReturnDataFlow.cs @@ -43,7 +43,7 @@ public static void Main () // Correct behavior in the trimming tools, but needs to be added in analyzer // Bug link: https://github.com/dotnet/linker/issues/2158 - [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", Tool.Trimmer | Tool.NativeAot, "")] static void AssignToAnnotatedTypeReference () { ref Type typeShouldHaveAllMethods = ref ReturnAnnotatedTypeReferenceAsAnnotated (); @@ -53,7 +53,7 @@ static void AssignToAnnotatedTypeReference () // Same as above for IL analysis, but this looks different to the Roslyn analyzer. // https://github.com/dotnet/linker/issues/2158 - [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", Tool.Trimmer | Tool.NativeAot, "")] static void AssignDirectlyToAnnotatedTypeReference () { ReturnAnnotatedTypeReferenceAsAnnotated () = typeof (TestTypeWithRequires); @@ -61,7 +61,7 @@ static void AssignDirectlyToAnnotatedTypeReference () } // https://github.com/dotnet/linker/issues/2158 - [ExpectedWarning ("IL2073", nameof (GetWithPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2073", nameof (GetWithPublicFields), Tool.Trimmer | Tool.NativeAot, "")] static void AssignToCapturedAnnotatedTypeReference () { // In this testcase, the Roslyn analyzer sees an assignment to a flow-capture reference. @@ -69,7 +69,7 @@ static void AssignToCapturedAnnotatedTypeReference () } [ExpectedWarning ("IL2072", nameof (GetWithPublicMethods), nameof (ReturnAnnotatedTypeWithRequirements))] - [ExpectedWarning ("IL2073", nameof (ReturnAnnotatedTypeWithRequirements), nameof (GetWithPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2073", nameof (ReturnAnnotatedTypeWithRequirements), nameof (GetWithPublicFields), Tool.Trimmer | Tool.NativeAot, "")] static void AssignToAnnotatedTypeReferenceWithRequirements () { ReturnAnnotatedTypeWithRequirements (GetWithPublicMethods ()) = GetWithPublicFields (); @@ -80,7 +80,7 @@ static void AssignToAnnotatedTypeReferenceWithRequirements () [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static ref Type AnnotatedTypeReferenceAsAnnotatedProperty => ref _annotatedField; - [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", Tool.Trimmer | Tool.NativeAot, "")] static void AssignToAnnotatedTypeReferenceProperty () { ref Type typeShouldHaveAllMethods = ref AnnotatedTypeReferenceAsAnnotatedProperty; @@ -89,7 +89,7 @@ static void AssignToAnnotatedTypeReferenceProperty () } // https://github.com/dotnet/linker/issues/2158 - [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "Message for --TestType.Requires--", Tool.Trimmer | Tool.NativeAot, "")] static void AssignDirectlyToAnnotatedTypeReferenceProperty () { AnnotatedTypeReferenceAsAnnotatedProperty = typeof (TestTypeWithRequires); @@ -97,7 +97,7 @@ static void AssignDirectlyToAnnotatedTypeReferenceProperty () } // https://github.com/dotnet/linker/issues/2158 - [ExpectedWarning ("IL2073", nameof (GetWithPublicFields), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2073", nameof (GetWithPublicFields), Tool.Trimmer | Tool.NativeAot, "")] static void AssignToCapturedAnnotatedTypeReferenceProperty () { AnnotatedTypeReferenceAsAnnotatedProperty = GetWithPublicMethods () ?? GetWithPublicFields (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodOutParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodOutParameterDataFlow.cs index 582c86ee012b4b..911f2f48ec0582 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodOutParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodOutParameterDataFlow.cs @@ -19,6 +19,7 @@ public static void Main () TestInitializedReadFromOutParameter_PassedTwice (); TestUninitializedReadFromOutParameter (); TestInitializedReadFromOutParameter_MismatchOnOutput (); + TestInitializedReturnOutParameter_MismatchOnOutput (); TestInitializedReadFromOutParameter_MismatchOnOutput_PassedTwice (); TestInitializedReadFromOutParameter_MismatchOnInput (); TestInitializedReadFromOutParameter_MismatchOnInput_PassedTwice (); @@ -55,7 +56,7 @@ static void TestUninitializedReadFromOutParameter () typeWithMethods.RequiresPublicMethods (); } - [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2632")] static void TestInitializedReadFromOutParameter_MismatchOnOutput () { Type typeWithMethods = null; @@ -63,9 +64,18 @@ static void TestInitializedReadFromOutParameter_MismatchOnOutput () typeWithMethods.RequiresPublicFields (); } - // https://github.com/dotnet/linker/issues/2632 // This test should generate a warning since there's mismatch on annotations - [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2068", nameof (TryGetAnnotatedValue), nameof (DynamicallyAccessedMemberTypes.PublicFields), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2632")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + static Type TestInitializedReturnOutParameter_MismatchOnOutput () + { + Type typeWithMethods = null; + TryGetAnnotatedValue (out typeWithMethods); + return typeWithMethods; + } + + // This test should generate a warning since there's mismatch on annotations + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2632")] static void TestInitializedReadFromOutParameter_MismatchOnOutput_PassedTwice () { Type typeWithMethods = null; @@ -73,10 +83,9 @@ static void TestInitializedReadFromOutParameter_MismatchOnOutput_PassedTwice () typeWithMethods.RequiresPublicFields (); } - // https://github.com/dotnet/linker/issues/2632 // This warning should not be generated, the value of typeWithMethods should have PublicMethods // after the call with out parameter. - [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Analyzer, "https://github.com/dotnet/linker/issues/2632")] static void TestInitializedReadFromOutParameter_MismatchOnInput () { Type typeWithMethods = GetTypeWithFields (); @@ -86,10 +95,9 @@ static void TestInitializedReadFromOutParameter_MismatchOnInput () } [ExpectedWarning ("IL2072", nameof (TryGetAnnotatedValueFromValue))] - // https://github.com/dotnet/linker/issues/2632 // This warning should not be generated, the value of typeWithMethods should have PublicMethods // after the call with out parameter. - [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicMethods), Tool.Analyzer, "https://github.com/dotnet/linker/issues/2632")] static void TestInitializedReadFromOutParameter_MismatchOnInput_PassedTwice () { Type typeWithMethods = GetTypeWithFields (); @@ -103,7 +111,7 @@ static void TestPassingOutParameter ([DynamicallyAccessedMembers (DynamicallyAcc TryGetAnnotatedValue (out typeWithMethods); } - [ExpectedWarning ("IL2067", "typeWithFields", nameof (TryGetAnnotatedValue))] + [ExpectedWarning ("IL2067", "typeWithFields", nameof (TryGetAnnotatedValue), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/linker/issues/2632")] static void TestPassingOutParameter_Mismatch ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] out Type typeWithFields) { TryGetAnnotatedValue (out typeWithFields); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs index 0c6c1d02d8c10c..aa2783332e429e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs @@ -142,8 +142,6 @@ private void TwoAnnotatedParameters ( type2.RequiresPublicConstructors (); } - // TODO: https://github.com/dotnet/linker/issues/2273 - // (Dataflow analysis is not supported by the analyzer yet) [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)", "'type'")] @@ -246,7 +244,7 @@ class UnsupportedType () static UnsupportedType GetUnsupportedTypeInstance () => null; [ExpectedWarning ("IL2098", nameof (UnsupportedType))] - [ExpectedWarning ("IL2067", ProducedBy = Tool.Analyzer)] // https://github.com/dotnet/runtime/issues/101211 + [ExpectedWarning ("IL2067", Tool.Analyzer, "")] // https://github.com/dotnet/runtime/issues/101211 static void RequirePublicMethods ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] UnsupportedType unsupportedTypeInstance) @@ -261,7 +259,7 @@ static void RequirePublicFields ( { } - [ExpectedWarning ("IL2072", ProducedBy = Tool.Analyzer)] // https://github.com/dotnet/runtime/issues/101211 + [ExpectedWarning ("IL2072", Tool.Analyzer, "")] // https://github.com/dotnet/runtime/issues/101211 public static void Test () { var t = GetUnsupportedTypeInstance (); RequirePublicMethods (t); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs index 4bd9257124654b..14c881bf2e4bdd 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs @@ -190,7 +190,7 @@ class AnnotationOnUnsupportedReturnType { class UnsupportedType { - [ExpectedWarning ("IL2082", ProducedBy = Tool.Analyzer)] // https://github.com/dotnet/runtime/issues/101211 + [UnexpectedWarning ("IL2082", Tool.Analyzer, "https://github.com/dotnet/runtime/issues/101211")] public UnsupportedType () { RequirePublicFields (this); } @@ -201,8 +201,7 @@ public UnsupportedType () { [ExpectedWarning ("IL2106")] // Linker and NativeAot should not produce IL2073 // They produce dataflow warnings despite the invalid annotations. - // https://github.com/dotnet/runtime/issues/101211 - [ExpectedWarning ("IL2073", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2073", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/101211")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static UnsupportedType GetWithPublicMethods () { return GetUnsupportedTypeInstance (); @@ -215,12 +214,13 @@ static void RequirePublicFields ( { } - [ExpectedWarning ("IL2072", ProducedBy = Tool.Analyzer)] // https://github.com/dotnet/runtime/issues/101211 + [ExpectedWarning ("IL2072", Tool.Analyzer, "https://github.com/dotnet/runtime/issues/101211")] static void TestMethodReturnValue () { var t = GetWithPublicMethods (); RequirePublicFields (t); } + [ExpectedWarning ("IL2072", Tool.Analyzer, "https://github.com/dotnet/runtime/issues/101211")] static void TestCtorReturnValue () { var t = new UnsupportedType (); RequirePublicFields (t); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs index 28dc0669d2aa02..c57d784bce24db 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs @@ -122,7 +122,7 @@ static void RequirePublicFields ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] UnsupportedType unsupportedTypeInstance) { } - [ExpectedWarning ("IL2075", nameof (UnsupportedType), nameof (UnsupportedType.GetMethod), ProducedBy = Tool.Analyzer)] // BUG + [ExpectedWarning ("IL2075", nameof (UnsupportedType), nameof (UnsupportedType.GetMethod), Tool.Analyzer, "https://github.com/dotnet/runtime/issues/101211")] static void TestMethodThisParameter () { var t = GetUnsupportedTypeInstance (); t.GetMethod ("foo"); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ObjectGetTypeDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ObjectGetTypeDataflow.cs new file mode 100644 index 00000000000000..e089abd68955b3 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/ObjectGetTypeDataflow.cs @@ -0,0 +1,44 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class ObjectGetTypeDataflow + { + public static void Main () + { + SealedConstructorAsSource.Test (); + } + + class SealedConstructorAsSource + { + [KeptMember (".ctor()")] + public class Base + { + } + + [KeptMember (".ctor()")] + [KeptBaseType (typeof (Base))] + public sealed class Derived : Base + { + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (Method))] + public void Method () { } + } + + [ExpectedWarning ("IL2026", nameof (Derived.Method))] + public static void Test () + { + new Derived ().GetType ().GetMethod ("Method"); + } + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs index 1a8930c8a7c8e0..76a1a48a06425c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs @@ -215,8 +215,7 @@ static Type PropertyWithSimpleGetter { // is highly unlikely to be done by anybody. If it happens, the analyzer will produce warnings which the trimming tools will not // but those warnings are not really wrong, so it's better if the developer fixes them anyway. [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)", - nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field), - ProducedBy = Tool.Analyzer)] + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field), Tool.Analyzer, "")] public void TestPropertyWhichLooksLikeCompilerGenerated () { // If the property was correctly recognized both the property getter and the backing field should get the annotation. @@ -231,8 +230,7 @@ public void TestPropertyWhichLooksLikeCompilerGenerated () static Type PropertyWhichLooksLikeCompilerGenerated { // See above comment about fake compiler generated backing fields - this warning is expected from the analyzer [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated) + ".get", - nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field), - ProducedBy = Tool.Analyzer)] + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field), Tool.Analyzer, "")] get { return PropertyWhichLooksLikeCompilerGenerated_Field; } @@ -272,17 +270,14 @@ public void TestPropertyWithDifferentBackingFields () // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 [ExpectedWarning ("IL2042", - "Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithDifferentBackingFields", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + "Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithDifferentBackingFields", Tool.Trimmer | Tool.NativeAot, "")] [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get", - "Type", - ProducedBy = Tool.Analyzer)] + "Type", Tool.Analyzer, "")] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type PropertyWithDifferentBackingFields { [ExpectedWarning ("IL2078", - nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get", Tool.Trimmer | Tool.NativeAot, "")] get { return PropertyWithDifferentBackingFields_GetterField; } @@ -299,25 +294,22 @@ public void TestPropertyWithExistingAttributes () } // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 - [ExpectedWarning ("IL2056", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes_Field", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2056", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes_Field", Tool.Trimmer | Tool.NativeAot, "")] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] [CompilerGenerated] Type PropertyWithExistingAttributes_Field; - [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2043", ["PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get"], Tool.Analyzer, "")] + [ExpectedWarning ("IL2043", [ "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set"], Tool.Analyzer, "")] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type PropertyWithExistingAttributes { // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 - [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get", Tool.Trimmer | Tool.NativeAot, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] get { return PropertyWithExistingAttributes_Field; } // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 - [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set", Tool.Trimmer | Tool.NativeAot, "")] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] set { PropertyWithExistingAttributes_Field = value; } } @@ -337,25 +329,22 @@ public void TestPropertyWithConflictingAttributes () } // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 - [ExpectedWarning ("IL2056", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes_Field", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2056", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes_Field", Tool.Trimmer | Tool.NativeAot, "")] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] [CompilerGenerated] Type PropertyWithConflictingAttributes_Field; - [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.get", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.set", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2043", ["PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.get"], Tool.Analyzer, "")] + [ExpectedWarning ("IL2043", ["PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.set"], Tool.Analyzer, "")] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type PropertyWithConflictingAttributes { // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 - [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.get", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.get", Tool.Trimmer | Tool.NativeAot, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] get { return PropertyWithConflictingAttributes_Field; } // On property/accessor mismatch, ILLink warns on accessor and analyzer warns on property https://github.com/dotnet/linker/issues/2654 - [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.set", - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.set", Tool.Trimmer | Tool.NativeAot, "")] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] set { PropertyWithConflictingAttributes_Field = value; } } @@ -382,8 +371,7 @@ public void TestPropertyWithConflictingNoneAttributes () Type PropertyWithConflictingNoneAttributes { // See above comment about fake compiler generated backing fields - this warning is expected from analyzer [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes) + ".get", - nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes_Field), - ProducedBy = Tool.Analyzer)] + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes_Field), Tool.Analyzer, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.None)] get { return PropertyWithConflictingNoneAttributes_Field; } @@ -399,8 +387,8 @@ public void TestPropertyWithIndexerWithMatchingAnnotations ([DynamicallyAccessed } // Trimmer and analyzer handle formatting of indexers differently. - [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".this[Int32].set", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".Item.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".this[Int32].set", Tool.Analyzer, "")] [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)")] [LogDoesNotContain ("'Value passed to parameter 'index' of method 'Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithIndexer.Item.set'")] public void TestPropertyWithIndexerWithoutMatchingAnnotations (Type myType) @@ -418,8 +406,8 @@ public class PropertyWithIndexer [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] public Type this[int index] { // Trimmer and analyzer handle formatting of indexers differently. - [ExpectedWarning ("IL2063", nameof (PropertyWithIndexer) + ".Item.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2063", nameof (PropertyWithIndexer) + ".this[Int32].get", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2063", nameof (PropertyWithIndexer) + ".Item.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2063", nameof (PropertyWithIndexer) + ".this[Int32].get", Tool.Analyzer, "")] get => Property_Field[index]; set => Property_Field[index] = value; } @@ -482,8 +470,7 @@ class WriteToGetOnlyProperty public Type GetOnlyProperty { get; } // Analyzer doesn't warn about compiler-generated backing field of property: https://github.com/dotnet/runtime/issues/93277 - [ExpectedWarning ("IL2074", nameof (WriteToGetOnlyProperty), nameof (GetUnknownType), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2074", nameof (WriteToGetOnlyProperty), nameof (GetUnknownType), Tool.Trimmer | Tool.NativeAot, "")] public WriteToGetOnlyProperty () { GetOnlyProperty = GetUnknownType (); @@ -562,10 +549,8 @@ class WriteCapturedGetOnlyProperty Type GetOnlyProperty { get; } // Analyzer doesn't warn about compiler-generated backing field of property: https://github.com/dotnet/runtime/issues/93277 - [ExpectedWarning ("IL2074", nameof (WriteCapturedGetOnlyProperty), nameof (GetUnknownType), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2074", nameof (WriteCapturedGetOnlyProperty), nameof (GetTypeWithPublicConstructors), - ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2074", nameof (WriteCapturedGetOnlyProperty), nameof (GetUnknownType), Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2074", nameof (WriteCapturedGetOnlyProperty), nameof (GetTypeWithPublicConstructors), Tool.Trimmer | Tool.NativeAot, "")] public WriteCapturedGetOnlyProperty () { GetOnlyProperty = GetUnknownType () ?? GetTypeWithPublicConstructors (); @@ -677,15 +662,15 @@ Type this[Index idx] { set => throw new NotImplementedException (); } - [ExpectedWarning ("IL2072", "this[Index].get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", ["this[Index].get", nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", ["Item.get", nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Trimmer | Tool.NativeAot, "")] static void TestRead (ExplicitIndexerAccess instance = null) { instance[new Index (1)].RequiresAll (); } - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "this[Index].set", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", [nameof (GetTypeWithPublicConstructors), "this[Index].set"], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", [nameof (GetTypeWithPublicConstructors), "Item.set"], Tool.Trimmer | Tool.NativeAot, "")] static void TestWrite (ExplicitIndexerAccess instance = null) { instance[^1] = GetTypeWithPublicConstructors (); @@ -708,22 +693,22 @@ Type this[int idx] { int Length => throw new NotImplementedException (); - [ExpectedWarning ("IL2072", "this[Int32].get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", ["this[Int32].get", nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", ["Item.get", nameof (DataFlowTypeExtensions.RequiresAll)], Tool.Trimmer | Tool.NativeAot, "")] static void TestRead (ImplicitIndexerAccess instance = null) { instance[new Index (1)].RequiresAll (); } - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "this[Int32].set", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", [nameof (GetTypeWithPublicConstructors), "this[Int32].set"], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", [nameof (GetTypeWithPublicConstructors), "Item.set"], Tool.Trimmer | Tool.NativeAot, "")] static void TestWrite (ImplicitIndexerAccess instance = null) { instance[^1] = GetTypeWithPublicConstructors (); } - [ExpectedWarning ("IL2072", nameof (GetUnknownType), "this[Int32].set", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2072", nameof (GetUnknownType), "Item.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072", [nameof (GetUnknownType), "this[Int32].set"], Tool.Analyzer, "")] + [ExpectedWarning ("IL2072", [nameof (GetUnknownType), "Item.set"], Tool.Trimmer | Tool.NativeAot, "")] static void TestNullCoalescingAssignment (ImplicitIndexerAccess instance = null) { instance[new Index (1)] ??= GetUnknownType (); @@ -747,8 +732,8 @@ int this[[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicField get => throw new NotImplementedException (); } - [ExpectedWarning ("IL2067", "this[Type].get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2067", ["this[Type].get", nameof (ParamDoesNotMeetRequirements)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2067", ["Item.get", nameof (ParamDoesNotMeetRequirements)], Tool.Trimmer | Tool.NativeAot, "")] static void ParamDoesNotMeetRequirements (Type t) { var x = new IndexWithTypeWithDam (); @@ -761,8 +746,8 @@ static void ParamDoesMeetRequirements ([DynamicallyAccessedMembers (DynamicallyA _ = x[t]; } - [ExpectedWarning ("IL2087", "this[Type].get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2087", "Item.get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2087", ["this[Type].get", nameof (TypeParamDoesNotMeetRequirements)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2087", ["Item.get", nameof (TypeParamDoesNotMeetRequirements)], Tool.Trimmer | Tool.NativeAot, "")] static void TypeParamDoesNotMeetRequirements () { var x = new IndexWithTypeWithDam (); @@ -802,8 +787,8 @@ Type this[[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFiel [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static Type fieldWithMethods; - [ExpectedWarning ("IL2067", "this[Type].get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.get", nameof (ParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2067", ["this[Type].get", nameof (ParamDoesNotMeetRequirements)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2067", ["Item.get", nameof (ParamDoesNotMeetRequirements)], Tool.Trimmer | Tool.NativeAot, "")] static void ParamDoesNotMeetRequirements (Type t) { var x = new IndexWithTypeWithDam (); @@ -816,8 +801,8 @@ static void ParamDoesMeetRequirements ([DynamicallyAccessedMembers (DynamicallyA fieldWithMethods = x[t]; } - [ExpectedWarning ("IL2087", "this[Type].get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2087", "Item.get", nameof (TypeParamDoesNotMeetRequirements), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2087", ["this[Type].get", nameof (TypeParamDoesNotMeetRequirements)], Tool.Analyzer, "")] + [ExpectedWarning ("IL2087", ["Item.get", nameof (TypeParamDoesNotMeetRequirements)], Tool.Trimmer | Tool.NativeAot, "")] static void TypeParamDoesNotMeetRequirements () { var x = new IndexWithTypeWithDam (); @@ -839,16 +824,16 @@ static void KnownTypeDoesMeetRequirements () fieldWithMethods = x[t]; } - [ExpectedWarning ("IL2067", "this[Type].set", nameof (t), "idx", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.set", nameof (t), "idx", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2067", ["this[Type].set", nameof (t), "idx"], Tool.Analyzer, "")] + [ExpectedWarning ("IL2067", ["Item.set", nameof (t), "idx"], Tool.Trimmer | Tool.NativeAot, "")] static void ValueMeetsRequirementsIndexDoesNot (Type t) { var x = new IndexWithTypeWithDam (); x[t] = fieldWithMethods; } - [ExpectedWarning ("IL2067", "this[Type].set", nameof (tUnannotated), "value", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2067", "Item.set", nameof (tUnannotated), "value", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2067", ["this[Type].set", nameof (tUnannotated), "value"], Tool.Analyzer, "")] + [ExpectedWarning ("IL2067", ["Item.set", nameof (tUnannotated), "value"], Tool.Trimmer | Tool.NativeAot, "")] static void ValueDoesNotMeetRequirementsIndexDoes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type t, Type tUnannotated) { var x = new IndexWithTypeWithDam (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs index 415dff13582ba6..983fc35c0b11eb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/RefFieldDataFlow.cs @@ -14,10 +14,10 @@ class RefFieldDataFlow { [Kept] // Bug for the IL2069's here: https://github.com/dotnet/runtime/issues/85464 - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2069", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2069", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2069", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2069", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2069", Tool.Trimmer | Tool.NativeAot, "")] public static void Main () { RefFieldWithMethods withMethods = new (ref fieldWithMethods); @@ -96,11 +96,11 @@ static void AssignRefToLocals< tmf = typeof (TF); // This is a hole that doesn't warn but assigns a misannotated value to target.T } - [ExpectedWarning ("IL2089", "RefFieldWithMethods", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2089", "RefFieldWithMethods", "T", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2089", "RefFieldWithMethodsAndFields", "T", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2089", "RefFieldWithFields", "T", Tool.Trimmer | Tool.NativeAot, "")] static void AssignRefLocals< T, [DAM (DAMT.PublicMethods)] TM, @@ -176,13 +176,13 @@ static void AssignParameters (scoped RefFieldWithMethods target, // ILLink doesn't recognize ldind.ref // https://github.com/dotnet/runtime/issues/85465 // IL2064's are bugs - shouldn't be unknown values - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2064", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2069", "RefFieldWithMethods.T", "param", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2069", "RefFieldWithMethods.T", "paramWithFields", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2064", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2064", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2064", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2064", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2064", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2069", "RefFieldWithMethods.T", "param", Tool.Analyzer, "")] + [ExpectedWarning ("IL2069", "RefFieldWithMethods.T", "paramWithFields", Tool.Analyzer, "")] static void AssignRefParameters< T, [DAM (DAMT.PublicMethods)] TM, @@ -233,15 +233,15 @@ static void AssignFields (RefFieldWithMethods target, UnannotatedField unannotat [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldUnannotated.T")] [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldWithFields.T")] - [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldUnannotated.T", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldWithFields.T", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldUnannotated.T", Tool.Analyzer, "")] + [ExpectedWarning ("IL2079", "RefFieldWithMethods.T", "RefFieldWithFields.T", Tool.Analyzer, "")] // IL2064's are bugs - shouldn't be unknown values // https://github.com/dotnet/runtime/issues/85465 - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = unannotated.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethods.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withFields.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethodsAndFields.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethodsAndFields.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = unannotated.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withMethods.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withFields.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withMethodsAndFields.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withMethodsAndFields.T; static void AssignRefFields ( RefFieldWithMethods target, RefFieldUnannotated unannotated, @@ -265,14 +265,14 @@ static void AssignRefFields ( [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefWithFields")] [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefUnannotated")] [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefWithFields")] - [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefUnannotated", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefWithFields", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefUnannotated", Tool.Analyzer, "")] + [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "GetRefWithFields", Tool.Analyzer, "")] // IL2064's are bugs - shouldn't be unknown values // https://github.com/dotnet/runtime/issues/85465 - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; static void AssignRefReturns< T, [DAM (DAMT.PublicMethods)] TM, @@ -348,26 +348,26 @@ static void AssignProperties (RefFieldWithMethods target, } // target.T = x.T - [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropUnannotated.T", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropWithFields.T", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropUnannotated.T", Tool.Analyzer, "")] + [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropWithFields.T", Tool.Analyzer, "")] // target.T = t; - [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropUnannotated.T", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropWithFields.T", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropUnannotated.T", Tool.Analyzer, "")] + [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropWithFields.T", Tool.Analyzer, "")] // target.T = ref x.T [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropUnannotated.T")] [ExpectedWarning ("IL2074", "RefFieldWithMethods.T", "RefPropWithFields.T")] // ref Type t = ref x.T; target.T = t; // IL2064's are bugs - shouldn't be unknown values // https://github.com/dotnet/runtime/issues/85465 - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = unannotated.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethods.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withFields.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethodsAndFieldswithMtho.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = withMethods.T; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; - [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", ProducedBy = Tool.Trimmer | Tool.NativeAot)] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = unannotated.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withMethods.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withFields.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withMethodsAndFieldswithMtho.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = withMethods.T; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; + [ExpectedWarning ("IL2064", "RefFieldWithMethods.T", Tool.Trimmer | Tool.NativeAot, "")] // target.T = t; static void AssignRefProperties (RefFieldWithMethods target, RefPropUnannotated unannotated = null, RefPropWithMethods withMethods = null, diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs index 8fc0362921be41..2933e51ba7768c 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs @@ -59,8 +59,7 @@ static void TestAllPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedM class AllPropagatedWithDerivedClass { // https://github.com/dotnet/linker/issues/2673 - [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll) + "(Type)", nameof (TestSystemTypeBase.BaseType) + ".get", - ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll) + "(Type)", nameof (TestSystemTypeBase.BaseType) + ".get", Tool.Analyzer, "")] static void TestAllPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] TestSystemTypeBase derivedType) { derivedType.BaseType.RequiresAll (); @@ -284,7 +283,7 @@ static void EnumerateInterfacesOnBaseTypes ([DynamicallyAccessedMembers (Dynamic } [ExpectedWarning ("IL2070")] - [ExpectedWarning ("IL2075", ProducedBy = Tool.Analyzer)] // ILLink doesn't implement backward branches data flow yet + [ExpectedWarning ("IL2075", Tool.Analyzer, "")] // ILLink doesn't implement backward branches data flow yet static void EnumerateInterfacesOnBaseTypes_Unannotated (Type type) { Type? t = type; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs index e32c8727f91e09..130f7ade7aa150 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs @@ -45,9 +45,9 @@ static void MethodWithUnresolvedGenericArgument< { } [Kept] - [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument", ProducedBy = Tool.Trimmer | Tool.Analyzer)] // Local variable type - [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument", ProducedBy = Tool.Trimmer | Tool.Analyzer)] // Called method declaring type - [ExpectedWarning ("IL2066", nameof (MethodWithUnresolvedGenericArgument), ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument", Tool.Trimmer | Tool.Analyzer, "")] // Local variable type + [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument", Tool.Trimmer | Tool.Analyzer, "")] // Called method declaring type + [ExpectedWarning ("IL2066", nameof (MethodWithUnresolvedGenericArgument), Tool.Trimmer | Tool.Analyzer, "")] static void UnresolvedGenericArgument () { var a = new TypeWithUnresolvedGenericArgument (); @@ -77,7 +77,7 @@ public AttributeWithRequirements ( } [Kept] - [ExpectedWarning ("IL2062", nameof (AttributeWithRequirements), ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2062", nameof (AttributeWithRequirements), Tool.Trimmer | Tool.Analyzer, "")] [KeptAttributeAttribute (typeof (AttributeWithRequirements))] [AttributeWithRequirements (typeof (Dependencies.UnresolvedType))] static void UnresolvedAttributeArgument () @@ -85,7 +85,7 @@ static void UnresolvedAttributeArgument () } [Kept] - [ExpectedWarning ("IL2062", nameof (AttributeWithRequirements.PropertyWithRequirements), ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2062", nameof (AttributeWithRequirements.PropertyWithRequirements), Tool.Trimmer | Tool.Analyzer, "")] [KeptAttributeAttribute (typeof (AttributeWithRequirements))] [AttributeWithRequirements (typeof (EmptyType), PropertyWithRequirements = typeof (Dependencies.UnresolvedType))] static void UnresolvedAttributePropertyValue () @@ -93,7 +93,7 @@ static void UnresolvedAttributePropertyValue () } [Kept] - [ExpectedWarning ("IL2064", nameof (AttributeWithRequirements.FieldWithRequirements), ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2064", nameof (AttributeWithRequirements.FieldWithRequirements), Tool.Trimmer | Tool.Analyzer, "")] [KeptAttributeAttribute (typeof (AttributeWithRequirements))] [AttributeWithRequirements (typeof (EmptyType), FieldWithRequirements = typeof (Dependencies.UnresolvedType))] static void UnresolvedAttributeFieldValue () @@ -104,14 +104,14 @@ static void UnresolvedAttributeFieldValue () static Dependencies.UnresolvedType _unresolvedField; [Kept] - [ExpectedWarning ("IL2072", nameof (Object.GetType), ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (Object.GetType), Tool.Trimmer | Tool.Analyzer, "")] static void UnresolvedObjectGetType () { RequirePublicMethods (_unresolvedField.GetType ()); } [Kept] - [ExpectedWarning ("IL2072", nameof (Object.GetType), ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2072", nameof (Object.GetType), Tool.Trimmer | Tool.Analyzer, "")] static void UnresolvedMethodParameter () { RequirePublicMethods (typeof (Dependencies.UnresolvedType)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs index 4b73a662347916..7cd16f88aaee6d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs @@ -633,24 +633,24 @@ class ImplIDamOnAllMissing : IDamOnAll // NativeAOT doesn't validate overrides when accessed through reflection because it's a direct call (non-virtual) // So it doesn't matter that the annotations are not in-sync since the access will validate // the annotations on the implementation method - it doesn't even see the base method in this case. - [ExpectedWarning ("IL2092", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2093", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] public static Type AbstractMethod (Type type) => null; // NativeAOT doesn't validate overrides when accessed through reflection because it's a direct call (non-virtual) - [ExpectedWarning ("IL2092", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2093", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] public static Type VirtualMethod (Type type) => null; } class ImplIDamOnAllMismatch : IDamOnAll { // NativeAOT doesn't validate overrides when accessed through reflection because it's a direct call (non-virtual) - [ExpectedWarning ("IL2092", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2093", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] public static Type AbstractMethod <[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] @@ -660,9 +660,9 @@ public static Type AbstractMethod { return null; } // NativeAOT doesn't validate overrides when accessed through reflection because it's a direct call (non-virtual) - [ExpectedWarning ("IL2092", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2093", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] public static Type VirtualMethod <[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] @@ -706,9 +706,9 @@ class ImplIDamOnNoneMatch : IDamOnNone class ImplIDamOnNoneMismatch : IDamOnNone { // NativeAOT doesn't validate overrides when accessed through reflection because it's a direct call (non-virtual) - [ExpectedWarning ("IL2092", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2093", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] public static Type AbstractMethod <[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] @@ -718,9 +718,9 @@ public static Type AbstractMethod { return null; } // NativeAOT doesn't validate overrides when accessed through reflection because it's a direct call (non-virtual) - [ExpectedWarning ("IL2092", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2093", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] public static Type VirtualMethod <[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] @@ -749,7 +749,7 @@ class BaseInPreservedScope class ImplIAnnotatedMethodsMismatch : Library.IAnnotatedMethods { // NativeAOT doesn't always validate static overrides when accessed through reflection because it's a direct call (non-virtual) - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] public static void GenericWithMethodsStatic () { } [ExpectedWarning ("IL2092")] @@ -771,7 +771,7 @@ public void ParamWithMethods (Type t) { } class ImplIUnannotatedMethodsMismatch : Library.IUnannotatedMethods { // NativeAOT doesn't always validate static overrides when accessed through reflection because it's a direct call (non-virtual) - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] public static void GenericStatic<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { } [ExpectedWarning ("IL2092")] @@ -947,7 +947,7 @@ interface IBaseWithDefault interface IDerivedWithDefault : IBaseWithDefault { [ExpectedWarning ("IL2092")] - [ExpectedWarning ("IL2092", ProducedBy = Tool.Analyzer)] // https://github.com/dotnet/linker/issues/3121 + [ExpectedWarning ("IL2092", Tool.Analyzer, "")] // https://github.com/dotnet/linker/issues/3121 void IBaseWithDefault.DefaultMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } } @@ -969,9 +969,9 @@ interface IGvmBase class ImplIGvmBase : IGvmBase { // NativeAOT doesn't validate overrides when it can resolve them as direct calls - [ExpectedWarning ("IL2092", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2093", ProducedBy = Tool.Trimmer | Tool.Analyzer)] - [ExpectedWarning ("IL2095", ProducedBy = Tool.Trimmer | Tool.Analyzer)] + [ExpectedWarning ("IL2092", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2093", Tool.Trimmer | Tool.Analyzer, "")] + [ExpectedWarning ("IL2095", Tool.Trimmer | Tool.Analyzer, "")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public Type UnannotatedGvm<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) => null; @@ -1045,8 +1045,8 @@ public override void MethodWithRequires ([DynamicallyAccessedMembers (Dynamicall [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithRequires))] [ExpectedWarning ("IL2026", nameof (DerivedTypeWithRequires_BaseMethodWithRequires.MethodWithRequires))] - [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires), ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires.MethodWithRequires), ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires), Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", nameof (DerivedTypeWithRequires_BaseMethodWithRequires.MethodWithRequires), Tool.NativeAot | Tool.Analyzer, "")] static void Test_DerivedTypeWithRequires_BaseMethodWithRequires () { new DerivedTypeWithRequires_BaseMethodWithRequires ().MethodWithRequires (typeof (int)); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs index e80a60f55ec2de..7c9acc549bdf53 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXml.cs @@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies // and will be found always. // For mono though, we have to specify the assembly (Mono.Linker.Tests.Cases.Expectations) because at the time of processing // that assembly is not yet loaded into the closure in ILLink, so it won't find the attribute type. -#if NETCOREAPP +#if NET [SetupLinkAttributesFile ("DynamicDependencyFromAttributeXml.netcore.Attributes.xml")] #else [SetupLinkAttributesFile ("DynamicDependencyFromAttributeXml.mono.Attributes.xml")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs index f3daf2eeaf03f7..6660e84b1ec175 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.cs @@ -12,7 +12,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies [KeptAssembly ("field_library.dll")] [KeptMemberInAssembly ("method_library.dll", "Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies.DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary_Method", "Method()")] [KeptMemberInAssembly ("field_library.dll", "Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies.DynamicDependencyFromAttributeXmlOnNonReferencedAssemblyLibrary_Field", "Method()")] -#if NETCOREAPP +#if NET [SetupLinkAttributesFile ("DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.netcore.Attributes.xml")] #else [SetupLinkAttributesFile ("DynamicDependencyFromAttributeXmlOnNonReferencedAssembly.mono.Attributes.xml")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomWarningUsage.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomWarningUsage.cs index 063038c93eadde..941f6c59e543fa 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomWarningUsage.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Extensibility/CustomWarningUsage.cs @@ -10,7 +10,7 @@ namespace Mono.Linker.Tests.Cases.Extensibility [ExpectedNoWarnings] public class CustomWarningUsage { - [ExpectedWarning ("IL2026", "--RUCMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "--RUCMethod--", Tool.Analyzer, "")] public static void Main () { new KnownTypeThatShouldWarn (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs index 9a8e4c4cb28cd8..3a7317444127b4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkerAttributeRemoval.cs @@ -17,7 +17,7 @@ namespace Mono.Linker.Tests.Cases.LinkAttributes [SetupCompileBefore ("attribute.dll", new[] { "Dependencies/LinkerAttributeRemovalAttributeToRemove.cs" })] [SetupCompileBefore ("copyattribute.dll", new[] { "Dependencies/LinkerAttributeRemovalAttributeFromCopyAssembly.cs" })] [SetupLinkerAction ("copy", "copyattribute")] -#if !NETCOREAPP +#if !NET [Reference ("System.dll")] [SetupCompileBefore ("copyassembly.dll", new[] { "Dependencies/LinkerAttributeRemovalCopyAssembly.cs" }, references: new[] { "System.dll", "attribute.dll" })] #else diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs index 074216595ed306..e9021db105d4e8 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs @@ -6,6 +6,7 @@ namespace Mono.Linker.Tests.Cases.LinkXml { [SetupLinkerDescriptorFile ("LinkXmlErrorCases.xml")] [SetupLinkerArgument ("--skip-unresolved", "true")] + [SetupLinkerArgument ("--verbose")] [ExpectedWarning ("IL2001", "TypeWithNoFields", FileName = "LinkXmlErrorCases.xml", SourceLine = 3, SourceColumn = 6)] [ExpectedWarning ("IL2002", "TypeWithNoMethods", FileName = "LinkXmlErrorCases.xml", SourceLine = 4, SourceColumn = 6)] @@ -17,13 +18,18 @@ namespace Mono.Linker.Tests.Cases.LinkXml [ExpectedWarning ("IL2017", "NonExistentProperty", "TypeWithNoProperties", FileName = "LinkXmlErrorCases.xml", SourceLine = 21, SourceColumn = 8)] [ExpectedWarning ("IL2018", "SetOnlyProperty", "TypeWithProperties", FileName = "LinkXmlErrorCases.xml", SourceLine = 25, SourceColumn = 8)] [ExpectedWarning ("IL2019", "GetOnlyProperty", "TypeWithProperties", FileName = "LinkXmlErrorCases.xml", SourceLine = 26, SourceColumn = 8)] - [ExpectedWarning ("IL2025", "Method", FileName = "LinkXmlErrorCases.xml", SourceLine = 39, SourceColumn = 8, ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2025", "Event", FileName = "LinkXmlErrorCases.xml", SourceLine = 40, SourceColumn = 8, ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2025", "Field", FileName = "LinkXmlErrorCases.xml", SourceLine = 41, SourceColumn = 8, ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2025", "Property", FileName = "LinkXmlErrorCases.xml", SourceLine = 42, SourceColumn = 8, ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'System.Int32 Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases/TypeWithEverything::Field'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases.TypeWithEverything.TypeWithEverything()'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases.TypeWithEverything.Method()'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'System.EventHandler Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases/TypeWithEverything::Event'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases.TypeWithEverything.Event.add'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases.TypeWithEverything.Event.remove'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'System.Int32 Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases/TypeWithEverything::Property()'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases.TypeWithEverything.Property.get'", ProducedBy = Tool.Trimmer)] + [LogContains ("Duplicate preserve of 'Mono.Linker.Tests.Cases.LinkXml.LinkXmlErrorCases.TypeWithEverything.Property.set'", ProducedBy = Tool.Trimmer)] // NativeAOT doesn't support wildcard * and will skip usages of it, including if they would warn // https://github.com/dotnet/runtime/issues/80466 - [ExpectedWarning ("IL2100", FileName = "LinkXmlErrorCases.xml", SourceLine = 50, SourceColumn = 4, ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2100", Tool.Trimmer, "", FileName = "LinkXmlErrorCases.xml", SourceLine = 50, SourceColumn = 4)] class LinkXmlErrorCases { public static void Main () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs index 4da189cced1f87..e6f445dfaca24b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs @@ -31,16 +31,16 @@ static Type GetUnknownType () // Analyzer test infrastructure doesn't support ExpectedWarning at the top-level. // This is OK because the test is meant to validate that the ILLink infrastructure produces the right line numbers, // and we have separate tests to check the line number of analyzer warnings. - [ExpectedWarning ("IL2074", nameof (SourceLines) + "." + nameof (type), nameof (SourceLines) + "." + nameof (GetUnknownType) + "()", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2074", nameof (SourceLines) + "." + nameof (type), nameof (SourceLines) + "." + nameof (GetUnknownType) + "()", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2074", nameof (SourceLines) + "." + nameof (type), nameof (SourceLines) + "." + nameof (GetUnknownType) + "()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2074", nameof (SourceLines) + "." + nameof (type), nameof (SourceLines) + "." + nameof (GetUnknownType) + "()", Tool.Analyzer, "")] static void UnrecognizedReflectionPattern () { type = GetUnknownType (); // IL2074 type = GetUnknownType (); // IL2074 } - [ExpectedWarning ("IL2091", "LocalFunction()", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL2089", nameof (SourceLines) + "." + nameof (type), "TOuterMethod", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2091", "LocalFunction()", Tool.Analyzer, "")] + [ExpectedWarning ("IL2089", nameof (SourceLines) + "." + nameof (type), "TOuterMethod", Tool.Analyzer, "")] static IEnumerable GenericMethodIteratorWithRequirement<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TOuterMethod> () { LocalFunction (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs index a14030d90ad164..4aca2d51861850 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs @@ -171,8 +171,8 @@ public FromParameterOnStaticMethodTypeB (int arg) { } } // Small formatting difference - [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, Object[])", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, params Object[])", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, Object[])", Tool.Trimmer, "")] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, params Object[])", Tool.Analyzer, "")] [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance), nameof (CultureInfo))] [Kept] private void FromParameterOnInstanceMethod ( @@ -197,8 +197,8 @@ public FromParameterOnInstanceMethodType (int arg, int arg2) { } [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type)")] // Small formatting difference - [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, Object[])", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, params Object[])", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, Object[])", Tool.Trimmer, "")] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, params Object[])", Tool.Analyzer, "")] [Kept] private static void FromParameterWithNonPublicConstructors ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] @@ -375,7 +375,7 @@ private static void WithAssemblyAndNoValueTypeName () [Kept] // Analyzer doesn't handle assembly resolution - [ExpectedWarning ("IL2061", nameof (Activator) + "." + nameof (Activator.CreateInstance), "NonExistingAssembly", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2061", nameof (Activator) + "." + nameof (Activator.CreateInstance), "NonExistingAssembly", Tool.Trimmer, "")] private static void WithNonExistingAssemblyName () { Activator.CreateInstance ("NonExistingAssembly", "Mono.Linker.Tests.Cases.Reflection.ActivatorCreateInstance+WithAssemblyNameParameterless1"); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs index 7ca59831a01a47..dae1731331bb13 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs @@ -16,7 +16,7 @@ public static void Main () GetConstructor_BindingAttr_Binder_Types_Modifiers.TestWithBindingFlags (); GetConstructor_BindingAttr_Binder_Types_Modifiers.TestWithUnknownBindingFlags (BindingFlags.Public); GetConstructor_BindingAttr_Binder_CallConvention_Types_Modifiers.TestWithCallingConvention (); -#if NETCOREAPP +#if NET GetConstructor_BindingAttr_Types.Test (); #endif TestNullType (); @@ -217,7 +217,7 @@ public static void TestWithCallingConvention () } } -#if NETCOREAPP +#if NET [Kept] class GetConstructor_BindingAttr_Types { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs index 5fa8b48caddcbe..fadd361a58cef2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs @@ -84,11 +84,11 @@ public int InstancePropertyViaReflection { [Kept] // https://github.com/dotnet/linker/issues/2669 - [ExpectedWarning ("IL2026", nameof (StaticPropertyExpressionAccess), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", nameof (StaticPropertyExpressionAccess), Tool.Trimmer, "")] [ExpectedWarning ("IL2026", nameof (StaticPropertyViaReflection))] [ExpectedWarning ("IL2026", nameof (StaticPropertyViaRuntimeMethod))] // https://github.com/dotnet/linker/issues/2669 - [ExpectedWarning ("IL2026", nameof (InstancePropertyExpressionAccess), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", nameof (InstancePropertyExpressionAccess), Tool.Trimmer, "")] [ExpectedWarning ("IL2026", nameof (InstancePropertyViaReflection))] public static void Test () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs index baf8860765d2dd..55e6c440fbc159 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs @@ -26,7 +26,7 @@ public static void Main () GetMethod_Name_BindingAttr.TestUnknownNameAndWrongBindingFlags ("Unknown"); GetMethod_Name_BindingAttr_Binder_Types_Modifiers.TestNameBindingFlagsAndParameterModifier (); GetMethod_Name_BindingAttr_Binder_CallConvention_Types_Modifiers.TestNameBindingFlagsCallingConventionParameterModifier (); -#if NETCOREAPP +#if NET GetMethod_Name_BindingAttr_Types.TestNameBindingFlagsAndTypes (); GetMethod_Name_GenericParameterCount_Types.TestNameWithIntAndType (); GetMethod_Name_GenericParameterCount_Types_Modifiers.TestNameWithIntAndTypeAndModifiers (); @@ -391,7 +391,7 @@ public static void TestNameBindingFlagsCallingConventionParameterModifier () } } -#if NETCOREAPP +#if NET // GetMethod(string name, BindingFlags bindingAttr, Type[] types) [Kept] class GetMethod_Name_BindingAttr_Types diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs index c91fb020f7feae..01717db24f5662 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs @@ -338,7 +338,7 @@ private void PrivateMethodWithRUC () { } [Kept] // https://github.com/dotnet/linker/issues/2638 - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", Tool.Trimmer, "")] public static void Test () { BindingFlags left = BindingFlags.Instance | BindingFlags.Static; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs index 9ec76e4de21ecb..af03ac42590ff7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/ObjectGetType.cs @@ -297,7 +297,7 @@ public void UnusedMethod () { } [Kept] // https://github.com/dotnet/runtime/issues/93718 // This should not warn - [ExpectedWarning ("IL2075", "GetMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2075", "GetMethod", Tool.Trimmer | Tool.NativeAot, "")] static void TestStruct (BasicAnnotatedStruct instance) { instance.GetType ().GetMethod ("UsedMethod"); @@ -682,8 +682,7 @@ public void Method () { } } [Kept] - // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2075", "GetMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2075", "GetMethod")] public static void Test () { new Derived ().GetType ().GetMethod ("Method"); @@ -1410,7 +1409,7 @@ public void Method () { } [Kept] // https://github.com/dotnet/runtime/issues/93719 - [ExpectedWarning ("IL2075", nameof (Type.GetType), ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2075", nameof (Type.GetType), Tool.Trimmer | Tool.NativeAot, "")] public static void Test () { foreach (var instance in GetInstances ()) { @@ -1586,8 +1585,7 @@ class Target [Kept] // https://github.com/dotnet/runtime/issues/93720 - // https://github.com/dotnet/linker/issues/2755 - [ExpectedWarning ("IL2072", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2072")] static void TestIsInstOf (object o) { if (o is Target t) { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs index 13ecc2ec29068c..c1f0b37ebaab54 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeHierarchyReflectionWarnings.cs @@ -250,7 +250,7 @@ public event MyEventHandler RUCEvent { [Kept] [ExpectedWarning ("IL2112", nameof (AnnotatedPublicEvents), "--RUC on add_RUCEvent--")] // https://github.com/dotnet/runtime/issues/100499 - [ExpectedWarning ("IL2112", nameof (AnnotatedPublicEvents), "--RUC on add_RUCEvent--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2112", [nameof (AnnotatedPublicEvents), "--RUC on add_RUCEvent--"], Tool.Trimmer, "")] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--RUC on add_RUCEvent--")] add { } @@ -313,7 +313,7 @@ class DerivedFromAnnotatedPublicParameterlessConstructor : AnnotatedPublicParame [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--")] - [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--", Tool.Trimmer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("--RUC on DerivedFromAnnotatedPublicParameterlessConstructor()--")] public DerivedFromAnnotatedPublicParameterlessConstructor () { } @@ -704,7 +704,7 @@ public class Base // https://github.com/dotnet/runtime/issues/86580 // Compare to the case above - the only difference is the type of the field // and it causes different warnings to be produced. - // [ExpectedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--")] + // [ExpectedSharedWarning ("IL2112", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--")] public virtual void RUCVirtualMethod () { } } @@ -712,7 +712,7 @@ public virtual void RUCVirtualMethod () { } [KeptMember (".ctor()")] [KeptBaseType (typeof (Base))] // https://github.com/dotnet/runtime/issues/86580 - [ExpectedWarning ("IL2113", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2113", "--RUCOnVirtualMethodDerivedAnnotated.Base.RUCVirtualMethod--", Tool.Trimmer, "")] public class Derived : Base { [Kept] @@ -756,7 +756,7 @@ public virtual void VirtualMethodWithRequires () { } [KeptBaseType (typeof (AnnotatedBase))] [KeptMember (".ctor()")] // https://github.com/dotnet/runtime/issues/86580 - [ExpectedWarning ("IL2113", "--AnnotatedBase.VirtualMethodWithRequires--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2113", "--AnnotatedBase.VirtualMethodWithRequires--", Tool.Trimmer, "")] class Derived : AnnotatedBase { [Kept] @@ -956,7 +956,7 @@ static void LocalFunctionWithDAMInner ([DynamicallyAccessedMembers(DynamicallyAc [Kept] [KeptAttributeAttribute (typeof (IteratorStateMachineAttribute))] - [ExpectedWarning ("IL2119", nameof (IteratorWithGenericDAM), CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", nameof (IteratorWithGenericDAM), Tool.Trimmer, "", CompilerGeneratedCode = true)] static IEnumerable IteratorWithGenericDAM< [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T> () @@ -968,7 +968,7 @@ static IEnumerable IteratorWithGenericDAM< [Kept] [KeptAttributeAttribute (typeof (AsyncStateMachineAttribute))] [KeptAttributeAttribute (typeof (DebuggerStepThroughAttribute))] - [ExpectedWarning ("IL2119", nameof (AsyncWithGenericDAM), CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2119", nameof (AsyncWithGenericDAM), Tool.Trimmer, "", CompilerGeneratedCode = true)] static async Task AsyncWithGenericDAM< [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() @@ -979,7 +979,7 @@ static async Task AsyncWithGenericDAM< [Kept] [KeptAttributeAttribute (typeof (AsyncIteratorStateMachineAttribute))] - [ExpectedWarning("IL2119", nameof(AsyncIteratorWithGenericDAM), CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] + [ExpectedWarning("IL2119", nameof(AsyncIteratorWithGenericDAM), Tool.Trimmer, "", CompilerGeneratedCode = true)] static async IAsyncEnumerable AsyncIteratorWithGenericDAM< [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs index 352be76d77910b..981ad6227ceb8d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs @@ -331,9 +331,9 @@ public class OverloadWith5ParametersWithIgnoreCase { } [Kept] // Small difference in formatting between analyzer/NativeAOT/linker - [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func`2,Func`4,Boolean,Boolean)'", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", Tool.Trimmer, "")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func`2,Func`4,Boolean,Boolean)'", Tool.NativeAot, "")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", Tool.Analyzer, "")] static void TestTypeOverloadWith5ParametersWithIgnoreCase () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith5ParametersWithIgnoreCase"; @@ -384,9 +384,9 @@ static void TestUnknownIgnoreCase3Params (int num) [Kept] // Small difference in formatting between analyzer/NativeAOT/linker - [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func`2,Func`4,Boolean,Boolean)'", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", Tool.Trimmer, "")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func`2,Func`4,Boolean,Boolean)'", Tool.NativeAot, "")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func, Func, Boolean, Boolean)'", Tool.Analyzer, "")] static void TestUnknownIgnoreCase5Params (int num) { const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs index d9536b9358109a..453f5661502ff2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs @@ -28,8 +28,8 @@ public static void Main () } [ExpectedWarning ("IL2026", "Message for --RequiresWithMessageOnly--.")] - [ExpectedWarning ("IL3002", "Message for --RequiresWithMessageOnly--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message for --RequiresWithMessageOnly--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message for --RequiresWithMessageOnly--.", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Message for --RequiresWithMessageOnly--.", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresWithMessageOnlyOnMethod () { RequiresWithMessageOnly (); @@ -43,8 +43,8 @@ static void RequiresWithMessageOnly () } [ExpectedWarning ("IL2026", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl")] - [ExpectedWarning ("IL3002", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresWithMessageAndUrlOnMethod () { RequiresWithMessageAndUrl (); @@ -58,8 +58,8 @@ static void RequiresWithMessageAndUrl () } [ExpectedWarning ("IL2026", "Message for --ConstructorRequires--.")] - [ExpectedWarning ("IL3002", "Message for --ConstructorRequires--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message for --ConstructorRequires--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message for --ConstructorRequires--.", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Message for --ConstructorRequires--.", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresOnConstructor () { new ConstructorRequires (); @@ -77,10 +77,10 @@ public ConstructorRequires () [ExpectedWarning ("IL2026", "Message for --getter PropertyRequires--.")] [ExpectedWarning ("IL2026", "Message for --setter PropertyRequires--.")] - [ExpectedWarning ("IL3002", "Message for --getter PropertyRequires--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "Message for --setter PropertyRequires--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message for --getter PropertyRequires--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message for --setter PropertyRequires--.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message for --getter PropertyRequires--.", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "Message for --setter PropertyRequires--.", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Message for --getter PropertyRequires--.", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Message for --setter PropertyRequires--.", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresOnPropertyGetterAndSetter () { _ = PropertyRequires; @@ -107,8 +107,8 @@ static void WarningMessageWithoutEndingPeriod () } [ExpectedWarning ("IL2026", "Adds a trailing period to this message.")] - [ExpectedWarning ("IL3002", "Adds a trailing period to this message.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Adds a trailing period to this message.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Adds a trailing period to this message.", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Adds a trailing period to this message.", Tool.Analyzer | Tool.NativeAot, "")] static void TestThatTrailingPeriodIsAddedToMessage () { WarningMessageWithoutEndingPeriod (); @@ -123,8 +123,8 @@ static void WarningMessageEndsWithPeriod () [LogDoesNotContain ("Does not add a period to this message..")] [ExpectedWarning ("IL2026", "Does not add a period to this message.")] - [ExpectedWarning ("IL3002", "Does not add a period to this message.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Does not add a period to this message.", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Does not add a period to this message.", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Does not add a period to this message.", Tool.Analyzer | Tool.NativeAot, "")] static void TestThatTrailingPeriodIsNotDuplicatedInWarningMessage () { WarningMessageEndsWithPeriod (); @@ -157,11 +157,11 @@ static event EventHandler EventToTestAdd { static event EventHandler AnnotatedEvent; [ExpectedWarning ("IL2026", "--EventToTestRemove.remove--")] - [ExpectedWarning ("IL3002", "--EventToTestRemove.remove--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--EventToTestRemove.remove--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--EventToTestRemove.remove--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--EventToTestRemove.remove--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--EventToTestAdd.add--")] - [ExpectedWarning ("IL3002", "--EventToTestAdd.add--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--EventToTestAdd.add--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--EventToTestAdd.add--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--EventToTestAdd.add--", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { EventToTestRemove -= (sender, e) => { }; @@ -181,8 +181,8 @@ public static void GenericTypeWithStaticMethodWhichRequires () { } } [ExpectedWarning ("IL2026", "--GenericTypeWithStaticMethodWhichRequires--")] - [ExpectedWarning ("IL3002", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--GenericTypeWithStaticMethodWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--GenericTypeWithStaticMethodWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] public static void GenericTypeWithStaticMethodViaLdftn () { var _ = new Action (GenericWithStaticMethod.GenericTypeWithStaticMethodWhichRequires); @@ -208,8 +208,8 @@ static void Requires () { } [RequiresAssemblyFiles ("--PropertyRequires--")] static int PropertyRequires { get; set; } - [ExpectedWarning ("IL3002", "--PropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--PropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--PropertyRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--PropertyRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestProperty () { var a = PropertyRequires; @@ -219,11 +219,11 @@ static void TestProperty () [RequiresAssemblyFiles ("--EventRequires--")] static event EventHandler EventRequires; - [ExpectedWarning ("IL3002", "--EventRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--EventRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--EventRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--EventRequires--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--RequiresOnEventLambda--")] - [ExpectedWarning ("IL3002", "--RequiresOnEventLambda--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--RequiresOnEventLambda--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--RequiresOnEventLambda--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--RequiresOnEventLambda--", Tool.Analyzer | Tool.NativeAot, "")] static void TestEvent () { EventRequires += (object sender, EventArgs e) => throw new NotImplementedException (); @@ -237,7 +237,7 @@ static void TestEvent () EventRequires (null, null); // no warning on invocation } - [ExpectedWarning("IL3002", "--Requires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning("IL3002", "--Requires--", Tool.Analyzer | Tool.NativeAot, "")] public static void Test() { Requires (); @@ -251,7 +251,7 @@ class DynamicCodeOnly [RequiresDynamicCode ("--Requires--")] static void Requires () { } - [ExpectedWarning ("IL3050", "--Requires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--Requires--", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { Requires (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs index 2b2c0438c1d01d..71af8ce1374138 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs @@ -24,10 +24,9 @@ public static void Main () class ReflectionAccessFromStateMachine { [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", Tool.Trimmer, "", CompilerGeneratedCode = true)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true)] static IEnumerable TestIterator () { @@ -45,10 +44,9 @@ static IEnumerable TestIteratorWithRUC () } [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", Tool.Trimmer, "", CompilerGeneratedCode = true)] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true)] static async void TestAsync () { @@ -66,11 +64,11 @@ static async void TestAsyncWithRUC () } [ExpectedWarning ("IL2026", "--TestIteratorWithRUC--")] - [ExpectedWarning ("IL3002", "--TestIteratorWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--TestIteratorWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--TestIteratorWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--TestIteratorWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] [ExpectedWarning ("IL2026", "--TestAsyncWithRUC--")] - [ExpectedWarning ("IL3002", "--TestAsyncWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--TestAsyncWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--TestAsyncWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--TestAsyncWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] public static void Test () { TestIterator ().GetEnumerator ().MoveNext (); // Must actually use the enumerator, otherwise NativeAOT will trim the implementation @@ -85,10 +83,9 @@ class ReflectionAccessFromLocalFunction static void TestLocalFunction () { [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", Tool.Trimmer, "")] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations))] void LocalFunction () { @@ -98,8 +95,8 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "--LocalFunction--")] - [ExpectedWarning ("IL3002", "--LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--LocalFunction--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--LocalFunction--", Tool.NativeAot | Tool.Analyzer, "")] static void TestLocalFunctionWithRUC () { [RequiresUnreferencedCode ("--LocalFunction--")] @@ -125,8 +122,8 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRUC--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] public static void Test () { TestLocalFunction (); @@ -141,10 +138,9 @@ static void TestLambda () { var lambda = [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", Tool.Trimmer, "")] [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations))] () => { typeof (TypeWithMethodWithRequires).RequiresAll (); @@ -153,8 +149,8 @@ static void TestLambda () } [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] - [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] static void TestLambdaWithRUC () { var lambda = @@ -168,8 +164,8 @@ static void TestLambdaWithRUC () } [ExpectedWarning ("IL2026", "--TestLambdaWithRUCLdftn--")] - [ExpectedWarning ("IL3002", "--TestLambdaWithRUCLdftn--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--TestLambdaWithRUCLdftn--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--TestLambdaWithRUCLdftn--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--TestLambdaWithRUCLdftn--", Tool.NativeAot | Tool.Analyzer, "")] static void TestLambdaWithRUCLdftn () { var lambda = @@ -196,8 +192,8 @@ static void TestLambdaInMethodWithRUC () } [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] - [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] public static void Test () { TestLambda (); @@ -224,8 +220,8 @@ public static void MethodWithRequires () public static void MethodWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) { } [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--")] - [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--MethodWithLocalFunctionWithRUC.LocalFunction--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithLocalFunctionWithRUC.LocalFunction--", Tool.NativeAot | Tool.Analyzer, "")] public static void MethodWithLocalFunctionWithRUC () { [RequiresUnreferencedCode ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] @@ -239,8 +235,8 @@ void LocalFunction () public static void MethodWithLocalFunctionCallsRUC () { [ExpectedWarning ("IL2026", "--MethodWithRUC--")] - [ExpectedWarning ("IL3002", "--MethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithRUC--", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3002", "--MethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithRUC--", Tool.NativeAot | Tool.Analyzer, "")] void LocalFunction () => MethodWithRUC (); LocalFunction (); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAccessedThrough.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAccessedThrough.cs index 727463e800801e..8a43183e35ec68 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAccessedThrough.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAccessedThrough.cs @@ -43,8 +43,8 @@ static void RequiresOnlyThroughReflection () // https://github.com/dotnet/linker/issues/2739 - the discussion there explains why (at least for now) we don't produce // RAF and RDC warnings from the analyzer in these cases. [ExpectedWarning ("IL2026", "--RequiresOnlyThroughReflection--")] - [ExpectedWarning ("IL3002", "--RequiresOnlyThroughReflection--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--RequiresOnlyThroughReflection--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--RequiresOnlyThroughReflection--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--RequiresOnlyThroughReflection--", Tool.NativeAot, "")] static void TestRequiresOnlyThroughReflection () { typeof (RequiresAccessedThrough) @@ -62,8 +62,8 @@ public static void RequiresOnlyThroughReflection () } [ExpectedWarning ("IL2026", "--GenericType.RequiresOnlyThroughReflection--")] - [ExpectedWarning ("IL3002", "--GenericType.RequiresOnlyThroughReflection--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--GenericType.RequiresOnlyThroughReflection--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--GenericType.RequiresOnlyThroughReflection--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--GenericType.RequiresOnlyThroughReflection--", Tool.NativeAot, "")] public static void Test () { typeof (AccessedThroughReflectionOnGenericType) @@ -75,7 +75,7 @@ public static void Test () class AccessThroughSpecialAttribute { // https://github.com/dotnet/linker/issues/1873 - // [ExpectedWarning ("IL2026", "--DebuggerProxyType.Method--")] + // [ExpectedSharedWarning ("IL2026", "--DebuggerProxyType.Method--")] [DebuggerDisplay ("Some{*}value")] class TypeWithDebuggerDisplay { @@ -104,12 +104,12 @@ public PInvokeReturnType () { } } // https://github.com/mono/linker/issues/2116 - [ExpectedWarning ("IL2026", "--PInvokeReturnType.ctor--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", "--PInvokeReturnType.ctor--", Tool.Trimmer, "")] [DllImport ("nonexistent")] static extern PInvokeReturnType PInvokeReturnsType (); // Analyzer doesn't support IL2050 yet - [ExpectedWarning ("IL2050", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2050", Tool.Trimmer | Tool.NativeAot, "")] public static void Test () { PInvokeReturnsType (); @@ -136,8 +136,8 @@ class NewConstraintTestAnnotatedType [ExpectedWarning ("IL2026", "--NewConstraintTestType.ctor--")] [ExpectedWarning ("IL2026", "--NewConstraintTestAnnotatedType--")] - [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () where T : new() { GenericMethod (); @@ -156,8 +156,8 @@ public static void DoNothing () { } [ExpectedWarning ("IL2026", "--NewConstraintTestType.ctor--")] [ExpectedWarning ("IL2026", "--NewConstraintTestAnnotatedType--")] - [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] public static void TestNewConstraintOnTypeParameter () where T : new() { _ = new NewConstraintOnTypeParameter (); @@ -166,8 +166,8 @@ public static void DoNothing () { } } [ExpectedWarning ("IL2026", "--AnnotatedMethod--")] - [ExpectedWarning ("IL3002", "--AnnotatedMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AnnotatedMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AnnotatedMethod--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AnnotatedMethod--", Tool.Analyzer | Tool.NativeAot, "")] public static void TestNewConstraintOnTypeParameterInAnnotatedMethod () { AnnotatedMethod (); @@ -191,8 +191,8 @@ public static void TestNewConstraintOnTypeParameterInAnnotatedType () [RequiresUnreferencedCode ("--AnnotatedType--")] class AnnotatedType { - [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] public static void Method () { _ = new NewConstraintOnTypeParameter (); @@ -202,8 +202,8 @@ public static void Method () [ExpectedWarning ("IL2026", "--NewConstraintTestType.ctor--")] [ExpectedWarning ("IL2026", "--NewConstraintTestAnnotatedType--")] - [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--NewConstraintTestType.ctor--", Tool.Analyzer | Tool.NativeAot, "")] public static void TestNewConstraintOnTypeParameterOfStaticType () where T : new() { NewConstraintOnTypeParameterOfStaticType.DoNothing (); @@ -224,11 +224,11 @@ static bool PropertyWithLdToken { } [ExpectedWarning ("IL2026", "--PropertyWithLdToken.get--")] - [ExpectedWarning ("IL2026", "--PropertyWithLdToken.get--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--PropertyWithLdToken.get--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--PropertyWithLdToken.get--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--PropertyWithLdToken.get--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--PropertyWithLdToken.get--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--PropertyWithLdToken.get--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--PropertyWithLdToken.get--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--PropertyWithLdToken.get--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--PropertyWithLdToken.get--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--PropertyWithLdToken.get--", Tool.NativeAot, "")] static void TestPropertyLdToken () { Expression> getter = () => PropertyWithLdToken; @@ -242,8 +242,8 @@ static void MethodWithLdToken () } [ExpectedWarning ("IL2026", "--MethodWithLdToken--")] - [ExpectedWarning ("IL3002", "--MethodWithLdToken--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithLdToken--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithLdToken--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithLdToken--", Tool.Analyzer | Tool.NativeAot, "")] static void TestMethodLdToken () { Expression e = () => MethodWithLdToken (); @@ -257,7 +257,7 @@ class FieldWithLdTokenType } [ExpectedWarning ("IL2026", "--FieldWithLdToken--")] - [ExpectedWarning ("IL3050", "--FieldWithLdToken--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--FieldWithLdToken--", Tool.Analyzer | Tool.NativeAot, "")] static void TestFieldLdToken () { Expression> f = () => FieldWithLdTokenType.Field; @@ -281,16 +281,16 @@ static void MethodWithDelegate () } [ExpectedWarning ("IL2026", "--MethodWithDelegate--")] - [ExpectedWarning ("IL3002", "--MethodWithDelegate--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithDelegate--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithDelegate--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithDelegate--", Tool.Analyzer | Tool.NativeAot, "")] static void TestMethodWithDelegate () { Action a = MethodWithDelegate; } [ExpectedWarning ("IL2026", "--LambdaThroughDelegate--")] - [ExpectedWarning ("IL3002", "--LambdaThroughDelegate--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--LambdaThroughDelegate--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--LambdaThroughDelegate--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--LambdaThroughDelegate--", Tool.Analyzer | Tool.NativeAot, "")] static void LambdaThroughDelegate () { Action a = @@ -303,8 +303,8 @@ static void LambdaThroughDelegate () } [ExpectedWarning ("IL2026", "--LocalFunctionThroughDelegate--")] - [ExpectedWarning ("IL3002", "--LocalFunctionThroughDelegate--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--LocalFunctionThroughDelegate--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--LocalFunctionThroughDelegate--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--LocalFunctionThroughDelegate--", Tool.Analyzer | Tool.NativeAot, "")] static void LocalFunctionThroughDelegate () { Action a = Local; @@ -341,15 +341,15 @@ private Target (int i) { } private static void MethodRequires () { } } - [ExpectedWarning ("IL2026", "--Target.MethodRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--Target.MethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--Target.MethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--Target.MethodRequires--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--Target.MethodRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--Target.MethodRequires--", Tool.NativeAot, "")] [UnsafeAccessor (UnsafeAccessorKind.StaticMethod)] extern static void MethodRequires (Target target); - [ExpectedWarning ("IL2026", "--Target..ctor--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--Target..ctor--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--Target..ctor--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--Target..ctor--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--Target..ctor--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--Target..ctor--", Tool.NativeAot, "")] [UnsafeAccessor (UnsafeAccessorKind.Constructor)] extern static Target Constructor (int i); @@ -367,22 +367,22 @@ private void InstanceMethod () { } private int InstanceField; } - [ExpectedWarning ("IL2026", "--TargetWitRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--TargetWitRequires--", Tool.Trimmer | Tool.NativeAot, "")] [UnsafeAccessor (UnsafeAccessorKind.Constructor)] extern static TargetWithRequires TargetRequiresConstructor (); - [ExpectedWarning ("IL2026", "--TargetWitRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--TargetWitRequires--", Tool.Trimmer | Tool.NativeAot, "")] [UnsafeAccessor (UnsafeAccessorKind.StaticMethod, Name = "StaticMethod")] extern static void TargetRequiresStaticMethod (TargetWithRequires target); // For trimmer this is a reflection access to an instance method - and as such it must warn (since it's in theory possible // to invoke the method via reflection on a null instance) // For NativeAOT this is a direct call to an instance method (there's no reflection involved) and as such it doesn't need to warn - [ExpectedWarning ("IL2026", "--TargetWitRequires--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", "--TargetWitRequires--", Tool.Trimmer, "")] [UnsafeAccessor (UnsafeAccessorKind.Method, Name = "InstanceMethod")] extern static void TargetRequiresInstanceMethod (TargetWithRequires target); - [ExpectedWarning ("IL2026", "--TargetWitRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--TargetWitRequires--", Tool.Trimmer | Tool.NativeAot, "")] [UnsafeAccessor (UnsafeAccessorKind.StaticField, Name = "StaticField")] extern static ref int TargetRequiresStaticField (TargetWithRequires target); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs index 4653f445cabb39..94249d6af5b6f0 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs @@ -26,87 +26,87 @@ class RequiresAttributeMismatch // The analyzer matches this behavior, treating the get/set methods as annotated if the property is annotated, // and warning only on the get/set methods. [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set")] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get")] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set")] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set")] - [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "BaseClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualMethod()")] - [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "DerivedClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "DerivedClassWithRequires.VirtualMethod()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "IBaseWithRequires.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "IBaseWithRequires.PropertyAnnotationInAccesor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set")] - [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "IBaseWithRequires.PropertyAnnotationInProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "IBaseWithRequires.Method()")] - [ExpectedWarning ("IL3002", "IBaseWithRequires.Method()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "IBaseWithRequires.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "IBaseWithRequires.Method()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "IBaseWithRequires.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationClassWithRequires.Method()")] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.Method()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "ImplementationClassWithRequires.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.Method()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "ImplementationClassWithRequires.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequires.PropertyAnnotationInProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3002", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationClassWithRequiresInSource.Method()")] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.Method()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "ImplementationClassWithRequiresInSource.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.Method()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "ImplementationClassWithRequiresInSource.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty.set", Tool.NativeAot, "")] public static void Main () { @@ -174,8 +174,8 @@ class DerivedClassWithRequires : BaseClassWithoutRequires [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] [ExpectedWarning ("IL2046", "DerivedClassWithRequires.VirtualMethod()", "BaseClassWithoutRequires.VirtualMethod()")] - [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualMethod()", "BaseClassWithoutRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "DerivedClassWithRequires.VirtualMethod()", "BaseClassWithoutRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualMethod()", "BaseClassWithoutRequires.VirtualMethod()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "DerivedClassWithRequires.VirtualMethod()", "BaseClassWithoutRequires.VirtualMethod()", Tool.Analyzer | Tool.NativeAot, "")] public override void VirtualMethod () { } @@ -183,8 +183,8 @@ public override void VirtualMethod () private string name; public override string VirtualPropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message")] [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] @@ -194,9 +194,9 @@ public override string VirtualPropertyAnnotationInAccesor { [RequiresAssemblyFiles ("Message")] public override string VirtualPropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithoutRequires.VirtualPropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithoutRequires.VirtualPropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithoutRequires.VirtualPropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithoutRequires.VirtualPropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -237,8 +237,8 @@ public static void Test() class DerivedClassWithoutRequires : BaseClassWithRequires { [ExpectedWarning ("IL2046", "DerivedClassWithoutRequires.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()")] - [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "DerivedClassWithoutRequires.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "DerivedClassWithoutRequires.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", Tool.Analyzer | Tool.NativeAot, "")] public override void VirtualMethod () { } @@ -246,24 +246,24 @@ public override void VirtualMethod () private string name; public override string VirtualPropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] get { return name; } set { name = value; } } public override string VirtualPropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInProperty", "BaseClassWithRequires.VirtualPropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] set; } public override string VirtualPropertyAnnotationInPropertyAndAccessor { [ExpectedWarning ("IL2046", "VirtualPropertyAnnotationInPropertyAndAccessor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInPropertyAndAccessor", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithoutRequires.VirtualPropertyAnnotationInPropertyAndAccessor", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -271,8 +271,8 @@ public override string VirtualPropertyAnnotationInPropertyAndAccessor { class DerivedClassWithAllWarnings : BaseClassWithRequires { [ExpectedWarning ("IL2046", "DerivedClassWithAllWarnings.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()")] - [ExpectedWarning ("IL3003", "DerivedClassWithAllWarnings.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "DerivedClassWithAllWarnings.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithAllWarnings.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "DerivedClassWithAllWarnings.VirtualMethod()", "BaseClassWithRequires.VirtualMethod()", Tool.Analyzer | Tool.NativeAot, "")] public override void VirtualMethod () { } @@ -282,12 +282,12 @@ public override void VirtualMethod () [RequiresAssemblyFiles ("Message")] public override string VirtualPropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3051", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3051", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] get { return name; } [RequiresAssemblyFiles ("Message")] [RequiresUnreferencedCode ("Message")] [ExpectedWarning ("IL2046", "VirtualPropertyAnnotationInAccesor.set", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.set")] - [ExpectedWarning ("IL3003", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.set", Tool.Analyzer | Tool.NativeAot, "")] set { name = value; } } @@ -304,7 +304,7 @@ public override string VirtualPropertyAnnotationInProperty { public override string VirtualPropertyAnnotationInPropertyAndAccessor { [ExpectedWarning ("IL2046", "VirtualPropertyAnnotationInPropertyAndAccessor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3003", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInPropertyAndAccessor.get", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get", Tool.Analyzer | Tool.NativeAot, "")] get; [RequiresAssemblyFiles ("Message")] [RequiresUnreferencedCode ("Message")] @@ -357,8 +357,8 @@ class ImplementationClassWithRequires : IBaseWithoutRequires [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] [ExpectedWarning ("IL2046", "ImplementationClassWithRequires.Method()", "IBaseWithoutRequires.Method()")] - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.Method()", "IBaseWithoutRequires.Method()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithRequires.Method()", "IBaseWithoutRequires.Method()", Tool.Analyzer | Tool.NativeAot, "")] public void Method () { } @@ -366,8 +366,8 @@ public void Method () private string name; public string PropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message")] [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] @@ -376,23 +376,23 @@ public string PropertyAnnotationInAccesor { } [RequiresAssemblyFiles ("Message")] - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", Tool.Analyzer, "")] public string PropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", Tool.NativeAot | Tool.Analyzer, "")] get; - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", ProducedBy = Tool.NativeAot | Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", Tool.NativeAot | Tool.Analyzer, "")] set; } [RequiresAssemblyFiles ("Message")] - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", Tool.Analyzer, "")] public string PropertyAnnotationInPropertyAndAccessor { [RequiresAssemblyFiles ("Message")] [RequiresUnreferencedCode ("Message")] [ExpectedWarning ("IL2046", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.get", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.get", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.get", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -403,12 +403,12 @@ class ExplicitImplementationClassWithRequires : IBaseWithoutRequires [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] // ILLink member string format includes namespace of explicit interface method. - [ExpectedWarning ("IL2046", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2046", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3051", "IBaseWithoutRequires.Method()", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2046", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", Tool.NativeAot, "")] + [ExpectedWarning ("IL2046", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", Tool.Analyzer, "")] + [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", Tool.Analyzer, "")] + [ExpectedWarning ("IL3051", "IBaseWithoutRequires.Method()", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", Tool.Analyzer, "")] void IBaseWithoutRequires.Method () { } @@ -416,8 +416,8 @@ void IBaseWithoutRequires.Method () private string name; string IBaseWithoutRequires.PropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "PropertyAnnotationInAccesor.get", "IBaseWithoutRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message")] [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] @@ -426,23 +426,23 @@ string IBaseWithoutRequires.PropertyAnnotationInAccesor { } [RequiresAssemblyFiles ("Message")] - [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", Tool.Analyzer, "")] string IBaseWithoutRequires.PropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.PropertyAnnotationInProperty", "IBaseWithoutRequires.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] set; } [RequiresAssemblyFiles ("Message")] - [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", Tool.Analyzer, "")] string IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor { [RequiresAssemblyFiles ("Message")] [RequiresUnreferencedCode ("Message")] [ExpectedWarning ("IL2046", "PropertyAnnotationInPropertyAndAccessor.get", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get")] - [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor.get", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor.get", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor", "IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -450,8 +450,8 @@ string IBaseWithoutRequires.PropertyAnnotationInPropertyAndAccessor { class ImplementationClassWithoutRequires : IBaseWithRequires { [ExpectedWarning ("IL2046", "ImplementationClassWithoutRequires.Method()", "IBaseWithRequires.Method()")] - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.Method()", "IBaseWithRequires.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequires.Method()", "IBaseWithRequires.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.Method()", "IBaseWithRequires.Method()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequires.Method()", "IBaseWithRequires.Method()", Tool.Analyzer | Tool.NativeAot, "")] public void Method () { } @@ -459,28 +459,28 @@ public void Method () private string name; public string PropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "ImplementationClassWithoutRequires.PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequires.PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequires.PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] get { return name; } set { name = value; } } - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", Tool.Analyzer, "")] public string PropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] set; } - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", Tool.Analyzer, "")] public string PropertyAnnotationInPropertyAndAccessor { [RequiresAssemblyFiles ("Message")] [RequiresUnreferencedCode ("Message")] [ExpectedWarning ("IL2046", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.get")] get; [ExpectedWarning ("IL2046", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.set", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set")] - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.set", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.set", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -488,12 +488,12 @@ public string PropertyAnnotationInPropertyAndAccessor { class ExplicitImplementationClassWithoutRequires : IBaseWithRequires { // ILLink member string format includes namespace of explicit interface method. - [ExpectedWarning ("IL2046", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3003", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3051", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2046", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3003", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3051", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2046", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3003", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", Tool.NativeAot, "")] + [ExpectedWarning ("IL2046", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", Tool.Analyzer, "")] + [ExpectedWarning ("IL3003", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", Tool.Analyzer, "")] + [ExpectedWarning ("IL3051", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", Tool.Analyzer, "")] void IBaseWithRequires.Method () { } @@ -501,26 +501,26 @@ void IBaseWithRequires.Method () private string name; string IBaseWithRequires.PropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "PropertyAnnotationInAccesor.get", "IBaseWithRequires.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] get { return name; } set { name = value; } } - [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", Tool.Analyzer, "")] string IBaseWithRequires.PropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInProperty", "IBaseWithRequires.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] set; } - [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", Tool.Analyzer, "")] string IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor { - [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor", Tool.Analyzer | Tool.NativeAot, "")] get; [ExpectedWarning ("IL2046", "PropertyAnnotationInPropertyAndAccessor.set", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set")] - [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor.set", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "PropertyAnnotationInPropertyAndAccessor.set", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -528,8 +528,8 @@ string IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor { class ImplementationClassWithoutRequiresInSource : ReferenceInterfaces.IBaseWithRequiresInReference { [ExpectedWarning ("IL2046", "ImplementationClassWithoutRequiresInSource.Method()", "IBaseWithRequiresInReference.Method()")] - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.Method()", "IBaseWithRequiresInReference.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequiresInSource.Method()", "IBaseWithRequiresInReference.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.Method()", "IBaseWithRequiresInReference.Method()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequiresInSource.Method()", "IBaseWithRequiresInReference.Method()", Tool.Analyzer | Tool.NativeAot, "")] public void Method () { } @@ -537,17 +537,17 @@ public void Method () private string name; public string PropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithRequiresInReference.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithRequiresInReference.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithRequiresInReference.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithRequiresInReference.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithRequiresInReference.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] get { return name; } set { name = value; } } - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInProperty", "IBaseWithRequiresInReference.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInProperty", "IBaseWithRequiresInReference.PropertyAnnotationInProperty", Tool.Analyzer, "")] public string PropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInProperty.get", "IBaseWithRequiresInReference.PropertyAnnotationInProperty.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInProperty.get", "IBaseWithRequiresInReference.PropertyAnnotationInProperty.get", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInProperty.set", "IBaseWithRequiresInReference.PropertyAnnotationInProperty.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithoutRequiresInSource.PropertyAnnotationInProperty.set", "IBaseWithRequiresInReference.PropertyAnnotationInProperty.set", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -555,8 +555,8 @@ public string PropertyAnnotationInProperty { class ImplementationClassWithRequiresInSource : ReferenceInterfaces.IBaseWithoutRequiresInReference { [ExpectedWarning ("IL2046", "ImplementationClassWithRequiresInSource.Method()", "IBaseWithoutRequiresInReference.Method()")] - [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.Method()", "IBaseWithoutRequiresInReference.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithRequiresInSource.Method()", "IBaseWithoutRequiresInReference.Method()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.Method()", "IBaseWithoutRequiresInReference.Method()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithRequiresInSource.Method()", "IBaseWithoutRequiresInReference.Method()", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message")] [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] @@ -567,8 +567,8 @@ public void Method () private string name; public string PropertyAnnotationInAccesor { [ExpectedWarning ("IL2046", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithoutRequiresInReference.PropertyAnnotationInAccesor.get")] - [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithoutRequiresInReference.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithoutRequiresInReference.PropertyAnnotationInAccesor.get", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithoutRequiresInReference.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", "IBaseWithoutRequiresInReference.PropertyAnnotationInAccesor.get", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message")] [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] @@ -576,12 +576,12 @@ public string PropertyAnnotationInAccesor { set { name = value; } } - [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty", "IBaseWithoutRequiresInReference.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty", "IBaseWithoutRequiresInReference.PropertyAnnotationInProperty", Tool.Analyzer, "")] [RequiresAssemblyFiles ("Message")] public string PropertyAnnotationInProperty { - [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty", "IBaseWithoutRequiresInReference.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty", "IBaseWithoutRequiresInReference.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty", "IBaseWithoutRequiresInReference.PropertyAnnotationInProperty", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplementationClassWithRequiresInSource.PropertyAnnotationInProperty", "IBaseWithoutRequiresInReference.PropertyAnnotationInProperty", Tool.Analyzer | Tool.NativeAot, "")] set; } } @@ -589,23 +589,23 @@ public string PropertyAnnotationInProperty { class StaticInterfaceMethods { [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] public static void Test () { typeof (IRequires).RequiresPublicMethods (); @@ -650,13 +650,13 @@ public static void AbstractMethod () { } class ImplIRequiresMismatching : IRequires { [ExpectedWarning ("IL2046", "ImplIRequiresMismatching.VirtualMethod", "IRequires.VirtualMethod")] - [ExpectedWarning ("IL3003", "ImplIRequiresMismatching.VirtualMethod", "IRequires.VirtualMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplIRequiresMismatching.VirtualMethod", "IRequires.VirtualMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplIRequiresMismatching.VirtualMethod", "IRequires.VirtualMethod", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplIRequiresMismatching.VirtualMethod", "IRequires.VirtualMethod", Tool.Analyzer | Tool.NativeAot, "")] public static void VirtualMethod () { } [ExpectedWarning ("IL2046", "ImplIRequiresMismatching.AbstractMethod", "IRequires.AbstractMethod")] - [ExpectedWarning ("IL3003", "ImplIRequiresMismatching.AbstractMethod", "IRequires.AbstractMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplIRequiresMismatching.AbstractMethod", "IRequires.AbstractMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplIRequiresMismatching.AbstractMethod", "IRequires.AbstractMethod", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplIRequiresMismatching.AbstractMethod", "IRequires.AbstractMethod", Tool.Analyzer | Tool.NativeAot, "")] public static void AbstractMethod () { } } class ImplINoRequiresMatching : INoRequires @@ -669,16 +669,16 @@ public static void AbstractMethod () { } class ImplINoRequiresMismatching : INoRequires { [ExpectedWarning ("IL2046", "ImplINoRequiresMismatching.VirtualMethod", "INoRequires.VirtualMethod")] - [ExpectedWarning ("IL3003", "ImplINoRequiresMismatching.VirtualMethod", "INoRequires.VirtualMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplINoRequiresMismatching.VirtualMethod", "INoRequires.VirtualMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplINoRequiresMismatching.VirtualMethod", "INoRequires.VirtualMethod", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplINoRequiresMismatching.VirtualMethod", "INoRequires.VirtualMethod", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message for --StaticInterfaceMethods.ImplINoRequiresMatching.VirtualMethod--")] [RequiresAssemblyFiles ("Message for --StaticInterfaceMethods.ImplINoRequiresMatching.VirtualMethod--")] [RequiresDynamicCode ("Message for --StaticInterfaceMethods.ImplINoRequiresMatching.VirtualMethod--")] public static void VirtualMethod () { } [ExpectedWarning ("IL2046", "ImplINoRequiresMismatching.AbstractMethod", "INoRequires.AbstractMethod")] - [ExpectedWarning ("IL3003", "ImplINoRequiresMismatching.AbstractMethod", "INoRequires.AbstractMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3051", "ImplINoRequiresMismatching.AbstractMethod", "INoRequires.AbstractMethod", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3003", "ImplINoRequiresMismatching.AbstractMethod", "INoRequires.AbstractMethod", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3051", "ImplINoRequiresMismatching.AbstractMethod", "INoRequires.AbstractMethod", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message for --StaticInterfaceMethods.ImplINoRequiresMatching.AbstractMethod--")] [RequiresAssemblyFiles ("Message for --StaticInterfaceMethods.ImplINoRequiresMatching.AbstractMethod--")] [RequiresDynamicCode ("Message for --StaticInterfaceMethods.ImplINoRequiresMatching.AbstractMethod--")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs index 3def1ee762beaf..a2f38e46486ad1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs @@ -50,8 +50,8 @@ public static void Main () class WarnInIteratorBody { [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static IEnumerable TestCallBeforeYieldReturn () { MethodWithRequires (); @@ -59,8 +59,8 @@ static IEnumerable TestCallBeforeYieldReturn () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static IEnumerable TestCallAfterYieldReturn () { yield return 0; @@ -68,8 +68,8 @@ static IEnumerable TestCallAfterYieldReturn () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] static IEnumerable TestReflectionAccess () { yield return 0; @@ -80,15 +80,15 @@ static IEnumerable TestReflectionAccess () } #if !RELEASE - [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] #else // In release mode, the compiler optimizes away the unused Action (and reference to MethodWithRequires) #endif - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer, "")] static IEnumerable TestLdftn () { yield return 0; @@ -98,8 +98,8 @@ static IEnumerable TestLdftn () // Cannot annotate fields either with RUC nor RAF therefore the warning persists [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static IEnumerable TestLazyDelegate () @@ -110,8 +110,8 @@ static IEnumerable TestLazyDelegate () } [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] static IEnumerable TestDynamicallyAccessedMethod () { typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); @@ -167,8 +167,8 @@ static IEnumerable TestLdftn () // Cannot annotate fields either with RUC nor RAF therefore the warning persists [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static IEnumerable TestLazyDelegate () @@ -234,8 +234,8 @@ public static void Test () class WarnInAsyncBody { [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async void TestCallBeforeYieldReturn () { MethodWithRequires (); @@ -243,8 +243,8 @@ static async void TestCallBeforeYieldReturn () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async void TestCallAfterYieldReturn () { await MethodAsync (); @@ -252,8 +252,8 @@ static async void TestCallAfterYieldReturn () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] static async void TestReflectionAccess () { await MethodAsync (); @@ -264,13 +264,13 @@ static async void TestReflectionAccess () } #if !RELEASE - [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] #endif - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer, "")] static async void TestLdftn () { await MethodAsync (); @@ -278,8 +278,8 @@ static async void TestLdftn () } [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static async void TestLazyDelegate () @@ -289,8 +289,8 @@ static async void TestLazyDelegate () } [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] static async void TestDynamicallyAccessedMethod () { typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); @@ -344,8 +344,8 @@ static async void TestLdftn () // Cannot annotate fields either with RUC nor RAF therefore the warning persists [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static async void TestLazyDelegate () @@ -409,8 +409,8 @@ public static void Test () class WarnInAsyncIteratorBody { [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async IAsyncEnumerable TestCallBeforeYieldReturn () { await MethodAsync (); @@ -419,8 +419,8 @@ static async IAsyncEnumerable TestCallBeforeYieldReturn () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async IAsyncEnumerable TestCallAfterYieldReturn () { yield return 0; @@ -429,8 +429,8 @@ static async IAsyncEnumerable TestCallAfterYieldReturn () } [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] static async IAsyncEnumerable TestReflectionAccess () { yield return 0; @@ -443,13 +443,13 @@ static async IAsyncEnumerable TestReflectionAccess () } #if !RELEASE - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] #endif - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer, "")] static async IAsyncEnumerable TestLdftn () { await MethodAsync (); @@ -458,8 +458,8 @@ static async IAsyncEnumerable TestLdftn () } [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static async IAsyncEnumerable TestLazyDelegate () @@ -470,8 +470,8 @@ static async IAsyncEnumerable TestLazyDelegate () } [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "", CompilerGeneratedCode = true)] static async IAsyncEnumerable TestDynamicallyAccessedMethod () { typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); @@ -530,8 +530,8 @@ static async IAsyncEnumerable TestLdftn () // Cannot annotate fields either with RUC nor RAF therefore the warning persists [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static async IAsyncEnumerable TestLazyDelegate () @@ -604,14 +604,14 @@ static void TestCall () LocalFunction (); [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunction () => MethodWithRequires (); } [ExpectedWarning ("IL2026", "--LocalFunctionWithRequires--")] - [ExpectedWarning ("IL3002", "--LocalFunctionWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--LocalFunctionWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--LocalFunctionWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--LocalFunctionWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestLocalFunctionWithRequires () { LocalFunction (); @@ -633,8 +633,8 @@ static void TestCallWithClosure (int p = 0) LocalFunction (); [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunction () { p++; @@ -657,8 +657,8 @@ static void TestReflectionAccess () LocalFunction (); [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "")] void LocalFunction () => typeof (RequiresInCompilerGeneratedCode) .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic) .Invoke (null, new object[] { }); @@ -669,13 +669,13 @@ static void TestLdftn () LocalFunction (); #if !RELEASE - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "")] #endif - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer, "")] void LocalFunction () { var action = new Action (MethodWithRequires); @@ -683,8 +683,8 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static void TestLazyDelegate () @@ -702,8 +702,8 @@ static void TestDynamicallyAccessedMethod () LocalFunction (); [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] void LocalFunction () => typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); } @@ -788,8 +788,8 @@ void LocalFunction () } [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static void TestLazyDelegate () @@ -919,7 +919,7 @@ public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction class DynamicallyAccessedLocalFunctionUnusedShouldWarn { - [ExpectedWarning ("IL2118", nameof (TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction), "LocalFunction", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", [nameof (TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction), "LocalFunction"], Tool.Trimmer, "")] public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction () { typeof (DynamicallyAccessedLocalFunctionUnusedShouldWarn).RequiresNonPublicMethods (); @@ -949,8 +949,8 @@ public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction } [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] static void TestSuppressionOnLocalFunction () { LocalFunction (); // This will produce a warning since the local function has Requires on it @@ -966,8 +966,8 @@ void LocalFunction (Type unknownType = null) } [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] static void TestSuppressionOnLocalFunctionWithAssignment () { LocalFunction (); // This will produce a warning since the local function has Requires on it @@ -986,8 +986,8 @@ void LocalFunction (Type unknownType = null) static Type typeWithNonPublicMethods; [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] static void TestSuppressionOnLocalFunctionWithNestedLocalFunction () { LocalFunction (); // This will produce a warning since the local function has Requires on it @@ -1001,9 +1001,9 @@ void LocalFunction () // ILLink doesn't have enough information to associate the Requires on LocalFunction // with this nested local function. - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot, "")] void NestedLocalFunction () => MethodWithRequires (); } } @@ -1028,8 +1028,8 @@ void LocalFunction (Type unknownType = null) class TestSuppressionOnOuterWithSameName { [ExpectedWarning ("IL2026", nameof (Outer) + "()")] - [ExpectedWarning ("IL3002", nameof (Outer) + "()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", nameof (Outer) + "()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", nameof (Outer) + "()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", nameof (Outer) + "()", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { Outer (); @@ -1051,8 +1051,8 @@ static void Outer (int i) LocalFunction (); [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunction () => MethodWithRequires (); } } @@ -1093,14 +1093,14 @@ static void WarnInNonNestedLocalFunctionTest () LocalFunction (); [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void LocalFunction () => MethodWithRequires (); } [ExpectedWarning ("IL2026", "--MethodWithNonNestedLocalFunction--")] - [ExpectedWarning ("IL3002", "--MethodWithNonNestedLocalFunction--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithNonNestedLocalFunction--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithNonNestedLocalFunction--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithNonNestedLocalFunction--", Tool.Analyzer | Tool.NativeAot, "")] static void SuppressInNonNestedLocalFunctionTest () { MethodWithNonNestedLocalFunction (); @@ -1122,16 +1122,16 @@ static void TestCall () { Action lambda = [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] () => MethodWithRequires (); lambda (); } [ExpectedWarning ("IL2026", "--LambdaWithRequires--")] - [ExpectedWarning ("IL3002", "--LambdaWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--LambdaWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--LambdaWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--LambdaWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestLambdaWithRequires () { Action lambda = @@ -1147,14 +1147,14 @@ static void TestCallUnused () { Action _ = [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] () => MethodWithRequires (); } [ExpectedWarning ("IL2026", "--LambdaWithRequires--")] - [ExpectedWarning ("IL3002", "--LambdaWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--LambdaWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--LambdaWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--LambdaWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestLambdaWithRequiresUnused () { Action _ = @@ -1168,8 +1168,8 @@ static void TestCallWithClosure (int p = 0) { Action lambda = [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] () => { p++; MethodWithRequires (); @@ -1182,13 +1182,13 @@ static void TestCallWithClosureUnused (int p = 0) { Action _ = #if !RELEASE - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "")] #endif - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer, "")] () => { p++; MethodWithRequires (); @@ -1199,8 +1199,8 @@ static void TestReflectionAccess () { Action _ = [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "")] () => { typeof (RequiresInCompilerGeneratedCode) .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic) @@ -1212,21 +1212,21 @@ static void TestLdftn () { Action _ = #if !RELEASE - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "")] #endif - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer, "")] () => { var action = new Action (MethodWithRequires); }; } [ExpectedWarning ("IL2026", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static void TestLazyDelegate () @@ -1240,8 +1240,8 @@ static void TestDynamicallyAccessedMethod () { Action _ = [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TypeWithMethodWithRequires.MethodWithRequires--", Tool.NativeAot, "")] () => { typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); }; @@ -1330,8 +1330,8 @@ static void TestLdftn () } [ExpectedWarning ("IL2026", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequiresAndReturns--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] public static Lazy _default = new Lazy (MethodWithRequiresAndReturns); static void TestLazyDelegate () @@ -1383,8 +1383,8 @@ static void TestGenericTypeParameterRequirement () } [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] static void TestSuppressionOnLambda () { var lambda = @@ -1397,8 +1397,8 @@ static void TestSuppressionOnLambda () } [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] static void TestSuppressionOnLambdaWithNestedLambda () { var lambda = @@ -1411,9 +1411,9 @@ static void TestSuppressionOnLambdaWithNestedLambda () // an IL reference to the generated lambda method, unlike local functions. // However, we don't make this association, for consistency with local functions. var nestedLambda = - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", ProducedBy = Tool.NativeAot | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.NativeAot | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", Tool.NativeAot | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.NativeAot | Tool.NativeAot, "")] () => MethodWithRequires (); }; @@ -1440,8 +1440,8 @@ static void TestSuppressionOnOuterAndLambda () class TestSuppressionOnOuterWithSameName { [ExpectedWarning ("IL2026", nameof (Outer) + "()")] - [ExpectedWarning ("IL3002", nameof (Outer) + "()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", nameof (Outer) + "()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", nameof (Outer) + "()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", nameof (Outer) + "()", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { Outer (); @@ -1462,8 +1462,8 @@ static void Outer (int i) { var lambda = [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] () => MethodWithRequires (); lambda (); @@ -1503,8 +1503,8 @@ static async void TestIteratorLocalFunctionInAsync () await MethodAsync (); [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] IEnumerable LocalFunction () { yield return 0; @@ -1543,8 +1543,8 @@ IEnumerable IteratorLocalFunction () yield return 1; [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunction () => MethodWithRequires (); } } @@ -1561,8 +1561,8 @@ IEnumerable IteratorLocalFunction () } [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunction () => MethodWithRequires (); } @@ -1754,8 +1754,8 @@ static IEnumerable TestDynamicallyAccessedMethodViaGenericMethodParameterIn #endif [ExpectedWarning ("IL2026", "--IteratorLocalFunction--")] - [ExpectedWarning ("IL3002", "--IteratorLocalFunction--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--IteratorLocalFunction--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--IteratorLocalFunction--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--IteratorLocalFunction--", Tool.Analyzer | Tool.NativeAot, "")] static void TestLocalFunctionInIteratorLocalFunction () { IteratorLocalFunction (); @@ -1771,16 +1771,16 @@ IEnumerable IteratorLocalFunction () yield return 1; // Trimmer doesn't try to associate LocalFunction with IteratorLocalFunction - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.NativeAot, "")] void LocalFunction () => MethodWithRequires (); } } [ExpectedWarning ("IL2026", "--IteratorLocalFunction--")] - [ExpectedWarning ("IL3002", "--IteratorLocalFunction--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--IteratorLocalFunction--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--IteratorLocalFunction--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--IteratorLocalFunction--", Tool.Analyzer | Tool.NativeAot, "")] static void TestLocalFunctionCalledFromIteratorLocalFunctionAndMethod () { IteratorLocalFunction (); @@ -1798,8 +1798,8 @@ IEnumerable IteratorLocalFunction () } [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] void LocalFunction () => MethodWithRequires (); } @@ -1847,8 +1847,8 @@ static async void TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress () } [ExpectedWarning ("IL2026", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static IEnumerable TestIteratorOnlyReferencedViaReflectionWhichShouldWarn () { yield return 0; @@ -1856,8 +1856,8 @@ static IEnumerable TestIteratorOnlyReferencedViaReflectionWhichShouldWarn ( } [ExpectedWarning ("IL2026", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3002", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot, CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "", CompilerGeneratedCode = true)] static async void TestAsyncOnlyReferencedViaReflectionWhichShouldWarn () { await MethodAsync (); @@ -1865,26 +1865,24 @@ static async void TestAsyncOnlyReferencedViaReflectionWhichShouldWarn () } [ExpectedWarning ("IL2026", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--")] - [ExpectedWarning ("IL3002", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--")] - [ExpectedWarning ("IL3002", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestAsyncOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", - ProducedBy = Tool.Trimmer)] - [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestIteratorOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] + [ExpectedWarning ("IL2118", [nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestAsyncOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()"], Tool.Trimmer, "")] + [ExpectedWarning ("IL2118", [nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestIteratorOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()"], Tool.Trimmer, "")] static void TestAll () { typeof (StateMachinesOnlyReferencedViaReflection).RequiresAll (); } [ExpectedWarning ("IL2026", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--")] - [ExpectedWarning ("IL3002", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--")] - [ExpectedWarning ("IL3002", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", Tool.NativeAot, "")] // NonPublicMethods doesn't warn for members emitted into compiler-generated state machine types. static void TestNonPublicMethods () { @@ -1901,8 +1899,8 @@ public static void Test () class LocalFunctionsReferencedViaReflection { [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestLocalFunctionWithRequires () { LocalFunction (); @@ -1922,8 +1920,8 @@ static void TestLocalFunctionWithRequiresOnlyAccessedViaReflection () } [ExpectedWarning ("IL2026", "LocalFunction")] - [ExpectedWarning ("IL3002", "LocalFunction", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "LocalFunction", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "LocalFunction", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "LocalFunction", Tool.Analyzer | Tool.NativeAot, "")] static void TestLocalFunctionWithClosureWithRequires (int p = 0) { LocalFunction (); @@ -1974,16 +1972,15 @@ void LocalFunction () // Warnings for Reflection access to methods with Requires [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection), - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", Tool.NativeAot, "")] + [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection), Tool.Trimmer, "")] static void TestAll () { typeof (LocalFunctionsReferencedViaReflection).RequiresAll (); @@ -1991,16 +1988,15 @@ static void TestAll () // Warnings for Reflection access to methods with Requires [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionWithClosureInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionWithClosureInMethodWithRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")] - [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), "<" + nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection) + ">", - ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL3002", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--", Tool.NativeAot, "")] + [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), "<" + nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection) + ">", Tool.Trimmer, "")] static void TestNonPublicMethods () { typeof (LocalFunctionsReferencedViaReflection).RequiresNonPublicMethods (); @@ -2016,8 +2012,8 @@ public static void Test () class LambdasReferencedViaReflection { [ExpectedWarning ("IL2026", "--TestLambdaWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLambdaWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLambdaWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLambdaWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLambdaWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestLambdaWithRequires () { var lambda = @@ -2030,8 +2026,8 @@ static void TestLambdaWithRequires () } [ExpectedWarning ("IL2026", "Lambda")] - [ExpectedWarning ("IL3002", "Lambda", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Lambda", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Lambda", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Lambda", Tool.Analyzer | Tool.NativeAot, "")] static void TestLambdaWithClosureWithRequires (int p = 0) { var lambda = @@ -2071,11 +2067,11 @@ static void TestLambdaWithClosureInMethodWithRequires (int p = 0) // Warnings for Reflection access to methods with Requires [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestLambdaWithClosureInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLambdaWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLambdaWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLambdaWithClosureInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLambdaWithClosureInMethodWithRequires--", Tool.NativeAot, "")] static void TestAll () { typeof (LambdasReferencedViaReflection).RequiresAll (); @@ -2083,11 +2079,11 @@ static void TestAll () // Warnings for Reflection access to methods with Requires [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLambdaInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLambdaInMethodWithRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TestLambdaWithClosureInMethodWithRequires--")] - [ExpectedWarning ("IL3002", "--TestLambdaWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TestLambdaWithClosureInMethodWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TestLambdaWithClosureInMethodWithRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TestLambdaWithClosureInMethodWithRequires--", Tool.NativeAot, "")] static void TestNonPublicMethods () { typeof (LambdasReferencedViaReflection).RequiresNonPublicMethods (); @@ -2123,8 +2119,8 @@ static async Task AsyncMethodCallingRequires (Type type) } [ExpectedWarning ("IL2026", "ParentSuppression")] - [ExpectedWarning ("IL3002", "ParentSuppression", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "ParentSuppression", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ParentSuppression", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "ParentSuppression", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { AsyncMethodCallingRequires (typeof (object)); @@ -2152,8 +2148,8 @@ static async Task AsyncMethodCallingRequires () } [ExpectedWarning ("IL2026", "ParentSuppression")] - [ExpectedWarning ("IL3002", "ParentSuppression", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "ParentSuppression", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ParentSuppression", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "ParentSuppression", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { AsyncMethodCallingRequires (); @@ -2192,8 +2188,8 @@ static async IAsyncEnumerable CreateAsync () } [ExpectedWarning ("IL2026", "ParentSuppression")] - [ExpectedWarning ("IL3002", "ParentSuppression", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "ParentSuppression", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "ParentSuppression", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "ParentSuppression", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { AsyncEnumMethodCallingRequires (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs index 8710ed0e45cf82..a8f5ab60dd0578 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttribute.cs @@ -61,16 +61,16 @@ public bool PropertyWhichRequires { } [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] class GenericTypeWithAttributedParameter<[AttributeWhichRequires] T> { public static void TestMethod () { } } [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] static void GenericMethodWithAttributedParameter<[AttributeWhichRequires] T> () { } static void TestRequiresOnAttributeOnGenericParameter () @@ -80,11 +80,11 @@ static void TestRequiresOnAttributeOnGenericParameter () } [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] [AttributeWhichRequires] [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] class TypeWithAttributeWhichRequires @@ -92,31 +92,31 @@ class TypeWithAttributeWhichRequires } [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] [AttributeWhichRequires] [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] static void MethodWithAttributeWhichRequires () { } [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] [AttributeWhichRequires] [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] static int _fieldWithAttributeWhichRequires; [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")] - [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] [AttributeWhichRequires] [AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)] static bool PropertyWithAttributeWhichRequires { get; set; } @@ -129,8 +129,8 @@ static void MethodWithAttributeWhichRequires () { } static void MethodWhichRequiresWithAttributeWhichRequires () { } [ExpectedWarning ("IL2026", "--MethodWhichRequiresWithAttributeWhichRequires--")] - [ExpectedWarning ("IL3002", "--MethodWhichRequiresWithAttributeWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWhichRequiresWithAttributeWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWhichRequiresWithAttributeWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWhichRequiresWithAttributeWhichRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestMethodWhichRequiresWithAttributeWhichRequires () { MethodWhichRequiresWithAttributeWhichRequires (); @@ -152,8 +152,8 @@ public void MethodWhichRequires () { } } [ExpectedWarning ("IL2026", "--TypeWithMethodWhichRequires--")] - [ExpectedWarning ("IL3002", "--TypeWithMethodWhichRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWithMethodWhichRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWithMethodWhichRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TypeWithMethodWhichRequires--", Tool.NativeAot, "")] [AttributeWhichMarksPublicMethods (typeof(TypeWithMethodWhichRequires))] static void ShouldWarn() { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index f1faf7684750f3..dc9a49597e7d9b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -59,7 +59,7 @@ public static void NestedStaticMethod () { } // This warning doesn't get suppressed since the declaring type NestedClass is not annotated with Requires [ExpectedWarning ("IL2026", "RequiresOnClass.RequiresOnMethod.MethodWithRequires()", "MethodWithRequires")] - [ExpectedWarning ("IL3050", "RequiresOnClass.RequiresOnMethod.MethodWithRequires()", "MethodWithRequires", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.RequiresOnMethod.MethodWithRequires()", "MethodWithRequires", Tool.Analyzer | Tool.NativeAot, "")] public static void CallMethodWithRequires () => RequiresOnMethod.MethodWithRequires (); } @@ -101,7 +101,7 @@ private class DerivedWithoutRequires : ClassWithRequires { // This method contains implicit call to ClassWithRequires.ctor() [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] public DerivedWithoutRequires () { } public static void StaticMethodInInheritedClass () { } @@ -155,7 +155,7 @@ static StaticCtor () } [ExpectedWarning ("IL2026", "RequiresOnClass.StaticCtor.StaticCtor()", "Message for --StaticCtor--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.StaticCtor.StaticCtor()", "Message for --StaticCtor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.StaticCtor.StaticCtor()", "Message for --StaticCtor--", Tool.Analyzer | Tool.NativeAot, "")] static void TestStaticCctorRequires () { _ = new StaticCtor (); @@ -174,14 +174,14 @@ static StaticCtorTriggeredByFieldAccess () } [ExpectedWarning ("IL2026", "StaticCtorTriggeredByFieldAccess.field", "Message for --StaticCtorTriggeredByFieldAccess--")] - [ExpectedWarning ("IL3050", "StaticCtorTriggeredByFieldAccess.field", "Message for --StaticCtorTriggeredByFieldAccess--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "StaticCtorTriggeredByFieldAccess.field", "Message for --StaticCtorTriggeredByFieldAccess--", Tool.Analyzer | Tool.NativeAot, "")] static void TestStaticCtorMarkingIsTriggeredByFieldAccessWrite () { StaticCtorTriggeredByFieldAccess.field = 1; } [ExpectedWarning ("IL2026", "StaticCtorTriggeredByFieldAccess.field", "Message for --StaticCtorTriggeredByFieldAccess--")] - [ExpectedWarning ("IL3050", "StaticCtorTriggeredByFieldAccess.field", "Message for --StaticCtorTriggeredByFieldAccess--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "StaticCtorTriggeredByFieldAccess.field", "Message for --StaticCtorTriggeredByFieldAccess--", Tool.Analyzer | Tool.NativeAot, "")] static void TestStaticCtorMarkingTriggeredOnSecondAccessWrite () { StaticCtorTriggeredByFieldAccess.field = 2; @@ -209,7 +209,7 @@ class StaticCCtorTriggeredByFieldAccessRead } [ExpectedWarning ("IL2026", "StaticCCtorTriggeredByFieldAccessRead.field", "Message for --StaticCCtorTriggeredByFieldAccessRead--")] - [ExpectedWarning ("IL3050", "StaticCCtorTriggeredByFieldAccessRead.field", "Message for --StaticCCtorTriggeredByFieldAccessRead--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "StaticCCtorTriggeredByFieldAccessRead.field", "Message for --StaticCCtorTriggeredByFieldAccessRead--", Tool.Analyzer | Tool.NativeAot, "")] static void TestStaticCtorMarkingIsTriggeredByFieldAccessRead () { var _ = StaticCCtorTriggeredByFieldAccessRead.field; @@ -229,7 +229,7 @@ public void TriggerStaticCtorMarking () } [ExpectedWarning ("IL2026", "StaticCtorTriggeredByCtorCalls.StaticCtorTriggeredByCtorCalls()")] - [ExpectedWarning ("IL3050", "StaticCtorTriggeredByCtorCalls.StaticCtorTriggeredByCtorCalls()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "StaticCtorTriggeredByCtorCalls.StaticCtorTriggeredByCtorCalls()", Tool.Analyzer | Tool.NativeAot, "")] static void TestStaticCtorTriggeredByCtorCall () { new StaticCtorTriggeredByCtorCalls (); @@ -243,7 +243,7 @@ class ClassWithInstanceField } [ExpectedWarning ("IL2026", "ClassWithInstanceField.ClassWithInstanceField()")] - [ExpectedWarning ("IL3050", "ClassWithInstanceField.ClassWithInstanceField()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "ClassWithInstanceField.ClassWithInstanceField()", Tool.Analyzer | Tool.NativeAot, "")] static void TestInstanceFieldCallDontWarn () { ClassWithInstanceField instance = new ClassWithInstanceField (); @@ -260,7 +260,7 @@ public ClassWithInstanceFieldWhichInitsDangerousClass () { } } [ExpectedWarning ("IL2026", "Calling the constructor is dangerous")] - [ExpectedWarning ("IL3050", "Calling the constructor is dangerous", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "Calling the constructor is dangerous", Tool.Analyzer | Tool.NativeAot, "")] static void TestInstanceFieldSuppression () { _ = new ClassWithInstanceFieldWhichInitsDangerousClass (); @@ -310,7 +310,7 @@ public class DerivedNestedClass : ClassWithRequires { // This method contains implicit call to ClassWithRequires.ctor() [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] public DerivedNestedClass () { } public static void NestedStaticMethod () { } @@ -389,14 +389,14 @@ public int Method (int a) } [ExpectedWarning ("IL2026", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresInClassAccessedByStaticMethod () { ClassWithRequires.StaticMethod (); } [ExpectedWarning ("IL2026", "RequiresOnClass.ClassWithRequires", "--ClassWithRequires--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires", "--ClassWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresInClassAccessedByCctor () { var classObject = new ClassWithRequires (); @@ -408,12 +408,12 @@ static void TestRequiresInParentClassAccesedByStaticMethod () } [ExpectedWarning ("IL2026", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] // Although we suppress the warning from RequiresOnMethod.MethodWithRequires () we still get a warning because we call CallRequiresMethod() which is an static method on a type with RUC [ExpectedWarning ("IL2026", "RequiresOnClass.ClassWithRequires.CallMethodWithRequires()", "--ClassWithRequires--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.CallMethodWithRequires()", "--ClassWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.CallMethodWithRequires()", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ClassWithRequires.Instance", "--ClassWithRequires--")] - [ExpectedWarning ("IL3050", "ClassWithRequires.Instance", "--ClassWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "ClassWithRequires.Instance", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresOnBaseButNotOnDerived () { var a = new DerivedWithoutRequires (); // Must instantiate to force checks on the base type (otherwise base type is non-interesting) @@ -429,7 +429,7 @@ static void TestRequiresOnBaseButNotOnDerived () } [ExpectedWarning ("IL2026", "RequiresOnClass.DerivedWithRequires.StaticMethodInInheritedClass()", "--DerivedWithRequires--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.DerivedWithRequires.StaticMethodInInheritedClass()", "--DerivedWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.DerivedWithRequires.StaticMethodInInheritedClass()", "--DerivedWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresOnDerivedButNotOnBase () { DerivedWithRequires.StaticMethodInInheritedClass (); @@ -439,9 +439,9 @@ static void TestRequiresOnDerivedButNotOnBase () } [ExpectedWarning ("IL2026", "RequiresOnClass.DerivedWithRequires2.StaticMethodInInheritedClass()", "--DerivedWithRequires2--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.DerivedWithRequires2.StaticMethodInInheritedClass()", "--DerivedWithRequires2--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.DerivedWithRequires2.StaticMethodInInheritedClass()", "--DerivedWithRequires2--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--")] - [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.StaticMethod()", "--ClassWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresOnBaseAndDerived () { DerivedWithRequires2.StaticMethodInInheritedClass (); @@ -452,7 +452,7 @@ static void TestRequiresOnBaseAndDerived () } [ExpectedWarning ("IL2026", "RequiresOnClass.ClassWithRequires.TestSuppressions(", "Type[])")] - [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.TestSuppressions(", "Type[])", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "RequiresOnClass.ClassWithRequires.TestSuppressions(", "Type[])", Tool.Analyzer | Tool.NativeAot, "")] static void TestSuppressionsOnClass () { ClassWithRequires.TestSuppressions (new[] { typeof (ClassWithRequires) }); @@ -496,11 +496,11 @@ class MemberTypesWithRequires } [ExpectedWarning ("IL2026", "MemberTypesWithRequires.field")] - [ExpectedWarning ("IL3050", "MemberTypesWithRequires.field", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "MemberTypesWithRequires.field", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "MemberTypesWithRequires.Property.set")] - [ExpectedWarning ("IL3050", "MemberTypesWithRequires.Property.set", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "MemberTypesWithRequires.Property.set", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "MemberTypesWithRequires.Event.remove")] - [ExpectedWarning ("IL3050", "MemberTypesWithRequires.Event.remove", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "MemberTypesWithRequires.Event.remove", Tool.Analyzer | Tool.NativeAot, "")] static void TestOtherMemberTypesWithRequires () { MemberTypesWithRequires.field = 1; @@ -519,25 +519,25 @@ static void TestNameOfDoesntWarn () class ReflectionAccessOnMethod { [ExpectedWarning ("IL2026", "BaseWithRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "BaseWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseWithRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "BaseWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method(Int32)")] - [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method(Int32)", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method(Int32)", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method()")] - [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method(Int32)")] - [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method(Int32)", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method(Int32)", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()")] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequiresOnTypeOverBaseWithNoRequires.Method()", Tool.NativeAot, "")] static void TestDAMAccess () { // Warns because BaseWithoutRequiresOnType.Method has Requires on the method @@ -563,17 +563,17 @@ static void TestDAMAccess () } [ExpectedWarning ("IL2026", "BaseWithRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "BaseWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithoutRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method(Int32)")] - [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method(Int32)", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method(Int32)", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method()")] - [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "InterfaceWithoutRequires.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method()")] - [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method(Int32)")] - [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method(Int32)", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "ImplementationWithRequiresOnType.Method(Int32)", Tool.NativeAot, "")] static void TestDirectReflectionAccess () { // Requires on the method itself @@ -609,7 +609,7 @@ public BaseWithRequires () { } class DerivedWithoutRequires : BaseWithRequires { [ExpectedWarning ("IL2026", "--BaseWithRequires--")] // The body has direct call to the base.ctor() - [ExpectedWarning ("IL3050", "--BaseWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--BaseWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] public DerivedWithoutRequires () { } } @@ -631,15 +631,15 @@ public DerivedWithRequiresOnBaseWithoutRequires () { } } [ExpectedWarning ("IL2026", "BaseWithRequires.BaseWithRequires()")] - [ExpectedWarning ("IL3050", "BaseWithRequires.BaseWithRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithRequires.BaseWithRequires()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseWithRequires.BaseWithRequires()")] - [ExpectedWarning ("IL3050", "BaseWithRequires.BaseWithRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithRequires.BaseWithRequires()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()")] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()")] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()")] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", Tool.NativeAot, "")] static void TestDAMAccess () { // Warns because the type has Requires @@ -656,11 +656,11 @@ static void TestDAMAccess () } [ExpectedWarning ("IL2026", "BaseWithRequires.BaseWithRequires()")] - [ExpectedWarning ("IL3050", "BaseWithRequires.BaseWithRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "BaseWithRequires.BaseWithRequires()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()")] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()")] - [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", Tool.NativeAot, "")] static void TestDirectReflectionAccess () { typeof (BaseWithRequires).GetConstructor (Type.EmptyTypes); @@ -708,15 +708,15 @@ class DerivedWithRequires : WithRequires } [ExpectedWarning ("IL2026", "WithRequires.StaticField")] - [ExpectedWarning ("IL3050", "WithRequires.StaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticField", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticField")] - [ExpectedWarning ("IL3050", "WithRequires.StaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticField", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticField")] - [ExpectedWarning ("IL3050", "WithRequires.StaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticField", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticField")] - [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticField", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticField")] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticField", Tool.NativeAot, "")] static void TestDAMAccess () { typeof (WithRequires).RequiresPublicFields (); @@ -727,11 +727,11 @@ static void TestDAMAccess () } [ExpectedWarning ("IL2026", "WithRequires.StaticField")] - [ExpectedWarning ("IL3050", "WithRequires.StaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticField", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticField")] - [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticField", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticField")] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticField", Tool.NativeAot, "")] static void TestDirectReflectionAccess () { typeof (WithRequires).GetField (nameof (WithRequires.StaticField)); @@ -742,17 +742,17 @@ static void TestDirectReflectionAccess () typeof (DerivedWithRequires).GetField (nameof (DerivedWithRequires.DerivedStaticField)); } - [ExpectedWarning ("IL2026", "WithRequires.StaticField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticField", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticField", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "WithRequires.StaticField", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticField", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticField", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticField", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticField", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticField", Tool.NativeAot, "")] [DynamicDependency (nameof (WithRequires.StaticField), typeof (WithRequires))] [DynamicDependency (nameof (WithRequires.InstanceField), typeof (WithRequires))] // Doesn't warn [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (DerivedWithoutRequires))] // Doesn't warn - [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticField", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticField", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticField", Tool.NativeAot, "")] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (DerivedWithRequires))] static void TestDynamicDependencyAccess () { @@ -768,13 +768,13 @@ class BaseForDAMAnnotatedClass [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] [RequiresUnreferencedCode ("This class is dangerous")] [RequiresDynamicCode ("This class is dangerous")] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseField", Tool.Trimmer | Tool.NativeAot, "")] class DAMAnnotatedClass : BaseForDAMAnnotatedClass { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicField", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicField", Tool.Trimmer | Tool.NativeAot, "")] public static int publicField; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privatefield", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privatefield", Tool.Trimmer | Tool.NativeAot, "")] static int privatefield; } @@ -786,7 +786,7 @@ static void TestDAMOnTypeAccess (DAMAnnotatedClass instance) [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] class DAMAnnotatedClassAccessedFromRUCScope { - [ExpectedWarning ("IL2112", "DAMAnnotatedClassAccessedFromRUCScope.RUCMethod", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClassAccessedFromRUCScope.RUCMethod", Tool.Trimmer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("--RUCMethod--")] public static void RUCMethod () { } } @@ -807,14 +807,14 @@ class GenericTypeWithRequires } [ExpectedWarning ("IL2026", "NonGenericField", "--GenericTypeWithRequires--")] - [ExpectedWarning ("IL3050", "NonGenericField", "--GenericTypeWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "NonGenericField", "--GenericTypeWithRequires--", Tool.NativeAot, "")] static void TestDAMAccessOnOpenGeneric () { typeof (GenericTypeWithRequires<>).RequiresPublicFields (); } [ExpectedWarning ("IL2026", "NonGenericField", "--GenericTypeWithRequires--")] - [ExpectedWarning ("IL3050", "NonGenericField", "--GenericTypeWithRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "NonGenericField", "--GenericTypeWithRequires--", Tool.NativeAot, "")] static void TestDAMAccessOnInstantiatedGeneric () { typeof (GenericTypeWithRequires).RequiresPublicFields (); @@ -846,11 +846,11 @@ class WithRequires } [ExpectedWarning ("IL2026", "StaticEvent.add")] - [ExpectedWarning ("IL3050", "StaticEvent.add", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "StaticEvent.add", Tool.NativeAot, "")] // https://github.com/dotnet/runtime/issues/100499 - [ExpectedWarning ("IL2026", "StaticEvent.add", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", "StaticEvent.add", Tool.Trimmer, "")] [ExpectedWarning ("IL2026", "StaticEvent.remove")] - [ExpectedWarning ("IL3050", "StaticEvent.remove", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "StaticEvent.remove", Tool.NativeAot, "")] static void TestDirectReflectionAccess () { typeof (WithRequires).GetEvent (nameof (WithRequires.StaticEvent)); @@ -894,41 +894,41 @@ class DerivedWithRequires : WithRequires } [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequiresOnlyInstanceProperties.InstanceProperty.get")] - [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequiresOnlyInstanceProperties.InstanceProperty.set")] - [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.get")] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.set")] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.set", Tool.NativeAot, "")] static void TestDAMAccess () { typeof (WithRequires).RequiresPublicProperties (); @@ -939,25 +939,25 @@ static void TestDAMAccess () } [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.get")] - [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.set")] - [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequires.PrivateStaticProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequiresOnlyInstanceProperties.InstanceProperty.get")] - [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "WithRequiresOnlyInstanceProperties.InstanceProperty.set")] - [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "WithRequiresOnlyInstanceProperties.InstanceProperty.set", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.get")] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.get", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.get", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.set")] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.set", Tool.NativeAot, "")] static void TestDirectReflectionAccess () { typeof (WithRequires).GetProperty (nameof (WithRequires.StaticProperty)); @@ -968,37 +968,37 @@ static void TestDirectReflectionAccess () typeof (DerivedWithRequires).GetProperty (nameof (DerivedWithRequires.DerivedStaticProperty)); } - [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.InstanceProperty.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.InstanceProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "WithRequires.StaticProperty.set", Tool.NativeAot, "")] [DynamicDependency (nameof (WithRequires.StaticProperty), typeof (WithRequires))] [DynamicDependency (nameof (WithRequires.InstanceProperty), typeof (WithRequires))] // Doesn't warn [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (DerivedWithoutRequires))] // Doesn't warn - [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.get", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.set", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.get", Tool.NativeAot, "")] + [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.set", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "DerivedWithRequires.DerivedStaticProperty.set", Tool.NativeAot, "")] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (DerivedWithRequires))] static void TestDynamicDependencyAccess () { @@ -1014,21 +1014,21 @@ class BaseForDAMAnnotatedClass [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] [RequiresUnreferencedCode ("This class is dangerous")] [RequiresDynamicCode ("This class is dangerous")] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.get", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL2113", "BaseForDAMAnnotatedClass.baseProperty.set", Tool.Trimmer | Tool.NativeAot, "")] class DAMAnnotatedClass : BaseForDAMAnnotatedClass { public static int publicProperty { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.get", Tool.Trimmer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.publicProperty.set", Tool.Trimmer | Tool.NativeAot, "")] set; } static int privateProperty { - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.get", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.get", Tool.Trimmer | Tool.NativeAot, "")] get; - [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.set", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2112", "DAMAnnotatedClass.privateProperty.set", Tool.Trimmer | Tool.NativeAot, "")] set; } } @@ -1064,7 +1064,7 @@ public int PropertyOnAttribute { [AttributeWithRequires (PropertyOnAttribute = 42)] [ExpectedWarning ("IL2026", "AttributeWithRequires.AttributeWithRequires()")] - [ExpectedWarning ("IL3050", "AttributeWithRequires.AttributeWithRequires()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "AttributeWithRequires.AttributeWithRequires()", Tool.Analyzer | Tool.NativeAot, "")] static void KeepFieldOnAttributeInner () { } static void KeepFieldOnAttribute () @@ -1114,7 +1114,7 @@ public static void Test () { } } [ExpectedWarning ("IL2026")] - [ExpectedWarning ("IL3050", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { TestClass.Test (); @@ -1142,7 +1142,7 @@ public class ClassWithRequires // https://github.com/dotnet/linker/issues/3142 // Instance fields get generic warnings but static fields don't. - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] public RequiresAll instanceField; [RequiresOnCtor] @@ -1150,7 +1150,7 @@ public class ClassWithRequires // https://github.com/dotnet/linker/issues/3140 // Instance fields get attribute warnings but static fields don't. - [ExpectedWarning ("IL2026", "--RequiresOnCtorAttribute--", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", "--RequiresOnCtorAttribute--", Tool.Trimmer, "")] [RequiresOnCtor] public int instanceFieldWithAttribute; @@ -1212,7 +1212,7 @@ public class GenericAnnotatedWithWarningWithRequires<[DynamicallyAccessedMembers [ExpectedWarning ("IL2026", "--GenericClassWithWarningWithRequires--")] [ExpectedWarning ("IL2026", "--ClassWithWarningWithRequires--")] [ExpectedWarning ("IL2026", "--GenericAnnotatedWithWarningWithRequires--")] - [ExpectedWarning ("IL2091", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2091", Tool.Trimmer, "")] public static void Test (ClassWithRequires inst = null) { var f = ClassWithRequires.field; @@ -1244,7 +1244,7 @@ public static void Method () { } } [ExpectedWarning ("IL2026", "--ConstClassWithRequires--", nameof (ConstClassWithRequires.Method))] - [ExpectedWarning ("IL3050", "--ConstClassWithRequires--", nameof (ConstClassWithRequires.Method), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--ConstClassWithRequires--", nameof (ConstClassWithRequires.Method), Tool.Analyzer | Tool.NativeAot, "")] static void TestClassWithRequires () { var a = ConstClassWithRequires.Message; @@ -1263,7 +1263,7 @@ public static void Method () { } } [ExpectedWarning ("IL2026", "--ConstClassWithRequiresUsingField--", nameof (ConstClassWithRequiresUsingField.Method))] - [ExpectedWarning ("IL3050", "--ConstClassWithRequiresUsingField--", nameof (ConstClassWithRequiresUsingField.Method), ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3050", "--ConstClassWithRequiresUsingField--", nameof (ConstClassWithRequiresUsingField.Method), Tool.Analyzer | Tool.NativeAot, "")] static void TestClassUsingFieldInAttribute () { ConstClassWithRequiresUsingField.Method (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnStaticConstructor.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnStaticConstructor.cs index 98fbe6876f0aef..cfd8bfd9145f37 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnStaticConstructor.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnStaticConstructor.cs @@ -30,8 +30,8 @@ public static void Main () class StaticCtor { [ExpectedWarning ("IL2026", "--MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2116", "StaticCtor..cctor()")] [RequiresUnreferencedCode ("Message for --TestStaticCtor--")] static StaticCtor () @@ -48,8 +48,8 @@ static void TestStaticCctorRequires () [RequiresUnreferencedCode ("Message for --StaticCtorOnTypeWithRequires--")] class StaticCtorOnTypeWithRequires { - [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static StaticCtorOnTypeWithRequires () => MethodWithRequires (); } @@ -70,8 +70,8 @@ static void TestRunClassConstructorOnTypeWithRequires () class StaticCtorForRunClassConstructorWithRequires { [ExpectedWarning ("IL2116")] - [ExpectedWarning ("IL3004", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3056", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3004", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3056", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message for --StaticCtorOnTypeWithRequires--")] [RequiresAssemblyFiles ("Message for --StaticCtorOnTypeWithRequires--")] [RequiresDynamicCode ("Message for --StaticCtorOnTypeWithRequires--")] @@ -118,8 +118,8 @@ static void TestStaticCtorMarkingIsTriggeredByFieldAccessOnExplicitLayout () class StaticCtorTriggeredByMethodCall { [ExpectedWarning ("IL2116", "StaticCtorTriggeredByMethodCall..cctor()")] - [ExpectedWarning ("IL3004", "StaticCtorTriggeredByMethodCall..cctor()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3056", "StaticCtorTriggeredByMethodCall..cctor()", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3004", "StaticCtorTriggeredByMethodCall..cctor()", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3056", "StaticCtorTriggeredByMethodCall..cctor()", Tool.Analyzer | Tool.NativeAot, "")] [RequiresUnreferencedCode ("Message for --StaticCtorTriggeredByMethodCall.Cctor--")] [RequiresAssemblyFiles ("Message for --StaticCtorTriggeredByMethodCall.Cctor--")] [RequiresDynamicCode ("Message for --StaticCtorTriggeredByMethodCall.Cctor--")] @@ -137,8 +137,8 @@ public void TriggerStaticCtorMarking () [ExpectedWarning ("IL2026", "--StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--")] - [ExpectedWarning ("IL3002", "--StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--StaticCtorTriggeredByMethodCall.TriggerStaticCtorMarking--", Tool.Analyzer | Tool.NativeAot, "")] static void TestStaticCtorTriggeredByMethodCall () { new StaticCtorTriggeredByMethodCall ().TriggerStaticCtorMarking (); @@ -146,9 +146,9 @@ static void TestStaticCtorTriggeredByMethodCall () class TypeIsBeforeFieldInit { - [ExpectedWarning ("IL2026", "Message from --TypeIsBeforeFieldInit.AnnotatedMethod--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3002", "Message from --TypeIsBeforeFieldInit.AnnotatedMethod--", ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL3050", "Message from --TypeIsBeforeFieldInit.AnnotatedMethod--", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", "Message from --TypeIsBeforeFieldInit.AnnotatedMethod--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3002", "Message from --TypeIsBeforeFieldInit.AnnotatedMethod--", Tool.Analyzer, "")] + [ExpectedWarning ("IL3050", "Message from --TypeIsBeforeFieldInit.AnnotatedMethod--", Tool.Analyzer, "")] public static int field = AnnotatedMethod (); [RequiresUnreferencedCode ("Message from --TypeIsBeforeFieldInit.AnnotatedMethod--")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs index b9ac10e61c11aa..4623dd6355fc1f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnVirtualsAndInterfaces.cs @@ -46,8 +46,8 @@ public override void VirtualMethodRequires () } [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestCallOnBase () { var tmp = new BaseType (); @@ -55,8 +55,8 @@ static void TestCallOnBase () } [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestCallOnOverride () { var tmp = new TypeWhichOverridesMethod (); @@ -64,8 +64,8 @@ static void TestCallOnOverride () } [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestCallOnOverrideViaBase () { BaseType tmp = new TypeWhichOverridesMethod (); @@ -73,11 +73,11 @@ static void TestCallOnOverrideViaBase () } [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TypeWhichOverridesMethod.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWhichOverridesMethod.VirtualMethodRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TypeWhichOverridesMethod.VirtualMethodRequires--", Tool.NativeAot, "")] static void TestDirectReflectionAccess () { BaseType tmp = new TypeWhichOverridesMethod (); @@ -90,11 +90,11 @@ static void TestDirectReflectionAccess () } [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--BaseType.VirtualMethodRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--BaseType.VirtualMethodRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--TypeWhichOverridesMethod.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--TypeWhichOverridesMethod.VirtualMethodRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--TypeWhichOverridesMethod.VirtualMethodRequires--", Tool.NativeAot, "")] static void TestAnnotatedReflectionAccess() { CallMethodWithRequiresOnInstance(new TypeWhichOverridesMethod ()); @@ -133,8 +133,8 @@ public override int VirtualPropertyRequires { } [ExpectedWarning ("IL2026", "--PropertyBaseType.VirtualPropertyRequires--")] - [ExpectedWarning ("IL3002", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--PropertyBaseType.VirtualPropertyRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--PropertyBaseType.VirtualPropertyRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--PropertyBaseType.VirtualPropertyRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void CallOnDerived () { var tmp = new TypeWhichOverridesProperty (); @@ -171,8 +171,8 @@ public void MethodWithRequires () } [ExpectedWarning ("IL2026", "--IRequires.MethodWithRequires--")] - [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--IRequires.MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--IRequires.MethodWithRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void TestCallViaInterface () { IRequires inst = new ImplementationClass (); @@ -180,8 +180,8 @@ static void TestCallViaInterface () } [ExpectedWarning ("IL2026", "--ImplementationClass.RequiresMethod--")] - [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", Tool.Analyzer | Tool.NativeAot, "")] static void TestCallViaImplementationClass () { ImplementationClass inst = new ImplementationClass (); @@ -189,8 +189,8 @@ static void TestCallViaImplementationClass () } [ExpectedWarning ("IL2026", "--ImplementationClass.RequiresMethod--")] - [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", Tool.NativeAot, "")] static void TestDirectReflectionAccess () { typeof (ImplementationClass).GetMethod ("MethodWithRequires").Invoke (new ImplementationClass (), Array.Empty ()); @@ -202,8 +202,8 @@ static void TestDirectReflectionAccess () } [ExpectedWarning ("IL2026", "--ImplementationClass.RequiresMethod--")] - [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--ImplementationClass.RequiresMethod--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--ImplementationClass.RequiresMethod--", Tool.NativeAot, "")] static void TestAnnotatedReflectionAccess () { CallMethodWithRequiresOnInstance (new ImplementationClass ()); @@ -240,8 +240,8 @@ public override DerivedReturnType GetRequires () } [ExpectedWarning ("IL2026", "--CovariantReturnDerived.GetRequires--")] - [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--CovariantReturnDerived.GetRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--CovariantReturnDerived.GetRequires--", Tool.Analyzer | Tool.NativeAot, "")] static void CallOnDerived () { var tmp = new CovariantReturnDerived (); @@ -276,8 +276,8 @@ public override DerivedReturnType GetRequires () } [ExpectedWarning ("IL2026", "--CovariantReturnViaLdftn.Derived.GetRequires--")] - [ExpectedWarning ("IL3002", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--CovariantReturnViaLdftn.Derived.GetRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--CovariantReturnViaLdftn.Derived.GetRequires--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--CovariantReturnViaLdftn.Derived.GetRequires--", Tool.Analyzer | Tool.NativeAot, "")] public static void Test () { var tmp = new Derived (); @@ -305,12 +305,12 @@ public virtual void RUCMethod () { } [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Base.RUCMethod--")] // Reflection triggered warnings are not produced by analyzer for RDC/RAS - [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Base.RUCMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Base.RUCMethod--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Base.RUCMethod--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "Message for --NewSlotVirtual.Derived.RUCMethod--")] // Reflection triggered warnings are not produced by analyzer for RDC/RAS - [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Derived.RUCMethod--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "Message for --NewSlotVirtual.Derived.RUCMethod--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "Message for --NewSlotVirtual.Derived.RUCMethod--", Tool.NativeAot, "")] public static void Test () { typeof (Derived).RequiresPublicMethods (); @@ -343,11 +343,11 @@ public static void AbstractMethod () { } } [ExpectedWarning ("IL2026", "--StaticInterfaces.IRequires.VirtualMethod--")] - [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.VirtualMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.VirtualMethod--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.VirtualMethod--", Tool.Analyzer | Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--StaticInterfaces.IRequires.AbstractMethod--")] - [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.AbstractMethod--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--StaticInterfaces.IRequires.AbstractMethod--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--StaticInterfaces.IRequires.AbstractMethod--", Tool.Analyzer | Tool.NativeAot, "")] static void UseRequiresMethods () where T : IRequires { T.AbstractMethod (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs index bec62cf5dbc49c..36720cf6a486c6 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs @@ -60,11 +60,11 @@ public override void VirtualMethodRequires () } [ExpectedWarning ("IL2026", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--")] - [ExpectedWarning ("IL3002", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--", Tool.NativeAot, "")] static void TestOverriddenVirtualMethod () { MethodWithAnnotatedParameter (typeof (TypeWhichOverridesMethod)); @@ -93,8 +93,8 @@ public TypeWithPublicMethods () { } } [ExpectedWarning ("IL2026", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")] - [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", Tool.NativeAot, "")] static void TestAccessOnGenericType () { new TypeWithPublicMethods (); @@ -103,8 +103,8 @@ static void TestAccessOnGenericType () static void MethodWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { } [ExpectedWarning ("IL2026", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")] - [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", Tool.NativeAot, "")] static void TestAccessOnGenericMethod () { MethodWithPublicMethods (); @@ -113,8 +113,8 @@ static void TestAccessOnGenericMethod () static void MethodWithPublicMethodsInference<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> (T instance) { } [ExpectedWarning ("IL2026", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--")] - [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--AccessedThroughGenericParameterAnnotation.TypeWithRequiresMethod.MethodWhichRequires--", Tool.NativeAot, "")] static void TestAccessOnGenericMethodWithInferenceOnMethod () { MethodWithPublicMethodsInference (new TypeWithRequiresMethod ()); @@ -138,9 +138,9 @@ static void RequiresInDynamicDependency () } // https://github.com/dotnet/runtime/issues/83080 - Analyzer doesn't recognize DynamicDependency in any way - [ExpectedWarning ("IL2026", "--RequiresInDynamicDependency--", ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL3002", "--RequiresInDynamicDependency--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--RequiresInDynamicDependency--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL2026", "--RequiresInDynamicDependency--", Tool.Trimmer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3002", "--RequiresInDynamicDependency--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--RequiresInDynamicDependency--", Tool.NativeAot, "")] [DynamicDependency ("RequiresInDynamicDependency")] public static void Test () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaXml.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaXml.cs index ab0ecd81cab7ed..eb0c4fcde0a1af 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaXml.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaXml.cs @@ -17,7 +17,7 @@ class RequiresViaXml // The second attribute is added through link attribute XML [RequiresUnreferencedCode ("Message for --MethodWithDuplicateRequiresAttribute--")] - [ExpectedWarning ("IL2027", "RequiresUnreferencedCodeAttribute", nameof (MethodWithDuplicateRequiresAttribute), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2027", "RequiresUnreferencedCodeAttribute", nameof (MethodWithDuplicateRequiresAttribute), Tool.Trimmer, "")] static void MethodWithDuplicateRequiresAttribute () { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs index 91485b261a5fdc..e935d941878588 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs @@ -29,11 +29,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability class RequiresWithCopyAssembly { [ExpectedWarning ("IL2026", "--IDerivedInterface.MethodInDerivedInterface--")] - [ExpectedWarning ("IL3002", "--IDerivedInterface.MethodInDerivedInterface--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--IDerivedInterface.MethodInDerivedInterface--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--IDerivedInterface.MethodInDerivedInterface--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--IDerivedInterface.MethodInDerivedInterface--", Tool.NativeAot, "")] [ExpectedWarning ("IL2026", "--IBaseInterface.MethodInBaseInterface--")] - [ExpectedWarning ("IL3002", "--IBaseInterface.MethodInBaseInterface--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--IBaseInterface.MethodInBaseInterface--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--IBaseInterface.MethodInBaseInterface--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--IBaseInterface.MethodInBaseInterface--", Tool.NativeAot, "")] public static void Main () { TestRequiresInMethodFromCopiedAssembly (); @@ -42,8 +42,8 @@ public static void Main () } [ExpectedWarning ("IL2026", "--Method--")] - [ExpectedWarning ("IL3002", "--Method--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--Method--", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--Method--", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--Method--", Tool.Analyzer | Tool.NativeAot, "")] static void TestRequiresInMethodFromCopiedAssembly () { var tmp = new RequiresInCopyAssembly (); @@ -51,8 +51,8 @@ static void TestRequiresInMethodFromCopiedAssembly () } [ExpectedWarning ("IL2026", "--MethodCalledThroughReflection--")] - [ExpectedWarning ("IL3002", "--MethodCalledThroughReflection--", ProducedBy = Tool.NativeAot)] - [ExpectedWarning ("IL3050", "--MethodCalledThroughReflection--", ProducedBy = Tool.NativeAot)] + [ExpectedWarning ("IL3002", "--MethodCalledThroughReflection--", Tool.NativeAot, "")] + [ExpectedWarning ("IL3050", "--MethodCalledThroughReflection--", Tool.NativeAot, "")] static void TestRequiresThroughReflectionInMethodFromCopiedAssembly () { typeof (RequiresInCopyAssembly) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/SingleFile/SingleFileIntrinsics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/SingleFile/SingleFileIntrinsics.cs index 5273af0230c104..617e286e1e641d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/SingleFile/SingleFileIntrinsics.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/SingleFile/SingleFileIntrinsics.cs @@ -27,7 +27,7 @@ public static void Main () TestAssemblyGetFilesSuppressedByRAF (); } - [ExpectedWarning("IL3000", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning("IL3000", Tool.Analyzer | Tool.NativeAot, "")] static void TestAssemblyLocation() { var a = typeof (SingleFileIntrinsics).Assembly.Location; @@ -39,7 +39,7 @@ static void TestAssemblyLocationSuppressedByRAF() var a = typeof (SingleFileIntrinsics).Assembly.Location; } - [ExpectedWarning ("IL3000", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3000", Tool.Analyzer | Tool.NativeAot, "")] static void TestAssemblyNameCodeBase() { var a = typeof (SingleFileIntrinsics).Assembly.GetName ().CodeBase; @@ -51,7 +51,7 @@ static void TestAssemblyNameCodeBaseSuppressedByRAF () var a = typeof (SingleFileIntrinsics).Assembly.GetName ().CodeBase; } - [ExpectedWarning ("IL3000", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3000", Tool.Analyzer | Tool.NativeAot, "")] static void TestAssemblyNameEscapedCodeBase () { var a = typeof (SingleFileIntrinsics).Assembly.GetName ().EscapedCodeBase; @@ -63,7 +63,7 @@ static void TestAssemblyNameEscapedCodeBaseSuppressedByRAF () var a = typeof (SingleFileIntrinsics).Assembly.GetName ().EscapedCodeBase; } - [ExpectedWarning ("IL3001", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3001", Tool.Analyzer | Tool.NativeAot, "")] static void TestAssemblyGetFile() { var a = typeof (SingleFileIntrinsics).Assembly.GetFile ("unknown"); @@ -75,8 +75,8 @@ static void TestAssemblyGetFileSuppressedByRAF () var a = typeof (SingleFileIntrinsics).Assembly.GetFile ("unknown"); } - [ExpectedWarning ("IL3001", ProducedBy = Tool.Analyzer | Tool.NativeAot)] - [ExpectedWarning ("IL3001", ProducedBy = Tool.Analyzer | Tool.NativeAot)] + [ExpectedWarning ("IL3001", Tool.Analyzer | Tool.NativeAot, "")] + [ExpectedWarning ("IL3001", Tool.Analyzer | Tool.NativeAot, "")] static void TestAssemblyGetFiles () { var a = typeof (SingleFileIntrinsics).Assembly.GetFiles (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs index e34f2b4bbfd3fc..b4723f3505437f 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutions.cs @@ -93,8 +93,8 @@ static void TestGuardAssemblyFiles () RequiresAssemblyFiles (); } - [ExpectedWarning ("IL4000", nameof (RequiresDynamicCodeAttribute), ProducedBy = Tool.Analyzer)] - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresDynamicCodeAttribute), Tool.Analyzer, "")] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureGuard (typeof (RequiresDynamicCodeAttribute))] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool GuardDynamicCodeAndUnreferencedCode => RuntimeFeature.IsDynamicCodeSupported && TestFeatures.IsUnreferencedCodeSupported; @@ -152,7 +152,7 @@ static void TestIndirectGuard () [FeatureSwitchDefinition ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.DefineFeatureGuard.FeatureSwitch")] static bool FeatureSwitch => AppContext.TryGetSwitch ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.DefineFeatureGuard.FeatureSwitch", out bool isEnabled) && isEnabled; - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer)] // Analyzer doesn't respect FeatureSwitchDefinition or feature settings + [ExpectedWarning ("IL2026", Tool.Analyzer, "")] // Analyzer doesn't respect FeatureSwitchDefinition or feature settings [ExpectedInstructionSequence (new[] { "nop", "ldc.i4.0", @@ -169,7 +169,7 @@ static void TestFeatureSwitch () RequiresUnreferencedCode (); } - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureSwitchDefinition ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.DefineFeatureGuard.FeatureSwitchAndGuard")] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool FeatureSwitchAndGuard => AppContext.TryGetSwitch ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.DefineFeatureGuard.FeatureSwitchAndGuard", out bool isEnabled) && isEnabled; @@ -264,7 +264,7 @@ public static void Test () [Kept] class FeatureGuardPrecedence { - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureSwitchDefinition ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.FeatureGuardPrecedence.GuardAndSwitch")] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool GuardAndSwitch => AppContext.TryGetSwitch ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.FeatureGuardPrecedence.GuardAndSwitch", out bool isEnabled) && isEnabled; @@ -281,7 +281,7 @@ class FeatureGuardPrecedence { "ret" })] // ILLink/ILCompiler ignore FeatureGuard on properties that also have FeatureSwitchDefinition - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "")] static void TestSwitchWinsOverGuard () { if (GuardAndSwitch) @@ -291,7 +291,7 @@ static void TestSwitchWinsOverGuard () [Kept] [KeptAttributeAttribute (typeof (FeatureSwitchDefinitionAttribute))] [KeptAttributeAttribute (typeof (FeatureGuardAttribute))] - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureSwitchDefinition ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.FeatureGuardPrecedence.GuardAndSwitchNotSet")] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool GuardAndSwitchNotSet { @@ -301,7 +301,7 @@ static bool GuardAndSwitchNotSet { [Kept] // No IL modifications because feature is not set, and FeatureGuard is ignored due to FeatureSwitchDefinition. - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "")] static void TestSwitchNotSetWinsOverGuard () { if (GuardAndSwitchNotSet) @@ -322,7 +322,7 @@ static void TestSwitchNotSetWinsOverGuard () "nop", "ret" })] - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "")] static void TestXmlWinsOverGuard () { if (GuardWithXml) @@ -331,7 +331,7 @@ static void TestXmlWinsOverGuard () [KeptAttributeAttribute (typeof (FeatureSwitchDefinitionAttribute))] [KeptAttributeAttribute (typeof (FeatureGuardAttribute))] - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureSwitchDefinition ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.FeatureGuardPrecedence.SwitchWithXml")] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool SwitchWithXml => AppContext.TryGetSwitch ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.FeatureGuardPrecedence.SwitchWithXml", out bool isEnabled) && isEnabled; @@ -348,7 +348,7 @@ static void TestXmlWinsOverGuard () "nop", "ret" })] - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "")] static void TestXmlWinsOverSwitch () { if (SwitchWithXml) RequiresUnreferencedCode (); @@ -356,7 +356,7 @@ static void TestXmlWinsOverSwitch () { [KeptAttributeAttribute (typeof (FeatureSwitchDefinitionAttribute))] [KeptAttributeAttribute (typeof (FeatureGuardAttribute))] - [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", nameof (RequiresUnreferencedCodeAttribute), Tool.Analyzer, "")] [FeatureSwitchDefinition ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardPrecedence.GuardAndSwitchWithXml")] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool GuardAndSwitchWithXml => AppContext.TryGetSwitch ("Mono.Linker.Tests.Cases.Substitutions.FeatureGuardSubstitutions.FeatureGuardPrecedence.GuardAndSwitchWithXml", out bool isEnabled) && isEnabled; @@ -373,7 +373,7 @@ static void TestXmlWinsOverSwitch () { "nop", "ret" })] - [ExpectedWarning ("IL2026", ProducedBy = Tool.Trimmer | Tool.NativeAot)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "")] static void TestXmlWinsOverGuardAndSwitch () { if (GuardAndSwitchWithXml) RequiresUnreferencedCode (); diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs index 198595d79394df..725f849d9093c2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/FeatureGuardSubstitutionsDisabled.cs @@ -25,7 +25,7 @@ public static void Main () } [Kept] - [ExpectedWarning ("IL4000", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL4000", Tool.Analyzer, "")] [KeptAttributeAttribute (typeof (FeatureGuardAttribute))] [FeatureGuard (typeof (RequiresUnreferencedCodeAttribute))] static bool GuardUnreferencedCode { @@ -46,7 +46,7 @@ static void TestGuard () static bool FeatureSwitch => throw null; [Kept] - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", Tool.Analyzer, "")] // Feature switches are still substituted when feature guard substitutions are disabled [ExpectBodyModified] static void TestFeatureSwitch () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/ResourceSubstitutions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/ResourceSubstitutions.cs index 9bdf9075dae9bc..d52432adfb10db 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/ResourceSubstitutions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Substitutions/ResourceSubstitutions.cs @@ -15,4 +15,4 @@ public static void Main () { } } -} \ No newline at end of file +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersRewrite.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersRewrite.cs index 240f365439954a..4ed5061aa4988e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersRewrite.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/TypeForwardersRewrite.cs @@ -21,7 +21,7 @@ unsafe class TypeForwardersRewrite { static void Main () { -#if NETCOREAPP +#if NET Test (null); #endif Test2 (null); @@ -56,7 +56,7 @@ static void Main () [KeptMember ("Invoke()")] delegate C D (); -#if NETCOREAPP +#if NET [Kept] static void Test (delegate* arg) { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs index ea7d62c5fb7daf..68714608fcca98 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/ComplexConditions.cs @@ -17,7 +17,7 @@ public static void Main () } [Kept] -#if !NETCOREAPP +#if !NET [ExpectBodyModified] #else [ExpectedInstructionSequence (new[] { @@ -50,7 +50,7 @@ static void Test_1 (object type) } [Kept] -#if !NETCOREAPP +#if !NET [ExpectBodyModified] #else [ExpectedInstructionSequence (new[] { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs index 0e0c1ef2a33556..230b7e4e9ba02b 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBlock/SizeOfInConditions.cs @@ -4,7 +4,7 @@ namespace Mono.Linker.Tests.Cases.UnreachableBlock { -#if NETCOREAPP +#if NET [SetupLinkerSubstitutionFile ("SizeOfInConditions.netcore.xml")] #else [SetupLinkerSubstitutionFile ("SizeOfInConditions.net_4_x.xml")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs index 9c9ae70e6dc1b2..0da48a31799df5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibrary.cs @@ -4,7 +4,7 @@ namespace Mono.Linker.Tests.Cases.UnreachableBody { -#if NETCOREAPP +#if NET [SetupLinkerArgument ("-a", "other2.dll")] #else [SetupLinkerArgument ("-r", "other2")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs index 852c9351af12bc..9cdfe5cb72f1d3 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/UnreachableBody/LinkedOtherIncludedLibraryNoInstanceCtor.cs @@ -5,7 +5,7 @@ namespace Mono.Linker.Tests.Cases.UnreachableBody { [SetupLinkerArgument ("--skip-unresolved", "true")] [Define ("OTHER_INCLUDED")] -#if NETCOREAPP +#if NET [SetupLinkerArgument ("-a", "other.dll", "visible")] #else [SetupLinkerArgument ("-r", "other")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs index 4bb2c22213bffe..afe1832a0013db 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileCSharp.cs @@ -8,7 +8,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.Individual { [SetupLinkerTrimMode ("skip")] -#if !NETCOREAPP +#if !NET [Reference ("System.Core.dll")] [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] #else diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs index 47d1c929435de7..e11f941e23f888 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/CanGenerateWarningSuppressionFileXml.cs @@ -5,7 +5,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.Individual { [SetupLinkerTrimMode ("skip")] -#if !NETCOREAPP +#if !NET [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] #else [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) })] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs index c39f6a9028ce53..10cd9d58982d77 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/Individual/WarningsAreSorted.cs @@ -12,7 +12,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.Individual { [SkipRemainingErrorsValidation] [SetupLinkerTrimMode ("skip")] -#if !NETCOREAPP +#if !NET [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) }, new[] { "System.Core.dll" })] #else [SetupCompileBefore ("library.dll", new[] { typeof (TriggerWarnings_Lib) })] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFeatureSubstitutions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFeatureSubstitutions.cs index 2f271f000919f2..ac8cf603419363 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFeatureSubstitutions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFeatureSubstitutions.cs @@ -43,7 +43,7 @@ class ReportRedundantSuppressionWhenTrimmerIncompatibleCodeDisabled // With feature switched to false, the trimming tools see only the 'else' branch. // The 'else' branch contains trimmer-compatible code, the trimming tools identifies the suppression as redundant. - [ExpectedWarning ("IL2121", "IL2072", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2072", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2072")] public static void Test () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFromXML.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFromXML.cs index 4d669f696fc225..aab9f007288864 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFromXML.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsFromXML.cs @@ -8,8 +8,8 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { [SkipKeptItemsValidation] [ExpectedNoWarnings] - [ExpectedWarning ("IL2121", "IL2026", ProducedBy = Tool.Trimmer, FileName = "DetectRedundantSuppressionsFromXML.xml", SourceLine = 7)] - [ExpectedWarning ("IL2121", "IL2109", ProducedBy = Tool.Trimmer, FileName = "DetectRedundantSuppressionsFromXML.xml", SourceLine = 12)] + [ExpectedWarning ("IL2121", "IL2026", Tool.Trimmer, "", FileName = "DetectRedundantSuppressionsFromXML.xml", SourceLine = 7)] + [ExpectedWarning ("IL2121", "IL2109", Tool.Trimmer, "", FileName = "DetectRedundantSuppressionsFromXML.xml", SourceLine = 12)] [SetupLinkAttributesFile ("DetectRedundantSuppressionsFromXML.xml")] public class DetectRedundantSuppressionsFromXML { @@ -32,4 +32,4 @@ static void DoNotTriggerWarning () { } class DoNotTriggerWarningType { } } } -} \ No newline at end of file +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInAssembly.cs index b1b985278a0a56..38995365302402 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInAssembly.cs @@ -4,7 +4,7 @@ using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; -[assembly: ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] +[assembly: ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [assembly: UnconditionalSuppressMessage ("Test", "IL2071:Redundant suppression, warning is not issued in this assembly")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInCompilerGeneratedCode.cs index a707584bef3655..54082fccd74e5a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInCompilerGeneratedCode.cs @@ -34,7 +34,7 @@ public class RedundantSuppressionOnLocalMethod { public static void Test () { - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] void LocalMethod () { @@ -52,7 +52,7 @@ public static void Test () Enumerable (); } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] static IEnumerable Enumerable () { @@ -63,7 +63,7 @@ static IEnumerable Enumerable () public class RedundantSuppressionInAsyncBody { - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public static async void Test () { @@ -71,7 +71,7 @@ public static async void Test () await MethodAsync (); } - [ExpectedWarning ("IL2121", "IL2070", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2070", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2070")] static async Task MethodAsync () { diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypes.cs index 56998d29aee59a..884ceb4a6c81b5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypes.cs @@ -50,7 +50,7 @@ public static string TrimmerCompatibleMethod () return "test"; } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public class RedundantSuppressionOnType { @@ -62,7 +62,7 @@ public static void Test () public class RedundantSuppressionOnMethod { - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public static void Test () { @@ -77,7 +77,7 @@ public static void Test () NestedType.TrimmerCompatibleMethod (); } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public class NestedType { @@ -96,7 +96,7 @@ public static void Test () } public static string TrimmerCompatibleProperty { - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] get { return TrimmerCompatibleMethod (); @@ -112,7 +112,7 @@ public static void Test () TrimmerCompatibleProperty = "test"; } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public static string TrimmerCompatibleProperty { get { @@ -131,7 +131,7 @@ public static void Test () var property = TrimmerCompatibleProperty; } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public static string TrimmerCompatibleProperty { get { @@ -147,7 +147,7 @@ public static void Test () TrimmerCompatibleProperty = "test"; } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public static string TrimmerCompatibleProperty { set { @@ -163,7 +163,7 @@ public static void Test () typeof (RedundantSuppressionOnPropertyAccessedByReflection).GetProperty ("TrimmerCompatibleProperty"); } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public static string TrimmerCompatibleProperty { get { @@ -185,7 +185,7 @@ static void EventSubscriber (object sender, EventArgs e) } public static event EventHandler TrimmerCompatibleEvent { - [ExpectedWarning ("IL2121", "IL2072", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2072", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2072")] add { TrimmerCompatibleMethod (); } remove { } @@ -204,7 +204,7 @@ static void EventSubscriber (object sender, EventArgs e) } - [ExpectedWarning ("IL2121", "IL2072", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2072", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2072")] public static event EventHandler TrimmerCompatibleEvent { add { TrimmerCompatibleMethod (); } @@ -219,7 +219,7 @@ public static void Test () typeof (RedundantSuppressionOnEventAccessedByReflection).GetEvent ("TrimmerCompatibleEvent"); } - [ExpectedWarning ("IL2121", "IL2072", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2072", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2072")] public static event EventHandler TrimmerCompatibleEvent { add { TrimmerCompatibleMethod (); } @@ -227,15 +227,15 @@ public static event EventHandler TrimmerCompatibleEvent { } } - [ExpectedWarning ("IL2121", "IL2072", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2072", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2072")] - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public class MultipleRedundantSuppressions { - [ExpectedWarning ("IL2121", "IL2072", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2072", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2072")] - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] public static void Test () { @@ -245,7 +245,7 @@ public static void Test () public class RedundantAndUsedSuppressions { - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2071")] [UnconditionalSuppressMessage ("Test", "IL2072")] public static void Test () @@ -317,7 +317,7 @@ public static void Test () MethodMarkedRUC (); } - [ExpectedWarning ("IL2121", "IL2072", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2072", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2072")] [RequiresUnreferencedCode ("Test")] public static void MethodMarkedRUC () diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypesUsingTarget.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypesUsingTarget.cs index 5991e418197f08..6b6c3df46f5bf2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypesUsingTarget.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInMembersAndTypesUsingTarget.cs @@ -37,7 +37,7 @@ public static string TrimmerCompatibleMethod () return "test"; } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] public class RedundantSuppressionOnType { public static void Test () @@ -48,7 +48,7 @@ public static void Test () public class RedundantSuppressionOnMethod { - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] public static void Test () { TrimmerCompatibleMethod (); @@ -62,7 +62,7 @@ public static void Test () NestedType.TrimmerCompatibleMethod (); } - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] public class NestedType { public static void TrimmerCompatibleMethod () @@ -80,7 +80,7 @@ public static void Test () } public static string TrimmerCompatibleProperty { - [ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] get { return TrimmerCompatibleMethod (); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInModule.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInModule.cs index 9dc15690107d39..da7717bc6c14b7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInModule.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/DetectRedundantSuppressionsInModule.cs @@ -4,7 +4,7 @@ using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; -[assembly: ExpectedWarning ("IL2121", "IL2071", ProducedBy = Tool.Trimmer)] +[assembly: ExpectedWarning ("IL2121", "IL2071", Tool.Trimmer, "")] [module: UnconditionalSuppressMessage ("Test", "IL2071:Redundant suppression, warning is not issued in this assembly")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs index c9e88bdf6a729c..63b0c109c17987 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInAssembly.cs @@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { -#if !NETCOREAPP +#if !NET [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] #endif [SkipKeptItemsValidation] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs index 5e3d6023c3b1fa..8506a09edb66c6 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs @@ -278,7 +278,7 @@ static void TestCallRUCMethodInLtftnLocalFunction () class DynamicallyAccessedLocalFunction { - [ExpectedWarning ("IL2118", "LocalFunction", ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", "LocalFunction", Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2026")] public static void TestCallRUCMethodInDynamicallyAccessedLocalFunction () { @@ -426,7 +426,7 @@ static void TestGenericTypeParameterRequirement () class DynamicallyAccessedLambda { - [ExpectedWarning ("IL2118", nameof (TestCallRUCMethodInDynamicallyAccessedLambda), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", nameof (TestCallRUCMethodInDynamicallyAccessedLambda), Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2026")] public static void TestCallRUCMethodInDynamicallyAccessedLambda () { @@ -440,7 +440,7 @@ public static void TestCallRUCMethodInDynamicallyAccessedLambda () class DynamicallyAccessedLambdaUnused { - [ExpectedWarning ("IL2118", nameof (TestCallRUCMethodInDynamicallyAccessedLambda), ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2118", nameof (TestCallRUCMethodInDynamicallyAccessedLambda), Tool.Trimmer, "")] [UnconditionalSuppressMessage ("Test", "IL2026")] public static void TestCallRUCMethodInDynamicallyAccessedLambda () { @@ -454,7 +454,7 @@ static void TestSuppressionOnLambda () { var lambda = // https://github.com/dotnet/roslyn/issues/59746 - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", Tool.Analyzer, "")] [UnconditionalSuppressMessage ("Test", "IL2026")] () => RequiresUnreferencedCodeMethod (); @@ -466,7 +466,7 @@ static void TestSuppressionOnOuterAndLambda () { var lambda = // https://github.com/dotnet/roslyn/issues/59746 - [ExpectedWarning ("IL2026", ProducedBy = Tool.Analyzer)] + [ExpectedWarning ("IL2026", Tool.Analyzer, "")] [UnconditionalSuppressMessage ("Test", "IL2026")] (Type unknownType) => { RequiresUnreferencedCodeMethod (); @@ -577,8 +577,8 @@ static IEnumerable TestDynamicallyAccessedMethodViaGenericMethodParameterIn static event EventHandler TestEvent; // https://github.com/dotnet/runtime/issues/82956 - the suppression is ignored - [ExpectedWarning ("IL2026", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer | Tool.NativeAot)] - [ExpectedWarning ("IL2121", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2026", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2121", Tool.Trimmer, "", CompilerGeneratedCode = true)] static void TestLambdaInLocalFunction () { LocalFunction (); @@ -595,7 +595,7 @@ void LocalFunction () // https://github.com/dotnet/runtime/issues/82956 - the suppression is ignored // https://github.com/dotnet/roslyn/issues/59746 [ExpectedWarning ("IL2026", CompilerGeneratedCode = true)] - [ExpectedWarning ("IL2121", CompilerGeneratedCode = true, ProducedBy = Tool.Trimmer)] + [ExpectedWarning ("IL2121", Tool.Trimmer, "", CompilerGeneratedCode = true)] static void TestLocalFunctionInLambda () { TestEvent += diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs index a4e0082b3b5ef6..8985bc61897541 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCopyAssembly.cs @@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { -#if !NETCOREAPP +#if !NET [Reference ("System.Core.dll")] #endif [SetupLinkerAction ("copy", "test")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs index 596b7d2cf62f9d..8287c0caddb7ee 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypes.cs @@ -6,7 +6,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { -#if !NETCOREAPP +#if !NET [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] #endif [SkipKeptItemsValidation] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs index a0121281c2494f..d00ac7d68fb484 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInMembersAndTypesUsingTarget.cs @@ -12,7 +12,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { -#if !NETCOREAPP +#if !NET [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] #endif [SkipKeptItemsValidation] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs index 8273e453bc8f1b..9906cecac482cb 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInModule.cs @@ -9,7 +9,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression { -#if !NETCOREAPP +#if !NET [Mono.Linker.Tests.Cases.Expectations.Metadata.Reference ("System.Core.dll")] #endif [SkipKeptItemsValidation] diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCases/TestSuites.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCases/TestSuites.cs index fd25f5cc8cef97..a05e68b17bd468 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCases/TestSuites.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCases/TestSuites.cs @@ -52,7 +52,7 @@ public void CodegenAnnotationTests (TestCase testCase) if (Environment.OSVersion.Platform == PlatformID.Win32NT) Assert.Ignore ("These tests are not valid when trimming .NET Framework"); -#if NETCOREAPP +#if NET Assert.Ignore ("These tests are not valid when trimming .NET Core"); #endif Run (testCase); diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs index 7b5835d2b0fc4f..bff5b87a995088 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs @@ -49,7 +49,7 @@ protected virtual void SetupProcess (Process process, CompilerOptions options) private static string BuildArguments (CompilerOptions options) { var args = new StringBuilder (); -#if NETCOREAPP +#if NET args.Append (options.OutputPath.ExtensionWithDot == ".dll" ? "-dll" : "-exe"); args.Append ($" -out:{options.OutputPath.InQuotes ()}"); #else @@ -62,7 +62,7 @@ private static string BuildArguments (CompilerOptions options) protected virtual NPath LocateIlasm () { -#if NETCOREAPP +#if NET var extension = RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? ".exe" : ""; var toolsDir = (string)AppContext.GetData("Mono.Linker.Tests.ILToolsDir")!; diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 2f05eab1e4c666..8b4dd418554a5a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -223,7 +223,7 @@ void VerifyExitCode (TrimmedTestCaseResult linkResult, AssemblyDefinition origin Assert.AreEqual (expectedExitCode, linkResult.ExitCode, $"Expected exit code {expectedExitCode} but got {linkResult.ExitCode}. Output was:\n{FormatLinkerOutput()}"); } else { if (linkResult.ExitCode != 0) { - Assert.Fail($"Linker exited with an unexpected non-zero exit code of {linkResult.ExitCode} and output:\n{FormatLinkerOutput()}"); + Assert.Fail ($"Linker exited with an unexpected non-zero exit code of {linkResult.ExitCode} and output:\n{FormatLinkerOutput()}"); } } @@ -734,6 +734,9 @@ void VerifyKeptAllTypesAndMembersInAssembly (AssemblyDefinition linked) static bool IsProducedByLinker (CustomAttribute attr) { + if (attr.Constructor.Parameters.Count > 2 && attr.ConstructorArguments[^2].Type.Name == "Tool") { + return ((Tool)attr.ConstructorArguments[^2].Value).HasFlag (Tool.Trimmer) == true; + } var producedBy = attr.GetPropertyValue ("ProducedBy"); return producedBy is null ? true : ((Tool) producedBy).HasFlag (Tool.Trimmer); } @@ -794,12 +797,29 @@ void VerifyLoggedMessages (AssemblyDefinition original, TrimmingTestLogger logge } break; - case nameof (ExpectedWarningAttribute): { + case nameof (ExpectedWarningAttribute) or nameof(UnexpectedWarningAttribute): { var expectedWarningCode = (string) attr.GetConstructorArgumentValue (0); if (!expectedWarningCode.StartsWith ("IL")) { - Assert.Fail ($"The warning code specified in {nameof (ExpectedWarningAttribute)} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'."); + Assert.Fail ($"The warning code specified in {attr.AttributeType.Name} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'."); } - var expectedMessageContains = ((CustomAttributeArgument[]) attr.GetConstructorArgumentValue (1)).Select (a => (string) a.Value).ToArray (); + IEnumerable expectedMessageContains = attr.Constructor.Parameters switch + { + // ExpectedWarningAttribute(string warningCode, params string[] expectedMessages) + // ExpectedWarningAttribute(string warningCode, string[] expectedMessages, Tool producedBy, string issueLink) + [_, { ParameterType.IsArray: true }, ..] + => ((CustomAttributeArgument[])attr.ConstructorArguments[1].Value) + .Select(caa => (string)caa.Value), + // ExpectedWarningAttribute(string warningCode, string expectedMessage1, string expectedMessage2, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "String" }, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] + => [(string)attr.GetConstructorArgumentValue(1), (string)attr.GetConstructorArgumentValue(2)], + // ExpectedWarningAttribute(string warningCode, string expectedMessage, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "String" }, { ParameterType.Name: "Tool" }, _] + => [(string)attr.GetConstructorArgumentValue(1)], + // ExpectedWarningAttribute(string warningCode, Tool producedBy, string issueLink) + [_, { ParameterType.Name: "Tool" }, _] + => [], + _ => throw new UnreachableException(), + }; string fileName = (string) attr.GetPropertyValue ("FileName"); int? sourceLine = (int?) attr.GetPropertyValue ("SourceLine"); int? sourceColumn = (int?) attr.GetPropertyValue ("SourceColumn"); diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs index c26e833d9e9f3a..fe25e06dd2c7a1 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs @@ -76,7 +76,7 @@ public virtual IEnumerable GetDefines () yield return "WIN32"; if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) - yield return "NETCOREAPP"; + yield return "NET"; if (Characteristics.HasFlag (TestRunCharacteristics.SupportsDefaultInterfaceMethods)) yield return "SUPPORTS_DEFAULT_INTERFACE_METHODS"; diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs index ec427ebdbc4858..89c202e472c05a 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs @@ -9,7 +9,7 @@ using System.Text; using Mono.Linker.Tests.Extensions; using NUnit.Framework; -#if NETCOREAPP +#if NET using System.Runtime.InteropServices; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Emit; @@ -190,7 +190,7 @@ protected static NPath MakeSupportingAssemblyReferencePathAbsolute (NPath output if (Path.IsPathRooted (referenceFileName)) return referenceFileName.ToNPath (); -#if NETCOREAPP +#if NET if (referenceFileName.StartsWith ("System.", StringComparison.Ordinal) || referenceFileName.StartsWith ("Mono.", StringComparison.Ordinal) || referenceFileName.StartsWith ("Microsoft.", StringComparison.Ordinal) || @@ -224,14 +224,14 @@ protected NPath CompileAssembly (CompilerOptions options) protected virtual NPath CompileCSharpAssemblyWithDefaultCompiler (CompilerOptions options) { -#if NETCOREAPP +#if NET return CompileCSharpAssemblyWithRoslyn (options); #else return CompileCSharpAssemblyWithCsc (options); #endif } -#if NETCOREAPP +#if NET protected virtual NPath CompileCSharpAssemblyWithRoslyn (CompilerOptions options) { var languageVersion = LanguageVersion.Preview; @@ -328,7 +328,7 @@ protected virtual NPath CompileCSharpAssemblyWithRoslyn (CompilerOptions options protected virtual NPath CompileCSharpAssemblyWithCsc (CompilerOptions options) { -#if NETCOREAPP +#if NET return CompileCSharpAssemblyWithRoslyn (options); #else return CompileCSharpAssemblyWithExternalCompiler (LocateCscExecutable (), options, "/shared "); diff --git a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs index cdb59e6571130d..8789c404839b48 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/TrimmingArgumentBuilder.cs @@ -66,7 +66,7 @@ public virtual void RootAssemblyEntryPoint (string fileName) public virtual void RootAssemblyVisible (string fileName) { -#if NETCOREAPP +#if NET Append ("-a"); Append (fileName); Append ("visible"); @@ -213,7 +213,7 @@ public virtual void ProcessOptions (TestCaseLinkerOptions options) IgnoreLinkAttributes (options.IgnoreLinkAttributes); -#if !NETCOREAPP +#if !NET if (!string.IsNullOrEmpty (options.Il8n)) AddIl8n (options.Il8n); #endif diff --git a/src/workloads/workloads.csproj b/src/workloads/workloads.csproj index 29669de949b9de..54eb3b3664ff4b 100644 --- a/src/workloads/workloads.csproj +++ b/src/workloads/workloads.csproj @@ -9,9 +9,7 @@ $(ArtifactsObjDir)workloads/ $(WorkloadIntermediateOutputPath)VS/ $(ArtifactsBinDir)workloads/ - $(workloadArtifactsPath)/ $(ArtifactsShippingPackagesDir) - $(workloadPackagesPath)/ false @@ -141,7 +139,7 @@ -