diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index a8fe633290e14c..6d3f2efaf848ce 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.21613.2", + "version": "1.0.0-prerelease.21622.1", "commands": [ "xharness" ] diff --git a/Directory.Build.props b/Directory.Build.props index f149734c7c81f4..0983ba4ae36f89 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -245,6 +245,7 @@ $([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'System.Private.CoreLib', 'src')) $([MSBuild]::NormalizePath('$(CoreClrProjectRoot)', 'System.Private.CoreLib', 'System.Private.CoreLib.csproj')) $([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'System.Private.CoreLib', 'System.Private.CoreLib.csproj')) + $([MSBuild]::NormalizePath('$(CoreClrProjectRoot)', 'nativeaot', 'System.Private.CoreLib', 'src', 'System.Private.CoreLib.csproj')) true diff --git a/docs/workflow/building/libraries/webassembly-instructions.md b/docs/workflow/building/libraries/webassembly-instructions.md index fdc5dc31d22267..3ae2d2f808abfe 100644 --- a/docs/workflow/building/libraries/webassembly-instructions.md +++ b/docs/workflow/building/libraries/webassembly-instructions.md @@ -152,7 +152,7 @@ Submit a PR request with the updated version, wait for all checks to pass and fo { "dockerfile": "src/ubuntu/18.04/webassembly/Dockerfile", "simpleTags": [ - "ubuntu-18.04-webassembly-20200529220811-6a6da63" + "ubuntu-18.04-webassembly-20210707133424-12f133e" ], "digest": "sha256:1f2d920a70bd8d55bbb329e87c3bd732ef930d64ff288dab4af0aa700c25cfaf", "osType": "Linux", @@ -169,7 +169,7 @@ Copy the docker image tag and replace it in [platform-matrix.yml](https://github ``` container: - image: ubuntu-18.04-webassembly-20200409132031-f70ea41 + image: ubuntu-18.04-webassembly-20210707133424-12f133e registry: mcr ``` diff --git a/docs/workflow/testing/libraries/testing-apple.md b/docs/workflow/testing/libraries/testing-apple.md index 0ce42742e9c710..2727fb4b28cd9c 100644 --- a/docs/workflow/testing/libraries/testing-apple.md +++ b/docs/workflow/testing/libraries/testing-apple.md @@ -48,6 +48,10 @@ For example: ``` ./build.sh libs.tests -os iOS -arch x64 -test /p:DevTeamProvisioning=H1A2B3C4D5 ``` +Other possible options are: +- to sign with an adhoc key by setting `/p:DevTeamProvisioning=adhoc` +- to skip signing all together by setting `/p:DevTeamProvisioning=-` . + [AppleAppBuilder](https://github.com/dotnet/runtime/blob/main/src/tasks/AppleAppBuilder/AppleAppBuilder.cs) generates temp Xcode projects you can manually open and resolve provisioning issues there using native UI and deploy to your devices. ### Running individual test suites diff --git a/eng/ApiCompatExcludeAttributes.txt b/eng/ApiCompatExcludeAttributes.txt index 19475f50297f8a..5ea702ad6f3d4a 100644 --- a/eng/ApiCompatExcludeAttributes.txt +++ b/eng/ApiCompatExcludeAttributes.txt @@ -1,3 +1,5 @@ T:System.CLSCompliantAttribute T:System.Diagnostics.CodeAnalysis.MemberNotNullAttribute T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute +T:System.Diagnostics.DebuggerGuidedStepThroughAttribute +T:System.Runtime.CompilerServices.EagerStaticClassConstructionAttribute diff --git a/eng/Subsets.props b/eng/Subsets.props index 22714ffc7d0a88..d8aa6d9fea0fea 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -49,9 +49,12 @@ $(PrimaryRuntimeFlavor) - + true + + + true diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 83ad7ff90ed386..bb600ce856b40f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/icu - d483c01eb69a904062475e49d6b20b8bbbefe64b + d9371f17932fbf828f1d1e2f21a99b64ba40eba5 https://github.com/dotnet/msquic @@ -18,125 +18,125 @@ - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 https://github.com/microsoft/vstest 140434f7109d357d0158ade9e5164a4861513965 - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b https://github.com/dotnet/llvm-project @@ -170,53 +170,53 @@ https://github.com/dotnet/llvm-project 662aff66999c435aec09c58643e9fd703eadc3e0 - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/runtime - 78f4a7de7e89ddefa88f9e9da7604ecb5c58d3b7 + 834b278911962102919b3a7dec22ca6cb26bfa8a - + https://github.com/dotnet/linker - 25323570686848f192bd05e726aff5c91eb0b2f0 + 41467d340a3345f08cb8ba67c20c1ea40c57682f - + https://github.com/dotnet/xharness - d5affc0d0361de14aa1ccbf5cad268d5873e3113 + 7ad8d01a879af9437a7c33d01409bd761700cdad - + https://github.com/dotnet/xharness - d5affc0d0361de14aa1ccbf5cad268d5873e3113 + 7ad8d01a879af9437a7c33d01409bd761700cdad - + https://github.com/dotnet/arcade - 943d03f62955c771825dfa1f1bdeb8f853a2d7dd + 0cd94b1d02c03377d99f3739beb191591f6abee5 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -234,13 +234,13 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization 91d6b3c1f51888d166701510189505f35714665c - + https://github.com/dotnet/hotreload-utils - 4782fa39c0fb1651890b6b03aef11f7129884eae + f0d838421286fed81005fd4ddf6562555b641b3b - + https://github.com/dotnet/runtime-assets - 658e482c4af9a16cbe9ea0fae4c6e4281f1521b6 + f6e023ee68f858cd020a13dc9dfc13ba6a82b64b https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 22c9796bed7290..d284110deaec40 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -54,30 +54,30 @@ 2.0.0-alpha.1.21525.11 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 2.5.1-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 - 7.0.0-beta.21615.1 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 2.5.1-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 + 7.0.0-beta.21621.3 6.0.0-preview.1.102 - 7.0.0-alpha.1.21612.5 - 7.0.0-alpha.1.21612.5 - 7.0.0-alpha.1.21612.5 + 7.0.0-alpha.1.21620.1 + 7.0.0-alpha.1.21620.1 + 7.0.0-alpha.1.21620.1 3.1.0 - 7.0.0-alpha.1.21612.5 + 7.0.0-alpha.1.21620.1 5.0.0 4.3.0 @@ -112,24 +112,24 @@ 5.0.0 5.0.0 4.9.0-rc2.21473.1 - 7.0.0-alpha.1.21612.5 - 7.0.0-alpha.1.21612.5 + 7.0.0-alpha.1.21620.1 + 7.0.0-alpha.1.21620.1 4.5.4 4.5.0 - 7.0.0-alpha.1.21612.5 + 7.0.0-alpha.1.21620.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 - 7.0.0-beta.21603.1 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 + 7.0.0-beta.21620.3 1.0.0-prerelease.21577.2 1.0.0-prerelease.21577.2 @@ -152,9 +152,9 @@ 1.0.1-prerelease-00006 16.9.0-preview-20201201-01 - 1.0.0-prerelease.21613.2 - 1.0.0-prerelease.21613.2 - 1.0.2-alpha.0.21613.2 + 1.0.0-prerelease.21622.1 + 1.0.0-prerelease.21622.1 + 1.0.2-alpha.0.21620.2 2.4.2-pre.9 2.4.2 1.3.0 @@ -167,10 +167,10 @@ 6.0.0-preview-20211019.1 - 7.0.100-1.21610.1 + 7.0.100-1.21620.1 $(MicrosoftNETILLinkTasksVersion) - 7.0.0-alpha.1.21613.1 + 7.0.0-alpha.1.21620.1 7.0.0-alpha.1.21529.3 diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh index fdfeea66e7d43f..5c94e98632a0a7 100755 --- a/eng/common/dotnet-install.sh +++ b/eng/common/dotnet-install.sh @@ -55,6 +55,9 @@ case $cpuname in aarch64) buildarch=arm64 ;; + loongarch64) + buildarch=loongarch64 + ;; amd64|x86_64) buildarch=x64 ;; diff --git a/eng/common/native/CommonLibrary.psm1 b/eng/common/native/CommonLibrary.psm1 index adf707c8fe7008..ca38268c44d832 100644 --- a/eng/common/native/CommonLibrary.psm1 +++ b/eng/common/native/CommonLibrary.psm1 @@ -276,7 +276,8 @@ function Get-MachineArchitecture { } if (($ProcessorArchitecture -Eq "AMD64") -Or ($ProcessorArchitecture -Eq "IA64") -Or - ($ProcessorArchitecture -Eq "ARM64")) { + ($ProcessorArchitecture -Eq "ARM64") -Or + ($ProcessorArchitecture -Eq "LOONGARCH64")) { return "x64" } return "x86" diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index ad3dbd4db8bc0d..ade8c7aab981b6 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -279,7 +279,7 @@ jobs: targetRid: browser-wasm platform: Browser_wasm container: - image: ubuntu-18.04-webassembly-20210531091624-f5c7a43 + image: ubuntu-18.04-webassembly-20210707133424-12f133e registry: mcr jobParameters: runtimeFlavor: ${{ parameters.runtimeFlavor }} diff --git a/eng/pipelines/libraries/outerloop-mono.yml b/eng/pipelines/libraries/outerloop-mono.yml index f73f0c1e03c323..1267cf72a62dea 100644 --- a/eng/pipelines/libraries/outerloop-mono.yml +++ b/eng/pipelines/libraries/outerloop-mono.yml @@ -39,7 +39,7 @@ jobs: extraStepsTemplate: /eng/pipelines/libraries/helix.yml extraStepsParameters: scenarios: - - wasmtestonbrowser + - WasmTestOnBrowser testScope: outerloop creator: dotnet-bot testRunNamePrefixSuffix: Mono_$(_BuildConfig) diff --git a/eng/pipelines/runtime-manual.yml b/eng/pipelines/runtime-manual.yml index 77f7b29cad8ac4..a4391cff70da59 100644 --- a/eng/pipelines/runtime-manual.yml +++ b/eng/pipelines/runtime-manual.yml @@ -316,7 +316,8 @@ jobs: extraHelixArguments: /p:BrowserHost=windows scenarios: - normal - - wasmtestonbrowser + - WasmTestOnBrowser + - WasmTestOnNodeJs condition: >- or( eq(variables['librariesContainsChange'], true), @@ -463,6 +464,48 @@ jobs: scenarios: - normal +# +# Build for Browser/wasm and test it on NodeJS +# +- 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 + runtimeFlavor: mono + platforms: + - Browser_wasm + variables: + # map dependencies variables to local variables + - name: librariesContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ] + - name: monoContainsChange + value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ] + jobParameters: + testGroup: innerloop + nameSuffix: AllSubsets_Mono + buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true + timeoutInMinutes: 180 + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true), + eq(variables['isFullMatrix'], true)) + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: Mono_$(_BuildConfig) + scenarios: + - WasmTestOnNodeJs + condition: >- + or( + eq(variables['librariesContainsChange'], true), + eq(variables['monoContainsChange'], true), + eq(variables['isManualOrIsNotPR'], true), + eq(variables['isFullMatrix'], true)) + # # Build the whole product using Mono and run runtime tests # diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 79ed215e3a6393..4288d372433df7 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -526,7 +526,7 @@ jobs: extraHelixArguments: /p:BrowserHost=windows $(_runSmokeTestsOnlyArg) scenarios: - normal - - wasmtestonbrowser + - WasmTestOnBrowser condition: >- or( eq(variables['librariesContainsChange'], true), diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index d49bf441a853b9..5d7f3ffde2f81b 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -380,7 +380,7 @@ jobs: testRunNamePrefixSuffix: Mono_$(_BuildConfig) scenarios: - normal - - wasmtestonbrowser + - WasmTestOnBrowser condition: >- or( eq(variables['librariesContainsChange'], true), diff --git a/eng/testing/AppleRunnerTemplate.sh b/eng/testing/AppleRunnerTemplate.sh index 8f66672f739e66..e3f82159daf792 100644 --- a/eng/testing/AppleRunnerTemplate.sh +++ b/eng/testing/AppleRunnerTemplate.sh @@ -17,7 +17,7 @@ if [ -n "$6" ]; then ADDITIONAL_ARGS=${@:6} fi -if [[ "$CONFIGURATION" != "Debug" ]]; then $CONFIGURATION="Release"; fi +if [[ "$CONFIGURATION" != "Debug" ]]; then CONFIGURATION="Release"; fi if [[ "$TARGET_OS" == "maccatalyst" ]]; then TARGET=maccatalyst; fi diff --git a/eng/testing/WasmRunnerAOTTemplate.sh b/eng/testing/WasmRunnerAOTTemplate.sh index 4aa271b960a537..7348a25674c008 100644 --- a/eng/testing/WasmRunnerAOTTemplate.sh +++ b/eng/testing/WasmRunnerAOTTemplate.sh @@ -1,11 +1,15 @@ #!/usr/bin/env bash -EXECUTION_DIR=$(dirname $0) -SCENARIO=$3 +# SetCommands defined in eng\testing\tests.wasm.targets +[[SetCommands]] +[[SetCommandsEcho]] -cd $EXECUTION_DIR +EXECUTION_DIR=$(dirname $0) +if [[ -n "$3" ]]; then + SCENARIO=$3 +fi -if [ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]; then +if [[ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]]; then XHARNESS_OUT="$EXECUTION_DIR/xharness-output" else XHARNESS_OUT="$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output" @@ -19,12 +23,47 @@ else HARNESS_RUNNER="dotnet xharness" fi -if [[ "$SCENARIO" == "WasmTestOnBrowser" ]]; then - XHARNESS_COMMAND="test-browser" -elif [ -z "$XHARNESS_COMMAND" ]; then - XHARNESS_COMMAND="test" +if [[ -z "$XHARNESS_COMMAND" ]]; then + if [[ "$SCENARIO" == "WasmTestOnBrowser" || "$SCENARIO" == "wasmtestonbrowser" ]]; then + XHARNESS_COMMAND="test-browser" + else + XHARNESS_COMMAND="test" + fi +fi + +if [[ "$XHARNESS_COMMAND" == "test" ]]; then + if [[ -z "$JS_ENGINE" ]]; then + if [[ "$SCENARIO" == "WasmTestOnNodeJs" || "$SCENARIO" == "wasmtestonnodejs" ]]; then + JS_ENGINE="--engine=NodeJS" + else + JS_ENGINE="--engine=V8" + fi + fi + + if [[ -z "$MAIN_JS" ]]; then + MAIN_JS="--js-file=test-main.js" + fi + + if [[ -z "$JS_ENGINE_ARGS" ]]; then + JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000" + fi +fi + +if [[ -z "$XHARNESS_ARGS" ]]; then + XHARNESS_ARGS="$JS_ENGINE $JS_ENGINE_ARGS $MAIN_JS" fi +echo EXECUTION_DIR=$EXECUTION_DIR +echo SCENARIO=$SCENARIO +echo XHARNESS_OUT=$XHARNESS_OUT +echo XHARNESS_CLI_PATH=$XHARNESS_CLI_PATH +echo HARNESS_RUNNER=$HARNESS_RUNNER +echo XHARNESS_COMMAND=$XHARNESS_COMMAND +echo MAIN_JS=$MAIN_JS +echo JS_ENGINE=$JS_ENGINE +echo JS_ENGINE_ARGS=$JS_ENGINE_ARGS +echo XHARNESS_ARGS=$XHARNESS_ARGS + function _buildAOTFunc() { local projectFile=$1 @@ -56,11 +95,23 @@ function _buildAOTFunc() return 0 } -# RunCommands defined in tests.mobile.targets -[[RunCommands]] +pushd $EXECUTION_DIR + +# ========================= BEGIN Test Execution ============================= +echo ----- start $(date) =============== To repro directly: ===================================================== +echo pushd $EXECUTION_DIR +# RunCommands defined in eng\testing\tests.wasm.targets +[[RunCommandsEcho]] +echo popd +echo =========================================================================================================== +pushd $EXECUTION_DIR +# RunCommands defined in eng\testing\tests.wasm.targets +[[RunCommands]] _exitCode=$? +popd +echo ----- end $(date) ----- exit code $_exitCode ---------------------------------------------------------- echo "XHarness artifacts: $XHARNESS_OUT" -exit $_exitCode +exit $_exitCode \ No newline at end of file diff --git a/eng/testing/WasmRunnerTemplate.cmd b/eng/testing/WasmRunnerTemplate.cmd index 603199341a2b08..9382fa8368fc53 100644 --- a/eng/testing/WasmRunnerTemplate.cmd +++ b/eng/testing/WasmRunnerTemplate.cmd @@ -1,8 +1,14 @@ @echo off setlocal enabledelayedexpansion +:: SetCommands defined in eng\testing\tests.wasm.targets +[[SetCommands]] +[[SetCommandsEcho]] + set EXECUTION_DIR=%~dp0 -set SCENARIO=%3 +if [%3] NEQ [] ( + set SCENARIO=%3 +) if [%HELIX_WORKITEM_UPLOAD_ROOT%] == [] ( set "XHARNESS_OUT=%EXECUTION_DIR%xharness-output" @@ -18,22 +24,60 @@ if [%XHARNESS_CLI_PATH%] NEQ [] ( set HARNESS_RUNNER=dotnet.exe xharness ) -if [%SCENARIO%]==[WasmTestOnBrowser] ( - set XHARNESS_COMMAND=test-browser +if [%XHARNESS_COMMAND%] == [] ( + if /I [%SCENARIO%]==[WasmTestOnBrowser] ( + set XHARNESS_COMMAND=test-browser + ) else ( + set XHARNESS_COMMAND=test + ) +) + +if /I [%XHARNESS_COMMAND%] == [test] ( + if [%JS_ENGINE%] == [] ( + if /I [%SCENARIO%] == [WasmTestOnNodeJs] ( + set "JS_ENGINE=--engine^=NodeJS" + ) else ( + set "JS_ENGINE=--engine^=V8" + ) + ) + if [%MAIN_JS%] == [] ( + set "MAIN_JS=--js-file^=test-main.js" + ) + + if [%JS_ENGINE_ARGS%] == [] ( + set "JS_ENGINE_ARGS=--engine-arg^=--stack-trace-limit^=1000" + ) ) else ( - if [%XHARNESS_COMMAND%] == [] ( - set XHARNESS_COMMAND=test + if [%BROWSER_PATH%] == [] ( + set "BROWSER_PATH=--browser-path^=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe" ) ) +if [%XHARNESS_ARGS%] == [] ( + set "XHARNESS_ARGS=%JS_ENGINE% %JS_ENGINE_ARGS% %BROWSER_PATH% %MAIN_JS%" +) + +echo EXECUTION_DIR=%EXECUTION_DIR% +echo SCENARIO=%SCENARIO% +echo XHARNESS_OUT=%XHARNESS_OUT% +echo XHARNESS_CLI_PATH=%XHARNESS_CLI_PATH% +echo HARNESS_RUNNER=%HARNESS_RUNNER% +echo XHARNESS_COMMAND=%XHARNESS_COMMAND% +echo MAIN_JS=%MAIN_JS% +echo JS_ENGINE=%JS_ENGINE% +echo JS_ENGINE_ARGS=%JS_ENGINE_ARGS% +echo XHARNESS_ARGS=%XHARNESS_ARGS% + :: ========================= BEGIN Test Execution ============================= echo ----- start %DATE% %TIME% =============== To repro directly: ===================================================== echo pushd %EXECUTION_DIR% +:: RunCommands defined in eng\testing\tests.wasm.targets [[RunCommandsEcho]] echo popd echo =========================================================================================================== pushd %EXECUTION_DIR% @echo on +:: RunCommands defined in eng\testing\tests.wasm.targets [[RunCommands]] set EXIT_CODE=%ERRORLEVEL% @echo off diff --git a/eng/testing/WasmRunnerTemplate.sh b/eng/testing/WasmRunnerTemplate.sh index 412c33724aa158..ae78d5304e8aed 100644 --- a/eng/testing/WasmRunnerTemplate.sh +++ b/eng/testing/WasmRunnerTemplate.sh @@ -1,9 +1,13 @@ #!/usr/bin/env bash -EXECUTION_DIR=$(dirname $0) -SCENARIO=$3 +# SetCommands defined in eng\testing\tests.wasm.targets +[[SetCommands]] +[[SetCommandsEcho]] -cd $EXECUTION_DIR +EXECUTION_DIR=$(dirname $0) +if [[ -n "$3" ]]; then + SCENARIO=$3 +fi if [[ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]]; then XHARNESS_OUT="$EXECUTION_DIR/xharness-output" @@ -19,17 +23,64 @@ else HARNESS_RUNNER="dotnet xharness" fi -if [[ "$SCENARIO" == "WasmTestOnBrowser" ]]; then - XHARNESS_COMMAND="test-browser" -elif [[ -z "$XHARNESS_COMMAND" ]]; then - XHARNESS_COMMAND="test" +if [[ -z "$XHARNESS_COMMAND" ]]; then + if [[ "$SCENARIO" == "WasmTestOnBrowser" || "$SCENARIO" == "wasmtestonbrowser" ]]; then + XHARNESS_COMMAND="test-browser" + else + XHARNESS_COMMAND="test" + fi fi -# RunCommands defined in tests.mobile.targets -[[RunCommands]] +if [[ "$XHARNESS_COMMAND" == "test" ]]; then + if [[ -z "$JS_ENGINE" ]]; then + if [[ "$SCENARIO" == "WasmTestOnNodeJs" || "$SCENARIO" == "wasmtestonnodejs" ]]; then + JS_ENGINE="--engine=NodeJS" + else + JS_ENGINE="--engine=V8" + fi + fi + + if [[ -z "$MAIN_JS" ]]; then + MAIN_JS="--js-file=test-main.js" + fi + + if [[ -z "$JS_ENGINE_ARGS" ]]; then + JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000" + fi +fi +if [[ -z "$XHARNESS_ARGS" ]]; then + XHARNESS_ARGS="$JS_ENGINE $JS_ENGINE_ARGS $MAIN_JS" +fi + +echo EXECUTION_DIR=$EXECUTION_DIR +echo SCENARIO=$SCENARIO +echo XHARNESS_OUT=$XHARNESS_OUT +echo XHARNESS_CLI_PATH=$XHARNESS_CLI_PATH +echo HARNESS_RUNNER=$HARNESS_RUNNER +echo XHARNESS_COMMAND=$XHARNESS_COMMAND +echo MAIN_JS=$MAIN_JS +echo JS_ENGINE=$JS_ENGINE +echo JS_ENGINE_ARGS=$JS_ENGINE_ARGS +echo XHARNESS_ARGS=$XHARNESS_ARGS + + +pushd $EXECUTION_DIR + +# ========================= BEGIN Test Execution ============================= +echo ----- start $(date) =============== To repro directly: ===================================================== +echo pushd $EXECUTION_DIR +# RunCommands defined in eng\testing\tests.wasm.targets +[[RunCommandsEcho]] +echo popd +echo =========================================================================================================== +pushd $EXECUTION_DIR +# RunCommands defined in eng\testing\tests.wasm.targets +[[RunCommands]] _exitCode=$? +popd +echo ----- end $(date) ----- exit code $_exitCode ---------------------------------------------------------- echo "XHarness artifacts: $XHARNESS_OUT" -exit $_exitCode +exit $_exitCode \ No newline at end of file diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets index 1d14775dadd90b..6706d6e6d64529 100644 --- a/eng/testing/tests.targets +++ b/eng/testing/tests.targets @@ -102,6 +102,7 @@ diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets index ff38cc8686b995..273ab76ef90a3f 100644 --- a/eng/testing/tests.wasm.targets +++ b/eng/testing/tests.wasm.targets @@ -14,6 +14,7 @@ <_ShellCommandSeparator Condition="'$(OS)' == 'Windows_NT'">&& <_ShellCommandSeparator Condition="'$(OS)' != 'Windows_NT'">&& false + <_WasmMainJSFileName Condition="'$(WasmMainJSPath)' != ''">$([System.IO.Path]::GetFileName('$(WasmMainJSPath)')) @@ -22,15 +23,27 @@ local + + + + + + + + + + + + + - V8 - $(JSEngineArgs) --engine-arg=--stack-trace-limit=1000 - <_XHarnessArgs Condition="'$(OS)' != 'Windows_NT'">wasm $XHARNESS_COMMAND --app=. --output-directory=$XHARNESS_OUT <_XHarnessArgs Condition="'$(OS)' == 'Windows_NT'">wasm %XHARNESS_COMMAND% --app=. --output-directory=%XHARNESS_OUT% - <_XHarnessArgs Condition="'$(Scenario)' != 'WasmTestOnBrowser' and '$(Scenario)' != 'BuildWasmApps'">$(_XHarnessArgs) --engine=$(JSEngine) $(JSEngineArgs) --js-file=test-main.js - <_XHarnessArgs Condition="'$(BrowserHost)' == 'windows'">$(_XHarnessArgs) --browser=chrome --browser-path=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe <_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode) <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs) @@ -39,8 +52,8 @@ <_AppArgs Condition="'$(WasmTestAppArgs)' != ''">$(_AppArgs) $(WasmTestAppArgs) - $HARNESS_RUNNER $(_XHarnessArgs) %24WasmXHarnessArgs -- $(WasmXHarnessMonoArgs) %24WasmXHarnessMonoArgs $(_AppArgs) %24WasmTestAppArgs - %HARNESS_RUNNER% $(_XHarnessArgs) %WasmXHarnessArgs% -- $(WasmXHarnessMonoArgs) %WasmXHarnessMonoArgs% $(_AppArgs) %WasmTestAppArgs% + $HARNESS_RUNNER $(_XHarnessArgs) %24XHARNESS_ARGS %24WasmXHarnessArgs -- $(WasmXHarnessMonoArgs) %24WasmXHarnessMonoArgs $(_AppArgs) %24WasmTestAppArgs + %HARNESS_RUNNER% $(_XHarnessArgs) %XHARNESS_ARGS% %WasmXHarnessArgs% -- $(WasmXHarnessMonoArgs) %WasmXHarnessMonoArgs% $(_AppArgs) %WasmTestAppArgs% diff --git a/global.json b/global.json index 2dd889a46287e8..e2c9f881274f55 100644 --- a/global.json +++ b/global.json @@ -12,12 +12,12 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "7.0.0-beta.21615.1", - "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.21615.1", - "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.21615.1", - "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.21615.1", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "7.0.0-beta.21621.3", + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.21621.3", + "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.21621.3", + "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.21621.3", "Microsoft.Build.NoTargets": "3.1.0", "Microsoft.Build.Traversal": "3.0.23", - "Microsoft.NET.Sdk.IL": "7.0.0-alpha.1.21612.5" + "Microsoft.NET.Sdk.IL": "7.0.0-alpha.1.21620.1" } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs index a9875ebdaf4f24..cdef535524ac76 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs @@ -23,7 +23,7 @@ internal ConstructorBuilder(string name, MethodAttributes attributes, CallingCon m_methodBuilder.GetMethodSignature().InternalGetSignature(out _); - int dummy = m_methodBuilder.MetadataToken; + _ = m_methodBuilder.MetadataToken; // Doubles as "CreateMethod" for MethodBuilder -- analogous to CreateType() } internal ConstructorBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention, diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs index fbbeaa57359e3d..ff832cff7e14a2 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs @@ -61,7 +61,7 @@ public override void Emit(OpCode opcode, MethodInfo meth) throw new ArgumentNullException(nameof(meth)); int stackchange = 0; - int token = 0; + int token; DynamicMethod? dynMeth = meth as DynamicMethod; if (dynMeth == null) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs index 13df0ed585d747..44884c129e2374 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs @@ -1104,7 +1104,7 @@ private int GetTypeTokenWorkerNoLock(Type type, bool getGenericDefinition) if (refedModule.Equals(this)) { // no need to do anything additional other than defining the TypeRef Token - TypeBuilder? typeBuilder = null; + TypeBuilder? typeBuilder; EnumBuilder? enumBuilder = type as EnumBuilder; typeBuilder = enumBuilder != null ? enumBuilder.m_typeBuilder : type as TypeBuilder; @@ -1178,7 +1178,7 @@ private int GetMethodTokenNoLock(MethodInfo method, bool getGenericTypeDefinitio } int tr; - int mr = 0; + int mr; if (method is MethodBuilder methBuilder) { @@ -1425,7 +1425,7 @@ private int GetFieldTokenNoLock(FieldInfo field) } int tr; - int mr = 0; + int mr; if (field is FieldBuilder fdBuilder) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs index 377fac0eb9059f..36fe011d10d4f5 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs @@ -1996,7 +1996,7 @@ private EventBuilder DefineEventNoLock(string name, EventAttributes attributes, if (meth.IsGenericMethodDefinition) { - int dummy = meth.MetadataToken; // Doubles as "CreateMethod" for MethodBuilder -- analogous to CreateType() + _ = meth.MetadataToken; // Doubles as "CreateMethod" for MethodBuilder -- analogous to CreateType() } MethodAttributes methodAttrs = meth.Attributes; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs index 68c09394e9275e..43984c60a5468d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs @@ -479,7 +479,7 @@ public override MethodInfo MakeGenericMethod(params Type[] methodInstantiation) RuntimeType.SanityCheckGenericArguments(methodInstantionRuntimeType, genericParameters); - MethodInfo? ret = null; + MethodInfo? ret; try { 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 c15e96d63ca719..3752e611586240 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -1288,8 +1288,6 @@ private void PopulateProperties( scope.EnumProperties(tkDeclaringType, out MetadataEnumResult tkProperties); - RuntimeModule declaringModuleHandle = RuntimeTypeHandle.GetModule(declaringType); - int numVirtuals = RuntimeTypeHandle.GetNumVirtuals(declaringType); Debug.Assert((declaringType.IsInterface && usedSlots == null && csPropertyInfos == null) || diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index 41735099fb2e79..406e1dc8c533da 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -750,7 +750,7 @@ internal AsAnyMarshaler(IntPtr pvArrayMarshaler) private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags) { Type elementType = pManagedHome.GetType().GetElementType()!; - VarEnum vt = VarEnum.VT_EMPTY; + VarEnum vt; switch (Type.GetTypeCode(elementType)) { diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index d472b1393518fb..40eb8d078209f7 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -149,6 +149,45 @@ bool emitter::IsDstSrcSrcAVXInstruction(instruction ins) return ((CodeGenInterface::instInfo[ins] & INS_Flags_IsDstSrcSrcAVXInstruction) != 0) && IsAVXInstruction(ins); } +//------------------------------------------------------------------------ +// HasRegularWideForm: Many x86/x64 instructions follow a regular encoding scheme where the +// byte-sized version of an instruction has the lowest bit of the opcode cleared +// while the 32-bit version of the instruction (taking potential prefixes to +// override operand size) has the lowest bit set. This function returns true if +// the instruction follows this format. +// +// Note that this bit is called `w` in the encoding table in Section B.2 of +// Volume 2 of the Intel Architecture Software Developer Manual. +// +// Arguments: +// ins - instruction to test +// +// Return Value: +// true if instruction has a regular form where the 'w' bit needs to be set. +bool emitter::HasRegularWideForm(instruction ins) +{ + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Wbit) != 0); +} + +//------------------------------------------------------------------------ +// HasRegularWideImmediateForm: As above in HasRegularWideForm, many instructions taking +// immediates have a regular form used to encode whether the instruction takes a sign-extended +// 1-byte immediate or a (in 64-bit sign-extended) 4-byte immediate, by respectively setting and +// clearing the second lowest bit. +// +// Note that this bit is called `s` in the encoding table in Section B.2 of +// Volume 2 of the Intel Architecture Software Developer Manual. +// +// Arguments: +// ins - instruction to test +// +// Return Value: +// true if instruction has a regular wide immediate form where the 's' bit needs to set. +bool emitter::HasRegularWideImmediateForm(instruction ins) +{ + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Sbit) != 0); +} + //------------------------------------------------------------------------ // DoesWriteZeroFlag: check if the instruction write the // ZF flag. @@ -10114,6 +10153,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) ssize_t dsp; bool dspInByte; bool dspIsZero; + bool isMoffset = false; instruction ins = id->idIns(); emitAttr size = id->idOpSize(); @@ -10190,6 +10230,41 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) opsz = 1; } } +#ifdef TARGET_X86 + else + { + // Special case: "mov eax, [addr]" and "mov [addr], eax" + // Amd64: this is one case where addr can be 64-bit in size. This is + // currently unused or not enabled on amd64 as it always uses RIP + // relative addressing which results in smaller instruction size. + if ((ins == INS_mov) && (id->idReg1() == REG_EAX) && (reg == REG_NA) && (rgx == REG_NA)) + { + switch (id->idInsFmt()) + { + case IF_RWR_ARD: + + assert(code == (insCodeRM(ins) | (insEncodeReg345(ins, REG_EAX, EA_PTRSIZE, NULL) << 8))); + + code &= ~((code_t)0xFFFFFFFF); + code |= 0xA0; + isMoffset = true; + break; + + case IF_AWR_RRD: + + assert(code == (insCodeMR(ins) | (insEncodeReg345(ins, REG_EAX, EA_PTRSIZE, NULL) << 8))); + + code &= ~((code_t)0xFFFFFFFF); + code |= 0xA2; + isMoffset = true; + break; + + default: + break; + } + } + } +#endif // TARGET_X86 // Emit VEX prefix if required // There are some callers who already add VEX prefix and call this routine. @@ -10336,10 +10411,9 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // Use the large version if this is not a byte. This trick will not // work in case of SSE2 and AVX instructions. - if ((size != EA_1BYTE) && (ins != INS_imul) && (ins != INS_bsf) && (ins != INS_bsr) && !IsSSEInstruction(ins) && - !IsAVXInstruction(ins)) + if ((size != EA_1BYTE) && HasRegularWideForm(ins)) { - code++; + code |= 0x1; } } else if (CodeGen::instIsFP(ins)) @@ -10409,8 +10483,27 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) dspInByte = false; // relocs can't be placed in a byte } + if (isMoffset) + { +#ifdef TARGET_AMD64 + // This code path should never be hit on amd64 since it always uses RIP relative addressing. + // In future if ever there is a need to enable this special case, also enable the logic + // that sets isMoffset to true on amd64. + unreached(); +#else // TARGET_X86 + + dst += emitOutputByte(dst, code); + dst += emitOutputSizeT(dst, dsp); + + if (id->idIsDspReloc()) + { + emitRecordRelocation((void*)(dst - TARGET_POINTER_SIZE), (void*)dsp, IMAGE_REL_BASED_MOFFSET); + } + +#endif // TARGET_X86 + } // Is there a [scaled] index component? - if (rgx == REG_NA) + else if (rgx == REG_NA) { // The address is of the form "[reg+disp]" switch (reg) @@ -11103,9 +11196,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) } // Use the large version if this is not a byte - // TODO-XArch-Cleanup Can the need for the 'w' size bit be encoded in the instruction flags? - if ((size != EA_1BYTE) && (ins != INS_imul) && (ins != INS_bsf) && (ins != INS_bsr) && (!insIsCMOV(ins)) && - !IsSSEInstruction(ins) && !IsAVXInstruction(ins)) + if ((size != EA_1BYTE) && HasRegularWideForm(ins)) { code |= 0x1; } @@ -11568,12 +11659,9 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) code &= 0x0000FFFF; } - if ((ins == INS_movsx || ins == INS_movzx || ins == INS_cmpxchg || ins == INS_xchg || ins == INS_xadd || - insIsCMOV(ins)) && - size != EA_1BYTE) + if (size != EA_1BYTE && HasRegularWideForm(ins)) { - // movsx and movzx are 'big' opcodes but also have the 'w' bit - code++; + code |= 0x1; } } else if (CodeGen::instIsFP(ins)) @@ -12740,7 +12828,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id) } // "test" has no 's' bit - if (ins == INS_test) + if (!HasRegularWideImmediateForm(ins)) { useSigned = false; } diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index 54575044f13867..d6ed324deb242a 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -89,6 +89,7 @@ static bool IsAVXOnlyInstruction(instruction ins); static bool IsFMAInstruction(instruction ins); static bool IsAVXVNNIInstruction(instruction ins); static bool IsBMIInstruction(instruction ins); + static regNumber getBmiRegNumber(instruction ins); static regNumber getSseShiftRegNumber(instruction ins); bool IsAVXInstruction(instruction ins) const; @@ -190,6 +191,8 @@ void SetContains256bitAVX(bool value) bool IsDstDstSrcAVXInstruction(instruction ins); bool IsDstSrcSrcAVXInstruction(instruction ins); +bool HasRegularWideForm(instruction ins); +bool HasRegularWideImmediateForm(instruction ins); bool DoesWriteZeroFlag(instruction ins); bool DoesWriteSignFlag(instruction ins); bool DoesResetOverflowAndCarryFlags(instruction ins); diff --git a/src/coreclr/jit/instr.h b/src/coreclr/jit/instr.h index 1e9302cf503e89..1b613b77eb446f 100644 --- a/src/coreclr/jit/instr.h +++ b/src/coreclr/jit/instr.h @@ -131,6 +131,10 @@ enum insFlags : uint32_t // Avx INS_Flags_IsDstDstSrcAVXInstruction = 1 << 25, INS_Flags_IsDstSrcSrcAVXInstruction = 1 << 26, + + // w and s bits + INS_FLAGS_Has_Wbit = 1 << 27, + INS_FLAGS_Has_Sbit = 1 << 28, // TODO-Cleanup: Remove this flag and its usage from TARGET_XARCH INS_FLAGS_DONT_CARE = 0x00, diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 17b94fc81d779e..458f919fe27935 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -57,9 +57,9 @@ INST5(pop, "pop", IUM_WR, 0x00008E, BAD_CODE, INST5(push_hide, "push", IUM_RD, 0x0030FE, 0x000068, BAD_CODE, BAD_CODE, 0x000050, INS_FLAGS_None ) INST5(pop_hide, "pop", IUM_WR, 0x00008E, BAD_CODE, BAD_CODE, BAD_CODE, 0x000058, INS_FLAGS_None ) -INST5(inc, "inc", IUM_RW, 0x0000FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000040, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) +INST5(inc, "inc", IUM_RW, 0x0000FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000040, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | INS_FLAGS_Has_Wbit ) INST5(inc_l, "inc", IUM_RW, 0x0000FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x00C0FE, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) -INST5(dec, "dec", IUM_RW, 0x0008FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000048, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) +INST5(dec, "dec", IUM_RW, 0x0008FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000048, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | INS_FLAGS_Has_Wbit ) INST5(dec_l, "dec", IUM_RW, 0x0008FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x00C8FE, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) // Multi-byte opcodes without modrm are represented in mixed endian fashion. @@ -67,18 +67,16 @@ INST5(dec_l, "dec", IUM_RW, 0x0008FE, BAD_CODE, INST5(bswap, "bswap", IUM_RW, 0x0F00C8, BAD_CODE, BAD_CODE, BAD_CODE, 0x00C80F, INS_FLAGS_None ) // id nm um mr mi rm a4 flags -INST4(add, "add", IUM_RW, 0x000000, 0x000080, 0x000002, 0x000004, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST4(or, "or", IUM_RW, 0x000008, 0x000880, 0x00000A, 0x00000C, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(adc, "adc", IUM_RW, 0x000010, 0x001080, 0x000012, 0x000014, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF - | Reads_CF ) -INST4(sbb, "sbb", IUM_RW, 0x000018, 0x001880, 0x00001A, 0x00001C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF - | Reads_CF ) -INST4(and, "and", IUM_RW, 0x000020, 0x002080, 0x000022, 0x000024, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(sub, "sub", IUM_RW, 0x000028, 0x002880, 0x00002A, 0x00002C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST4(xor, "xor", IUM_RW, 0x000030, 0x003080, 0x000032, 0x000034, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(cmp, "cmp", IUM_RD, 0x000038, 0x003880, 0x00003A, 0x00003C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST4(test, "test", IUM_RD, 0x000084, 0x0000F6, 0x000084, 0x0000A8, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(mov, "mov", IUM_WR, 0x000088, 0x0000C6, 0x00008A, 0x0000B0, INS_FLAGS_None ) +INST4(add, "add", IUM_RW, 0x000000, 0x000080, 0x000002, 0x000004, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(or, "or", IUM_RW, 0x000008, 0x000880, 0x00000A, 0x00000C, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(adc, "adc", IUM_RW, 0x000010, 0x001080, 0x000012, 0x000014, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | Reads_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(sbb, "sbb", IUM_RW, 0x000018, 0x001880, 0x00001A, 0x00001C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | Reads_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(and, "and", IUM_RW, 0x000020, 0x002080, 0x000022, 0x000024, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(sub, "sub", IUM_RW, 0x000028, 0x002880, 0x00002A, 0x00002C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(xor, "xor", IUM_RW, 0x000030, 0x003080, 0x000032, 0x000034, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(cmp, "cmp", IUM_RD, 0x000038, 0x003880, 0x00003A, 0x00003C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(test, "test", IUM_RD, 0x000084, 0x0000F6, 0x000084, 0x0000A8, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Wbit ) +INST4(mov, "mov", IUM_WR, 0x000088, 0x0000C6, 0x00008A, 0x0000B0, INS_FLAGS_Has_Wbit ) INST4(lea, "lea", IUM_WR, BAD_CODE, BAD_CODE, 0x00008D, BAD_CODE, INS_FLAGS_None ) @@ -91,11 +89,11 @@ INST3(bt, "bt", IUM_RD, 0x0F00A3, BAD_CODE, INST3(bsf, "bsf", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BC, Undefined_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) INST3(bsr, "bsr", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BD, Undefined_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) -INST3(movsx, "movsx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BE, INS_FLAGS_None ) +INST3(movsx, "movsx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BE, INS_FLAGS_Has_Wbit ) #ifdef TARGET_AMD64 -INST3(movsxd, "movsxd", IUM_WR, BAD_CODE, BAD_CODE, 0x4800000063, INS_FLAGS_None ) +INST3(movsxd, "movsxd", IUM_WR, BAD_CODE, BAD_CODE, 0x4800000063, INS_FLAGS_Has_Wbit ) #endif -INST3(movzx, "movzx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00B6, INS_FLAGS_None ) +INST3(movzx, "movzx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00B6, INS_FLAGS_Has_Wbit ) INST3(cmovo, "cmovo", IUM_WR, BAD_CODE, BAD_CODE, 0x0F0040, Reads_OF ) INST3(cmovno, "cmovno", IUM_WR, BAD_CODE, BAD_CODE, 0x0F0041, Reads_OF ) @@ -114,8 +112,8 @@ INST3(cmovge, "cmovge", IUM_WR, BAD_CODE, BAD_CODE, INST3(cmovle, "cmovle", IUM_WR, BAD_CODE, BAD_CODE, 0x0F004E, Reads_OF | Reads_SF | Reads_ZF ) INST3(cmovg, "cmovg", IUM_WR, BAD_CODE, BAD_CODE, 0x0F004F, Reads_OF | Reads_SF | Reads_ZF ) -INST3(xchg, "xchg", IUM_RW, 0x000086, BAD_CODE, 0x000086, INS_FLAGS_None ) -INST3(imul, "imul", IUM_RW, 0x0F00AC, BAD_CODE, 0x0F00AF, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INST3(xchg, "xchg", IUM_RW, 0x000086, BAD_CODE, 0x000086, INS_FLAGS_Has_Wbit ) +INST3(imul, "imul", IUM_RW, 0x0F00AC, BAD_CODE, 0x0F00AF, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) // id nm um mr mi rm flags @@ -123,25 +121,25 @@ INST3(imul, "imul", IUM_RW, 0x0F00AC, BAD_CODE, // as 2-operand instructions with the target register being implicit // implicit_reg = op1*op2_icon #define INSTMUL INST3 -INSTMUL(imul_AX, "imul", IUM_RD, BAD_CODE, 0x000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_CX, "imul", IUM_RD, BAD_CODE, 0x000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_DX, "imul", IUM_RD, BAD_CODE, 0x001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_BX, "imul", IUM_RD, BAD_CODE, 0x001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_SP, "imul", IUM_RD, BAD_CODE, BAD_CODE, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_BP, "imul", IUM_RD, BAD_CODE, 0x002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_SI, "imul", IUM_RD, BAD_CODE, 0x003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_DI, "imul", IUM_RD, BAD_CODE, 0x003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INSTMUL(imul_AX, "imul", IUM_RD, BAD_CODE, 0x000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_CX, "imul", IUM_RD, BAD_CODE, 0x000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_DX, "imul", IUM_RD, BAD_CODE, 0x001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_BX, "imul", IUM_RD, BAD_CODE, 0x001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_SP, "imul", IUM_RD, BAD_CODE, BAD_CODE, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_BP, "imul", IUM_RD, BAD_CODE, 0x002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_SI, "imul", IUM_RD, BAD_CODE, 0x003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_DI, "imul", IUM_RD, BAD_CODE, 0x003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) #ifdef TARGET_AMD64 -INSTMUL(imul_08, "imul", IUM_RD, BAD_CODE, 0x4400000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_09, "imul", IUM_RD, BAD_CODE, 0x4400000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_10, "imul", IUM_RD, BAD_CODE, 0x4400001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_11, "imul", IUM_RD, BAD_CODE, 0x4400001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_12, "imul", IUM_RD, BAD_CODE, 0x4400002068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_13, "imul", IUM_RD, BAD_CODE, 0x4400002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_14, "imul", IUM_RD, BAD_CODE, 0x4400003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_15, "imul", IUM_RD, BAD_CODE, 0x4400003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INSTMUL(imul_08, "imul", IUM_RD, BAD_CODE, 0x4400000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_09, "imul", IUM_RD, BAD_CODE, 0x4400000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_10, "imul", IUM_RD, BAD_CODE, 0x4400001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_11, "imul", IUM_RD, BAD_CODE, 0x4400001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_12, "imul", IUM_RD, BAD_CODE, 0x4400002068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_13, "imul", IUM_RD, BAD_CODE, 0x4400002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_14, "imul", IUM_RD, BAD_CODE, 0x4400003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_15, "imul", IUM_RD, BAD_CODE, 0x4400003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) #endif // TARGET_AMD64 @@ -628,55 +626,49 @@ INST2(ret, "ret", IUM_RD, 0x0000C3, 0x0000C2, INST2(loop, "loop", IUM_RD, BAD_CODE, 0x0000E2, INS_FLAGS_None ) INST2(call, "call", IUM_RD, 0x0010FF, 0x0000E8, INS_FLAGS_None ) -INST2(rol, "rol", IUM_RW, 0x0000D2, BAD_CODE, Undefined_OF | Writes_CF ) -INST2(rol_1, "rol", IUM_RW, 0x0000D0, 0x0000D0, Writes_OF | Writes_CF ) -INST2(rol_N, "rol", IUM_RW, 0x0000C0, 0x0000C0, Undefined_OF | Writes_CF ) -INST2(ror, "ror", IUM_RW, 0x0008D2, BAD_CODE, Undefined_OF | Writes_CF ) -INST2(ror_1, "ror", IUM_RW, 0x0008D0, 0x0008D0, Writes_OF | Writes_CF ) -INST2(ror_N, "ror", IUM_RW, 0x0008C0, 0x0008C0, Undefined_OF | Writes_CF ) - -INST2(rcl, "rcl", IUM_RW, 0x0010D2, BAD_CODE, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(rcl_1, "rcl", IUM_RW, 0x0010D0, 0x0010D0, Writes_OF | Writes_CF - | Reads_CF ) -INST2(rcl_N, "rcl", IUM_RW, 0x0010C0, 0x0010C0, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(rcr, "rcr", IUM_RW, 0x0018D2, BAD_CODE, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(rcr_1, "rcr", IUM_RW, 0x0018D0, 0x0018D0, Writes_OF | Writes_CF - | Reads_CF ) -INST2(rcr_N, "rcr", IUM_RW, 0x0018C0, 0x0018C0, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(shl, "shl", IUM_RW, 0x0020D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shl_1, "shl", IUM_RW, 0x0020D0, 0x0020D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shl_N, "shl", IUM_RW, 0x0020C0, 0x0020C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shr, "shr", IUM_RW, 0x0028D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shr_1, "shr", IUM_RW, 0x0028D0, 0x0028D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shr_N, "shr", IUM_RW, 0x0028C0, 0x0028C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(sar, "sar", IUM_RW, 0x0038D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(sar_1, "sar", IUM_RW, 0x0038D0, 0x0038D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(sar_N, "sar", IUM_RW, 0x0038C0, 0x0038C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) +INST2(rol, "rol", IUM_RW, 0x0000D2, BAD_CODE, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(rol_1, "rol", IUM_RW, 0x0000D0, 0x0000D0, Writes_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(rol_N, "rol", IUM_RW, 0x0000C0, 0x0000C0, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(ror, "ror", IUM_RW, 0x0008D2, BAD_CODE, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(ror_1, "ror", IUM_RW, 0x0008D0, 0x0008D0, Writes_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(ror_N, "ror", IUM_RW, 0x0008C0, 0x0008C0, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) + +INST2(rcl, "rcl", IUM_RW, 0x0010D2, BAD_CODE, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcl_1, "rcl", IUM_RW, 0x0010D0, 0x0010D0, Writes_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcl_N, "rcl", IUM_RW, 0x0010C0, 0x0010C0, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcr, "rcr", IUM_RW, 0x0018D2, BAD_CODE, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcr_1, "rcr", IUM_RW, 0x0018D0, 0x0018D0, Writes_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcr_N, "rcr", IUM_RW, 0x0018C0, 0x0018C0, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(shl, "shl", IUM_RW, 0x0020D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shl_1, "shl", IUM_RW, 0x0020D0, 0x0020D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shl_N, "shl", IUM_RW, 0x0020C0, 0x0020C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shr, "shr", IUM_RW, 0x0028D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shr_1, "shr", IUM_RW, 0x0028D0, 0x0028D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shr_N, "shr", IUM_RW, 0x0028C0, 0x0028C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(sar, "sar", IUM_RW, 0x0038D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(sar_1, "sar", IUM_RW, 0x0038D0, 0x0038D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(sar_N, "sar", IUM_RW, 0x0038C0, 0x0038C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) // id nm um mr flags -INST1(r_movsb, "rep movsb", IUM_RD, 0x00A4F3, Reads_DF ) -INST1(r_movsd, "rep movsd", IUM_RD, 0x00A5F3, Reads_DF ) +INST1(r_movsb, "rep movsb", IUM_RD, 0x00A4F3, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(r_movsd, "rep movsd", IUM_RD, 0x00A5F3, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(r_movsq, "rep movsq", IUM_RD, 0xF3A548, Reads_DF ) #endif // defined(TARGET_AMD64) -INST1(movsb, "movsb", IUM_RD, 0x0000A4, Reads_DF ) -INST1(movsd, "movsd", IUM_RD, 0x0000A5, Reads_DF ) +INST1(movsb, "movsb", IUM_RD, 0x0000A4, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(movsd, "movsd", IUM_RD, 0x0000A5, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(movsq, "movsq", IUM_RD, 0x00A548, Reads_DF ) #endif // defined(TARGET_AMD64) -INST1(r_stosb, "rep stosb", IUM_RD, 0x00AAF3, Reads_DF ) -INST1(r_stosd, "rep stosd", IUM_RD, 0x00ABF3, Reads_DF ) +INST1(r_stosb, "rep stosb", IUM_RD, 0x00AAF3, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(r_stosd, "rep stosd", IUM_RD, 0x00ABF3, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(r_stosq, "rep stosq", IUM_RD, 0xF3AB48, Reads_DF ) #endif // defined(TARGET_AMD64) -INST1(stosb, "stosb", IUM_RD, 0x0000AA, Reads_DF ) -INST1(stosd, "stosd", IUM_RD, 0x0000AB, Reads_DF ) +INST1(stosb, "stosb", IUM_RD, 0x0000AA, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(stosd, "stosd", IUM_RD, 0x0000AB, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(stosq, "stosq", IUM_RD, 0x00AB48, Reads_DF ) #endif // defined(TARGET_AMD64) @@ -687,20 +679,20 @@ INST1(pause, "pause", IUM_RD, 0x0090F3, INST1(lock, "lock", IUM_RD, 0x0000F0, INS_FLAGS_None ) INST1(leave, "leave", IUM_RD, 0x0000C9, INS_FLAGS_None ) -INST1(neg, "neg", IUM_RW, 0x0018F6, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST1(not, "not", IUM_RW, 0x0010F6, INS_FLAGS_None ) +INST1(neg, "neg", IUM_RW, 0x0018F6, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST1(not, "not", IUM_RW, 0x0010F6, INS_FLAGS_None | INS_FLAGS_Has_Wbit ) INST1(cwde, "cwde", IUM_RD, 0x000098, INS_FLAGS_None ) INST1(cdq, "cdq", IUM_RD, 0x000099, INS_FLAGS_None ) -INST1(idiv, "idiv", IUM_RD, 0x0038F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) -INST1(imulEAX, "imul", IUM_RD, 0x0028F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INST1(div, "div", IUM_RD, 0x0030F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) -INST1(mulEAX, "mul", IUM_RD, 0x0020F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INST1(idiv, "idiv", IUM_RD, 0x0038F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF | INS_FLAGS_Has_Wbit ) +INST1(imulEAX, "imul", IUM_RD, 0x0028F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST1(div, "div", IUM_RD, 0x0030F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF | INS_FLAGS_Has_Wbit ) +INST1(mulEAX, "mul", IUM_RD, 0x0020F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Wbit ) INST1(sahf, "sahf", IUM_RD, 0x00009E, Restore_SF_ZF_AF_PF_CF ) -INST1(xadd, "xadd", IUM_RW, 0x0F00C0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST1(cmpxchg, "cmpxchg", IUM_RW, 0x0F00B0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) +INST1(xadd, "xadd", IUM_RW, 0x0F00C0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST1(cmpxchg, "cmpxchg", IUM_RW, 0x0F00B0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) INST1(shld, "shld", IUM_RW, 0x0F00A4, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) INST1(shrd, "shrd", IUM_RW, 0x0F00AC, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 0729d06e414f13..2b75e4171b53bd 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -12029,7 +12029,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) effectiveOp1 = op1->gtEffectiveVal(); // If we are storing a small type, we might be able to omit a cast. - if (effectiveOp1->OperIs(GT_IND) && varTypeIsSmall(effectiveOp1)) + if (effectiveOp1->OperIs(GT_IND, GT_CLS_VAR) && varTypeIsSmall(effectiveOp1)) { if (!gtIsActiveCSE_Candidate(op2) && op2->OperIs(GT_CAST) && varTypeIsIntegral(op2->AsCast()->CastOp()) && !op2->gtOverflow()) diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs index 007e940bec2795..b610ba7cbb55c7 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs @@ -1414,8 +1414,6 @@ public uint GetFieldOffset(EETypeField eField) Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0); return cbOffset; } - if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithThreadStatics) != 0) - cbOffset += 4; Debug.Assert(false, "Unknown MethodTable field type"); return 0; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs index 8fefdd42132fee..0499890c36ac62 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs @@ -28,8 +28,7 @@ public class DeveloperExperience /// private static bool IsMetadataStackTraceResolutionDisabled() { - bool disableMetadata = false; - AppContext.TryGetSwitch("Diagnostics.DisableMetadataStackTraceResolution", out disableMetadata); + AppContext.TryGetSwitch("Diagnostics.DisableMetadataStackTraceResolution", out bool disableMetadata); return disableMetadata; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs index a963522d5eca4d..dc332681127a2d 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs @@ -143,9 +143,8 @@ private IEnumerable GetMatchingCustomAttributesIterator(E e for (int i = 0; i < immediateResults.Count; i++) { Type attributeType = immediateResults[i].AttributeType; - AttributeUsageAttribute? usage; TypeUnificationKey attributeTypeKey = new TypeUnificationKey(attributeType); - if (!encounteredTypes.TryGetValue(attributeTypeKey, out usage)) + if (!encounteredTypes.TryGetValue(attributeTypeKey, out _)) encounteredTypes.Add(attributeTypeKey, null); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/GenericVirtualMethodSupport.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/GenericVirtualMethodSupport.cs index 3ceaf03e3f0b40..1db523e3e6afe9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/GenericVirtualMethodSupport.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/GenericVirtualMethodSupport.cs @@ -14,8 +14,8 @@ private static unsafe IntPtr GVMLookupForSlotWorker(RuntimeTypeHandle type, Runt bool slotChanged = false; IntPtr resolution = IntPtr.Zero; - IntPtr functionPointer = IntPtr.Zero; - IntPtr genericDictionary = IntPtr.Zero; + IntPtr functionPointer; + IntPtr genericDictionary; bool lookForDefaultImplementations = false; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Resources/Strings.resx b/src/coreclr/nativeaot/System.Private.CoreLib/src/Resources/Strings.resx index 1f979fe12d4eb4..42df14c410ed46 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Resources/Strings.resx @@ -3247,6 +3247,18 @@ A MemberInfo that matches '{0}' could not be found. + + Bad magic in '{0}': Header starts with '{1}' instead of 'tzdata' + + + Unable to fully read from file '{0}' at offset {1} length {2}; read {3} bytes expected {4}. + + + Length in index file less than AndroidTzDataHeader + + + Unable to properly load any time zone data files. + NullabilityInfoContext is not supported in the current application because 'System.Reflection.NullabilityInfoContext.IsSupported' is set to false. Set the MSBuild Property 'NullabilityInfoContextSupport' to true in order to enable it. diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameLexer.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameLexer.cs index d2dca88f24e386..84555ab310d454 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameLexer.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameLexer.cs @@ -31,8 +31,7 @@ internal AssemblyNameLexer(string s) // internal Token GetNext() { - string ignore; - return GetNext(out ignore); + return GetNext(out _); } // diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs index e3cc38081028e3..39011afc922f8e 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/InteropExtensions.cs @@ -69,9 +69,7 @@ public static IntPtr GetRawFunctionPointerForOpenStaticDelegate(this Delegate de if (!del.IsOpenStatic) return IntPtr.Zero; - RuntimeTypeHandle typeOfFirstParameterIfInstanceDelegate; - - IntPtr funcPtr = del.GetFunctionPointer(out typeOfFirstParameterIfInstanceDelegate, out bool _, out bool _); + IntPtr funcPtr = del.GetFunctionPointer(out RuntimeTypeHandle _, out bool _, out bool _); return funcPtr; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.CoreRT.cs index 78567538db945a..c8c1d47c00eeda 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.CoreRT.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.CoreRT.cs @@ -58,7 +58,7 @@ internal static void GetDllImportSearchPathFlags(Assembly callingAssembly, out i internal static IntPtr LoadBySearch(Assembly callingAssembly, bool searchAssemblyDirectory, int dllImportSearchPathFlags, ref LoadLibErrorTracker errorTracker, string libraryName) { - IntPtr ret = IntPtr.Zero; + IntPtr ret; int loadWithAlteredPathFlags = 0; bool libNameIsRelativePath = !Path.IsPathFullyQualified(libraryName); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs index 5063c24c12c398..cb1b39db71283a 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeMethodHandle.cs @@ -105,9 +105,7 @@ public override int GetHashCode() public IntPtr GetFunctionPointer() { RuntimeTypeHandle declaringType; - MethodNameAndSignature nameAndSignature; - RuntimeTypeHandle[] genericArgs; - RuntimeAugments.TypeLoaderCallbacks.GetRuntimeMethodHandleComponents(this, out declaringType, out nameAndSignature, out genericArgs); + RuntimeAugments.TypeLoaderCallbacks.GetRuntimeMethodHandleComponents(this, out declaringType, out _, out _); return ReflectionAugments.ReflectionCoreCallbacks.GetFunctionPointer(this, declaringType); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.CoreRT.cs index 92f2c2ad3e94dd..f5317ff6d22ed7 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.CoreRT.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Monitor.CoreRT.cs @@ -130,9 +130,8 @@ public static bool IsEntered(object obj) public static bool Wait(object obj, int millisecondsTimeout) { Condition condition = GetCondition(obj); - DebugBlockingItem blockingItem; - using (new DebugBlockingScope(obj, DebugBlockingItemType.MonitorEvent, millisecondsTimeout, out blockingItem)) + using (new DebugBlockingScope(obj, DebugBlockingItemType.MonitorEvent, millisecondsTimeout, out _)) { return condition.Wait(millisecondsTimeout); } @@ -164,9 +163,7 @@ public static void PulseAll(object obj) internal static bool TryAcquireContended(Lock lck, object obj, int millisecondsTimeout) { - DebugBlockingItem blockingItem; - - using (new DebugBlockingScope(obj, DebugBlockingItemType.MonitorCriticalSection, millisecondsTimeout, out blockingItem)) + using (new DebugBlockingScope(obj, DebugBlockingItemType.MonitorCriticalSection, millisecondsTimeout, out _)) { return lck.TryAcquire(millisecondsTimeout, trackContentions: true); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/AnalysisBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/AnalysisBasedMetadataManager.cs index 6ba6cc54c5122f..8ad71eb3db5b5d 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/AnalysisBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/AnalysisBasedMetadataManager.cs @@ -22,6 +22,7 @@ namespace ILCompiler public sealed class AnalysisBasedMetadataManager : GeneratingMetadataManager, ICompilationRootProvider { private readonly List _modulesWithMetadata; + private readonly List _typesWithRootedCctorContext; private readonly Dictionary _reflectableTypes = new Dictionary(); private readonly Dictionary _reflectableMethods = new Dictionary(); @@ -33,7 +34,8 @@ public AnalysisBasedMetadataManager(CompilerTypeSystemContext typeSystemContext) new FullyBlockedManifestResourceBlockingPolicy(), null, new NoStackTraceEmissionPolicy(), new NoDynamicInvokeThunkGenerationPolicy(), Array.Empty(), Array.Empty>(), Array.Empty>(), - Array.Empty>(), Array.Empty()) + Array.Empty>(), Array.Empty(), + Array.Empty()) { } @@ -48,10 +50,12 @@ public AnalysisBasedMetadataManager( IEnumerable> reflectableTypes, IEnumerable> reflectableMethods, IEnumerable> reflectableFields, - IEnumerable reflectableAttributes) + IEnumerable reflectableAttributes, + IEnumerable rootedCctorContexts) : base(typeSystemContext, blockingPolicy, resourceBlockingPolicy, logFile, stackTracePolicy, invokeThunkGenerationPolicy) { _modulesWithMetadata = new List(modulesWithMetadata); + _typesWithRootedCctorContext = new List(rootedCctorContexts); foreach (var refType in reflectableTypes) { @@ -209,6 +213,11 @@ void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootPr } } } + + foreach (var type in _typesWithRootedCctorContext) + { + rootProvider.RootNonGCStaticBaseForType(type, reason); + } } private struct Policy : IMetadataPolicy diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index 687104277c2f2b..bd649904129bf8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -794,10 +794,28 @@ public MetadataManager ToAnalysisBasedMetadataManager() } } + var rootedCctorContexts = new List(); + foreach (NonGCStaticsNode cctorContext in GetCctorContextMapping()) + { + // If we generated a static constructor and the owning type, this might be something + // that gets fed to RuntimeHelpers.RunClassConstructor. RunClassConstructor + // also works on reflection blocked types and there is a possibility that we + // wouldn't have generated the cctor otherwise. + // + // This is a heuristic and we'll possibly root more cctor contexts than + // strictly necessary, but it's not worth introducing a new node type + // in the compiler just so we can propagate this knowledge from dataflow analysis + // (that detects RunClassConstructor usage) and this spot. + if (!TypeGeneratesEEType(cctorContext.Type)) + continue; + + rootedCctorContexts.Add(cctorContext.Type); + } + return new AnalysisBasedMetadataManager( _typeSystemContext, _blockingPolicy, _resourceBlockingPolicy, _metadataLogFile, _stackTraceEmissionPolicy, _dynamicInvokeThunkGenerationPolicy, _modulesWithMetadata, reflectableTypes.ToEnumerable(), reflectableMethods.ToEnumerable(), - reflectableFields.ToEnumerable(), _customAttributesWithMetadata); + reflectableFields.ToEnumerable(), _customAttributesWithMetadata, rootedCctorContexts); } private struct ReflectableEntityBuilder diff --git a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj index f505b0851ecc22..359af2447d39a0 100644 --- a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj @@ -31,7 +31,7 @@ - 7.0.0-alpha.1.21455.2 + 7.0.0-alpha.1.21612.2 $(Configuration) Debug diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetNodeName.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetNodeName.cs deleted file mode 100644 index 0c2f1ee7078b1f..00000000000000 --- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetNodeName.cs +++ /dev/null @@ -1,34 +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.Diagnostics; -using System.Runtime.InteropServices; -using System.Text; - -internal static partial class Interop -{ - internal static partial class Sys - { - [GeneratedDllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetNodeName", SetLastError = true)] - private static unsafe partial int GetNodeName(byte* name, ref int len); - - internal static unsafe string GetNodeName() - { - // max value of _UTSNAME_LENGTH on known Unix platforms is 1024. - const int _UTSNAME_LENGTH = 1024; - int len = _UTSNAME_LENGTH; - byte* name = stackalloc byte[_UTSNAME_LENGTH]; - int err = GetNodeName(name, ref len); - if (err != 0) - { - // max domain name can be 255 chars. - Debug.Fail($"{nameof(GetNodeName)} failed with error {err}"); - throw new InvalidOperationException($"{nameof(GetNodeName)}: {err}"); - } - - // Marshal.PtrToStringAnsi uses UTF8 on Unix. - return Marshal.PtrToStringAnsi((IntPtr)name); - } - } -} 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 27213cc2a0ed39..99bcc38f0a7159 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 @@ -168,6 +168,7 @@ internal static partial class WinHttp public const uint WINHTTP_OPTION_TCP_KEEPALIVE = 152; public const uint WINHTTP_OPTION_STREAM_ERROR_CODE = 159; + public const uint WINHTTP_OPTION_REQUIRE_STREAM_END = 160; public enum WINHTTP_WEB_SOCKET_BUFFER_TYPE { diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/BindingList.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/BindingList.cs index 9e5faa75ec37b3..b423375c646b8d 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/BindingList.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/BindingList.cs @@ -73,7 +73,7 @@ private void Initialize() } } - private bool ItemTypeHasDefaultConstructor + private static bool ItemTypeHasDefaultConstructor { get { diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CultureInfoConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CultureInfoConverter.cs index b675da60e69d0d..3e8408548c63a0 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CultureInfoConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CultureInfoConverter.cs @@ -22,7 +22,7 @@ public class CultureInfoConverter : TypeConverter /// /// Retrieves the "default" name for our culture. /// - private string DefaultCultureString => SR.CultureInfoConverterDefaultCultureString; + private static string DefaultCultureString => SR.CultureInfoConverterDefaultCultureString; private const string DefaultInvariantCultureString = "(Default)"; diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs index b72d91e01c955a..eb5f0d456b8cd3 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs @@ -50,7 +50,7 @@ internal sealed class RuntimeLicenseContext : LicenseContext /// if there is a '#' in the path, everything after this is treated as a fragment. So /// we need to append the fragment to the end of the path. /// - private string GetLocalPath(string fileName) + private static string GetLocalPath(string fileName) { Debug.Assert(fileName != null && fileName.Length > 0, "Cannot get local path, fileName is not valid"); @@ -150,7 +150,7 @@ private string GetLocalPath(string fileName) * we are attempting to locate could have different casing * depending on how the assembly was loaded. **/ - private Stream? CaseInsensitiveManifestResourceStreamLookup(Assembly satellite, string name) + private static Stream? CaseInsensitiveManifestResourceStreamLookup(Assembly satellite, string name) { CompareInfo comparer = CultureInfo.InvariantCulture.CompareInfo; diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs index 7237e3f94b0f69..05241af299d0c9 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.ReflectedTypeData.cs @@ -154,7 +154,7 @@ internal AttributeCollection GetAttributes() /// /// Retrieves the component name from the site. /// - internal string? GetComponentName(object? instance) + internal static string? GetComponentName(object? instance) { IComponent? comp = instance as IComponent; ISite? site = comp?.Site; diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs index 48709a88c24675..dacc0ea3aba45d 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs @@ -355,10 +355,9 @@ internal AttributeCollection GetAttributes([DynamicallyAccessedMembers(Dynamical /// /// Retrieves the component name from the site. /// - internal string? GetComponentName([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, object? instance) + internal static string? GetComponentName(object? instance) { - ReflectedTypeData td = GetTypeData(type, true)!; - return td.GetComponentName(instance); + return ReflectedTypeData.GetComponentName(instance); } /// @@ -464,7 +463,7 @@ internal EventDescriptorCollection GetEvents([DynamicallyAccessedMembers(Dynamic /// Retrieves custom extender attributes. We don't support /// extender attributes, so we always return an empty collection. /// - internal AttributeCollection GetExtendedAttributes(object instance) + internal static AttributeCollection GetExtendedAttributes(object instance) { return AttributeCollection.Empty; } @@ -481,10 +480,9 @@ internal AttributeCollection GetExtendedAttributes(object instance) /// /// Retrieves the component name from the site. /// - [RequiresUnreferencedCode("The Type of instance cannot be statically discovered.")] - internal string? GetExtendedComponentName(object instance) + internal static string? GetExtendedComponentName(object instance) { - return GetComponentName(instance.GetType(), instance); + return GetComponentName(instance); } /// @@ -502,7 +500,7 @@ internal TypeConverter GetExtendedConverter(object instance) /// Return the default event. The default event is determined by the /// presence of a DefaultEventAttribute on the class. /// - internal EventDescriptor? GetExtendedDefaultEvent(object instance) + internal static EventDescriptor? GetExtendedDefaultEvent() { return null; // we don't support extended events. } @@ -510,7 +508,7 @@ internal TypeConverter GetExtendedConverter(object instance) /// /// Return the default property. /// - internal PropertyDescriptor? GetExtendedDefaultProperty(object instance) + internal static PropertyDescriptor? GetExtendedDefaultProperty(object instance) { return null; // extender properties are never the default. } @@ -527,7 +525,7 @@ internal TypeConverter GetExtendedConverter(object instance) /// /// Retrieves the events for this type. /// - internal EventDescriptorCollection GetExtendedEvents(object instance) + internal static EventDescriptorCollection GetExtendedEvents(object instance) { return EventDescriptorCollection.Empty; } @@ -796,7 +794,7 @@ private static IExtenderProvider[] GetExtenders(ICollection components, object i /// /// Retrieves the owner for a property. /// - internal object GetExtendedPropertyOwner(object instance, PropertyDescriptor? pd) + internal static object GetExtendedPropertyOwner(object instance, PropertyDescriptor? pd) { return GetPropertyOwner(instance.GetType(), instance, pd); } @@ -878,7 +876,7 @@ internal PropertyDescriptorCollection GetProperties([DynamicallyAccessedMembers( /// /// Retrieves the owner for a property. /// - internal object GetPropertyOwner(Type type, object instance, PropertyDescriptor? pd) + internal static object GetPropertyOwner(Type type, object instance, PropertyDescriptor? pd) { return TypeDescriptor.GetAssociation(type, instance); } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs index 0747e7ff01e95e..f1b36ef296ab94 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs @@ -3324,9 +3324,9 @@ AttributeCollection ICustomTypeDescriptor.GetAttributes() // custom type descriptor TypeDescriptionProvider p = _node.Provider; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { - return rp.GetExtendedAttributes(_instance); + return ReflectTypeDescriptionProvider.GetExtendedAttributes(_instance); } ICustomTypeDescriptor desc = p.GetExtendedTypeDescriptor(_instance); @@ -3369,9 +3369,9 @@ AttributeCollection ICustomTypeDescriptor.GetAttributes() // custom type descriptor TypeDescriptionProvider p = _node.Provider; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { - return rp.GetExtendedComponentName(_instance); + return ReflectTypeDescriptionProvider.GetExtendedComponentName(_instance); } ICustomTypeDescriptor desc = p.GetExtendedTypeDescriptor(_instance); @@ -3413,9 +3413,9 @@ TypeConverter ICustomTypeDescriptor.GetConverter() // custom type descriptor TypeDescriptionProvider p = _node.Provider; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { - return rp.GetExtendedDefaultEvent(_instance); + return ReflectTypeDescriptionProvider.GetExtendedDefaultEvent(); } ICustomTypeDescriptor desc = p.GetExtendedTypeDescriptor(_instance); @@ -3433,9 +3433,9 @@ TypeConverter ICustomTypeDescriptor.GetConverter() // If so, we can call on it directly rather than creating another // custom type descriptor TypeDescriptionProvider p = _node.Provider; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { - return rp.GetExtendedDefaultProperty(_instance); + return ReflectTypeDescriptionProvider.GetExtendedDefaultProperty(_instance); } ICustomTypeDescriptor desc = p.GetExtendedTypeDescriptor(_instance); @@ -3478,9 +3478,9 @@ EventDescriptorCollection ICustomTypeDescriptor.GetEvents() // If so, we can call on it directly rather than creating another // custom type descriptor TypeDescriptionProvider p = _node.Provider; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { - return rp.GetExtendedEvents(_instance); + return ReflectTypeDescriptionProvider.GetExtendedEvents(_instance); } ICustomTypeDescriptor desc = p.GetExtendedTypeDescriptor(_instance); @@ -3500,13 +3500,13 @@ EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[]? attribute // If so, we can call on it directly rather than creating another // custom type descriptor TypeDescriptionProvider p = _node.Provider; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { // There is no need to filter these events. For extended objects, they // are accessed through our pipeline code, which always filters before // returning. So any filter we do here is redundant. Note that we do // pass a valid filter to a custom descriptor so it can optimize if it wants. - EventDescriptorCollection events = rp.GetExtendedEvents(_instance); + EventDescriptorCollection events = ReflectTypeDescriptionProvider.GetExtendedEvents(_instance); return events; } @@ -3578,9 +3578,9 @@ object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor? pd) TypeDescriptionProvider p = _node.Provider; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { - return rp.GetExtendedPropertyOwner(_instance, pd); + return ReflectTypeDescriptionProvider.GetExtendedPropertyOwner(_instance, pd); } ICustomTypeDescriptor desc = p.GetExtendedTypeDescriptor(_instance); @@ -3675,9 +3675,9 @@ AttributeCollection ICustomTypeDescriptor.GetAttributes() // custom type descriptor TypeDescriptionProvider p = _node.Provider; string? name; - if (p is ReflectTypeDescriptionProvider rp) + if (p is ReflectTypeDescriptionProvider) { - name = rp.GetComponentName(_objectType, _instance); + name = ReflectTypeDescriptionProvider.GetComponentName(_instance); } else { @@ -3924,7 +3924,7 @@ PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[]? at object? owner; if (p is ReflectTypeDescriptionProvider rp) { - owner = rp.GetPropertyOwner(_objectType, _instance!, pd); + owner = ReflectTypeDescriptionProvider.GetPropertyOwner(_objectType, _instance!, pd); } else { diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs index ccdb2c2b572157..0e9d0301f1f925 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs @@ -519,7 +519,7 @@ private SettingsProperty CreateSetting(PropertyInfo propertyInfo) // level and also property level, the latter overrides the former // for a given setting. This is exactly the behavior we want. - settingsProperty.Attributes.Add(attribute.GetType(), attribute); + settingsProperty.Attributes[attribute.GetType()] = attribute; } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ApplicationSettingsBaseTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ApplicationSettingsBaseTests.cs index 20a29b62154874..b1d976f24b89ca 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ApplicationSettingsBaseTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/ApplicationSettingsBaseTests.cs @@ -96,6 +96,37 @@ public override void Initialize(string name, NameValueCollection config) } +#nullable enable + public class SettingsWithNullableAttribute : ApplicationSettingsBase + { + [ApplicationScopedSetting] + public string StringProperty + { + get + { + return (string)this[nameof(StringProperty)]; + } + set + { + this[nameof(StringProperty)] = value; + } + } + + [UserScopedSetting] + public string? NullableStringProperty + { + get + { + return (string)this[nameof(NullableStringProperty)]; + } + set + { + this[nameof(NullableStringProperty)] = value; + } + } + } +#nullable disable + private class PersistedSimpleSettings : SimpleSettings { } @@ -315,5 +346,27 @@ public void OnSettingsLoaded_QueryProperty() Assert.Equal(newStringPropertyValue, settings.StringProperty); Assert.True(loadedFired); } + + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + [Fact] + public void SettingsProperty_SettingsWithNullableAttributes_Ok() + { + SettingsWithNullableAttribute settings = new SettingsWithNullableAttribute(); + + Assert.Null(settings.NullableStringProperty); + + string newValue = null; + + settings.SettingChanging += (object sender, SettingChangingEventArgs e) + => + { + newValue = (string)e.NewValue; + }; + + settings.NullableStringProperty = "test"; + + Assert.Equal("test", newValue); + Assert.Equal(newValue, settings.NullableStringProperty); + } } } diff --git a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs index 28cd4f7494b1d9..7538f21eac709d 100644 --- a/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs +++ b/src/libraries/System.Data.Common/tests/System/Data/DataTableTest.cs @@ -3566,6 +3566,7 @@ public void Remote() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/62965", TestPlatforms.Browser)] // fails on NodeJS on windows public void Bug55978() { DataTable dt = new DataTable(); diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs index 46f02c47e8e93d..616111cc36cbf8 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs @@ -684,13 +684,15 @@ internal string PartUriExtension { if (_partUriExtension == null) { - _partUriExtension = Path.GetExtension(_partUriString); + string partUriExtension = Path.GetExtension(_partUriString); //If extension is absent just return the empty string //else remove the leading "." from the returned extension //string - if (_partUriExtension.Length > 0) - _partUriExtension = _partUriExtension.Substring(1); + if (partUriExtension.Length > 0) + partUriExtension = partUriExtension.Substring(1); + + _partUriExtension = partUriExtension; } return _partUriExtension; } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs index 3b4c247b8b7032..07133b2667c229 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs @@ -1120,6 +1120,7 @@ private void SetSessionHandleOptions(SafeWinHttpHandle sessionHandle) SetSessionHandleTimeoutOptions(sessionHandle); SetDisableHttp2StreamQueue(sessionHandle); SetTcpKeepalive(sessionHandle); + SetRequireStreamEnd(sessionHandle); } private unsafe void SetTcpKeepalive(SafeWinHttpHandle sessionHandle) @@ -1145,6 +1146,27 @@ private unsafe void SetTcpKeepalive(SafeWinHttpHandle sessionHandle) } } + private void SetRequireStreamEnd(SafeWinHttpHandle sessionHandle) + { + if (WinHttpTrailersHelper.OsSupportsTrailers) + { + // Setting WINHTTP_OPTION_REQUIRE_STREAM_END to TRUE is needed for WinHttp to read trailing headers + // in case the response has Content-Lenght defined. + // According to the WinHttp team, the feature-detection logic in WinHttpTrailersHelper.OsSupportsTrailers + // should also indicate the support of WINHTTP_OPTION_REQUIRE_STREAM_END. + // WINHTTP_OPTION_REQUIRE_STREAM_END doesn't have effect on HTTP 1.1 requests, therefore it's safe to set it on + // the session handle so it is inhereted by all request handles. + uint optionData = 1; + if (!Interop.WinHttp.WinHttpSetOption(sessionHandle, Interop.WinHttp.WINHTTP_OPTION_REQUIRE_STREAM_END, ref optionData)) + { + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, "Failed to enable WINHTTP_OPTION_REQUIRE_STREAM_END error code: " + Marshal.GetLastWin32Error()); + } + } + } + } + private void SetSessionHandleConnectionOptions(SafeWinHttpHandle sessionHandle) { uint optionData = (uint)_maxConnectionsPerServer; diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/TrailingHeadersTest.cs b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/TrailingHeadersTest.cs index cef52465524dcf..5ac753c266ee0a 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/TrailingHeadersTest.cs +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/TrailingHeadersTest.cs @@ -67,8 +67,10 @@ public async Task Http2GetAsync_NoTrailingHeaders_EmptyCollection() } } - [ConditionalFact(nameof(TestsEnabled))] - public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted() + [InlineData(false)] + [InlineData(true)] + [ConditionalTheory(nameof(TestsEnabled))] + public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted(bool responseHasContentLength) { using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) using (HttpClient client = CreateHttpClient()) @@ -80,7 +82,14 @@ public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted() int streamId = await connection.ReadRequestHeaderAsync(); // Response header. - await connection.SendDefaultResponseHeadersAsync(streamId); + if (responseHasContentLength) + { + await connection.SendResponseHeadersAsync(streamId, endStream: false, headers: new[] { new HttpHeaderData("Content-Length", DataBytes.Length.ToString()) }); + } + else + { + await connection.SendDefaultResponseHeadersAsync(streamId); + } // Response data, missing Trailers. await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes)); @@ -98,8 +107,10 @@ public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted() } } - [ConditionalFact(nameof(TestsEnabled))] - public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Available() + [InlineData(false)] + [InlineData(true)] + [ConditionalTheory(nameof(TestsEnabled))] + public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Available(bool responseHasContentLength) { using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) using (HttpClient client = CreateHttpClient()) @@ -111,7 +122,14 @@ public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Availab int streamId = await connection.ReadRequestHeaderAsync(); // Response header. - await connection.SendDefaultResponseHeadersAsync(streamId); + if (responseHasContentLength) + { + await connection.SendResponseHeadersAsync(streamId, endStream: false, headers: new[] { new HttpHeaderData("Content-Length", DataBytes.Length.ToString()) }); + } + else + { + await connection.SendDefaultResponseHeadersAsync(streamId); + } // Response data, missing Trailers. await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes)); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs index f07fdbd72a6c04..addd5ae321d040 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Globalization; -using System.IO; using System.Text; namespace System.Net.Http.Headers @@ -22,9 +21,6 @@ internal static class HeaderUtilities internal const string BytesUnit = "bytes"; - // Validator - internal static readonly Action, string> TokenValidator = ValidateToken; - internal static void SetQuality(UnvalidatedObjectCollection parameters, double? value) { Debug.Assert(parameters != null); @@ -372,11 +368,6 @@ internal static void DumpHeaders(StringBuilder sb, params HttpHeaders?[] headers sb.Append('}'); } - private static void ValidateToken(HttpHeaderValueCollection collection, string value) - { - CheckValidToken(value, "item"); - } - internal static UnvalidatedObjectCollection? Clone(this UnvalidatedObjectCollection? source) { if (source == null) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs index 92a88c22a3edfd..bae8addd668fec 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs @@ -22,8 +22,7 @@ public ICollection Allow { if (_allow == null) { - _allow = new HttpHeaderValueCollection(KnownHeaders.Allow.Descriptor, - this, HeaderUtilities.TokenValidator); + _allow = new HttpHeaderValueCollection(KnownHeaders.Allow.Descriptor, this); } return _allow; } @@ -43,8 +42,7 @@ public ICollection ContentEncoding { if (_contentEncoding == null) { - _contentEncoding = new HttpHeaderValueCollection(KnownHeaders.ContentEncoding.Descriptor, - this, HeaderUtilities.TokenValidator); + _contentEncoding = new HttpHeaderValueCollection(KnownHeaders.ContentEncoding.Descriptor, this); } return _contentEncoding; } @@ -56,8 +54,7 @@ public ICollection ContentLanguage { if (_contentLanguage == null) { - _contentLanguage = new HttpHeaderValueCollection(KnownHeaders.ContentLanguage.Descriptor, - this, HeaderUtilities.TokenValidator); + _contentLanguage = new HttpHeaderValueCollection(KnownHeaders.ContentLanguage.Descriptor, this); } return _contentLanguage; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs index 0acffa6098ac80..b5fae3e1eec5ea 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs @@ -27,11 +27,6 @@ public CacheControlHeaderValue? CacheControl set { _parent.SetOrRemoveParsedValue(KnownHeaders.CacheControl.Descriptor, value); } } - public HttpHeaderValueCollection Connection - { - get { return ConnectionCore; } - } - public bool? ConnectionClose { get @@ -46,30 +41,23 @@ public bool? ConnectionClose if (value == true) { _connectionCloseSet = true; - ConnectionCore.SetSpecialValue(); + if (!_parent.ContainsParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose)) + { + _parent.AddParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose); + } } else { _connectionCloseSet = value != null; - ConnectionCore.RemoveSpecialValue(); + // We intentionally ignore the return value. It's OK if "close" wasn't in the store. + _parent.RemoveParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose); } } } internal static bool? GetConnectionClose(HttpHeaders parent, HttpGeneralHeaders? headers) { - // If we've already initialized the connection header value collection - // and it contains the special value, or if we haven't and the headers contain - // the parsed special value, return true. We don't just access ConnectionCore, - // as doing so will unnecessarily initialize the collection even if it's not needed. - if (headers?._connection != null) - { - if (headers._connection.IsSpecialValueSet) - { - return true; - } - } - else if (parent.ContainsParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose)) + if (parent.ContainsParsedValue(KnownHeaders.Connection.Descriptor, HeaderUtilities.ConnectionClose)) { return true; } @@ -104,32 +92,15 @@ public HttpHeaderValueCollection Trailer { if (_trailer == null) { - _trailer = new HttpHeaderValueCollection(KnownHeaders.Trailer.Descriptor, - _parent, HeaderUtilities.TokenValidator); + _trailer = new HttpHeaderValueCollection(KnownHeaders.Trailer.Descriptor, _parent); } return _trailer; } } - public HttpHeaderValueCollection TransferEncoding - { - get { return TransferEncodingCore; } - } - internal static bool? GetTransferEncodingChunked(HttpHeaders parent, HttpGeneralHeaders? headers) { - // If we've already initialized the transfer encoding header value collection - // and it contains the special value, or if we haven't and the headers contain - // the parsed special value, return true. We don't just access TransferEncodingCore, - // as doing so will unnecessarily initialize the collection even if it's not needed. - if (headers?._transferEncoding != null) - { - if (headers._transferEncoding.IsSpecialValueSet) - { - return true; - } - } - else if (parent.ContainsParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked)) + if (parent.ContainsParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked)) { return true; } @@ -154,12 +125,16 @@ public bool? TransferEncodingChunked if (value == true) { _transferEncodingChunkedSet = true; - TransferEncodingCore.SetSpecialValue(); + if (!_parent.ContainsParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked)) + { + _parent.AddParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked); + } } else { _transferEncodingChunkedSet = value != null; - TransferEncodingCore.RemoveSpecialValue(); + // We intentionally ignore the return value. It's OK if "chunked" wasn't in the store. + _parent.RemoveParsedValue(KnownHeaders.TransferEncoding.Descriptor, HeaderUtilities.TransferEncodingChunked); } } } @@ -200,27 +175,25 @@ public HttpHeaderValueCollection Warning } } - private HttpHeaderValueCollection ConnectionCore + public HttpHeaderValueCollection Connection { get { if (_connection == null) { - _connection = new HttpHeaderValueCollection(KnownHeaders.Connection.Descriptor, - _parent, HeaderUtilities.ConnectionClose, HeaderUtilities.TokenValidator); + _connection = new HttpHeaderValueCollection(KnownHeaders.Connection.Descriptor, _parent); } return _connection; } } - private HttpHeaderValueCollection TransferEncodingCore + public HttpHeaderValueCollection TransferEncoding { get { if (_transferEncoding == null) { - _transferEncoding = new HttpHeaderValueCollection( - KnownHeaders.TransferEncoding.Descriptor, _parent, HeaderUtilities.TransferEncodingChunked); + _transferEncoding = new HttpHeaderValueCollection(KnownHeaders.TransferEncoding.Descriptor, _parent); } return _transferEncoding; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs index 68ba04e5b67815..97c458a6d6b855 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.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.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -35,8 +34,6 @@ public sealed class HttpHeaderValueCollection : ICollection where T : clas { private readonly HeaderDescriptor _descriptor; private readonly HttpHeaders _store; - private readonly T? _specialValue; - private readonly Action, T>? _validator; public int Count { @@ -48,45 +45,10 @@ public bool IsReadOnly get { return false; } } - internal bool IsSpecialValueSet - { - get - { - // If this collection instance has a "special value", then check whether that value was already set. - if (_specialValue == null) - { - return false; - } - return _store.ContainsParsedValue(_descriptor, _specialValue); - } - } - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store) - : this(descriptor, store, null, null) { - } - - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, - Action, T> validator) - : this(descriptor, store, null, validator) - { - } - - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, T specialValue) - : this(descriptor, store, specialValue, null) - { - } - - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, T? specialValue, - Action, T>? validator) - { - Debug.Assert(descriptor.Name != null); - Debug.Assert(store != null); - _store = store; _descriptor = descriptor; - _specialValue = specialValue; - _validator = validator; } public void Add(T item) @@ -204,27 +166,6 @@ public override string ToString() return _store.GetHeaderString(_descriptor); } - internal void SetSpecialValue() - { - Debug.Assert(_specialValue != null, - "This method can only be used if the collection has a 'special value' set."); - - if (!_store.ContainsParsedValue(_descriptor, _specialValue)) - { - _store.AddParsedValue(_descriptor, _specialValue); - } - } - - internal void RemoveSpecialValue() - { - Debug.Assert(_specialValue != null, - "This method can only be used if the collection has a 'special value' set."); - - // We're not interested in the return value. It's OK if the "special value" wasn't in the store - // before calling RemoveParsedValue(). - _store.RemoveParsedValue(_descriptor, _specialValue); - } - private void CheckValue(T item) { if (item == null) @@ -232,10 +173,13 @@ private void CheckValue(T item) throw new ArgumentNullException(nameof(item)); } - // If this instance has a custom validator for validating arguments, call it now. - if (_validator != null) + if (_descriptor.Parser == GenericHeaderParser.TokenListParser) { - _validator(this, item); + // The collection expects valid HTTP tokens, which are typed as string. + // Unlike other parsed values (which are always valid by construction), + // we can't assume the provided string is a valid token. So validate it before we use it. + Debug.Assert(typeof(T) == typeof(string)); + HeaderUtilities.CheckValidToken((string)(object)item, nameof(item)); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs index 1731a954bf0a8d..684728b19c55ba 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs @@ -51,26 +51,17 @@ public AuthenticationHeaderValue? Authorization set { SetOrRemoveParsedValue(KnownHeaders.Authorization.Descriptor, value); } } - public HttpHeaderValueCollection Expect - { - get { return ExpectCore; } - } - public bool? ExpectContinue { get { - // ExpectCore will force the collection into existence, so avoid accessing it if possible. - if (_expectContinueSet || ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue)) + if (ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue)) { - if (ExpectCore.IsSpecialValueSet) - { - return true; - } - if (_expectContinueSet) - { - return false; - } + return true; + } + if (_expectContinueSet) + { + return false; } return null; @@ -80,12 +71,16 @@ public bool? ExpectContinue if (value == true) { _expectContinueSet = true; - ExpectCore.SetSpecialValue(); + if (!ContainsParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue)) + { + AddParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue); + } } else { _expectContinueSet = value != null; - ExpectCore.RemoveSpecialValue(); + // We intentionally ignore the return value. It's OK if "100-continue" wasn't in the store. + RemoveParsedValue(KnownHeaders.Expect.Descriptor, HeaderUtilities.ExpectContinue); } } } @@ -189,8 +184,8 @@ public Uri? Referrer public HttpHeaderValueCollection UserAgent => GetSpecializedCollection(UserAgentSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.UserAgent.Descriptor, thisRef)); - private HttpHeaderValueCollection ExpectCore => - _expect ??= new HttpHeaderValueCollection(KnownHeaders.Expect.Descriptor, this, HeaderUtilities.ExpectContinue); + public HttpHeaderValueCollection Expect => + _expect ??= new HttpHeaderValueCollection(KnownHeaders.Expect.Descriptor, this); #endregion diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs index 2c03f00acf7972..442db3beb2f49b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs @@ -35,7 +35,7 @@ private T GetSpecializedCollection(int slot, Func cre } public HttpHeaderValueCollection AcceptRanges => - GetSpecializedCollection(AcceptRangesSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptRanges.Descriptor, thisRef, HeaderUtilities.TokenValidator)); + GetSpecializedCollection(AcceptRangesSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptRanges.Descriptor, thisRef)); public TimeSpan? Age { @@ -68,7 +68,7 @@ public RetryConditionHeaderValue? RetryAfter GetSpecializedCollection(ServerSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Server.Descriptor, thisRef)); public HttpHeaderValueCollection Vary => - GetSpecializedCollection(VarySlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Vary.Descriptor, thisRef, HeaderUtilities.TokenValidator)); + GetSpecializedCollection(VarySlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Vary.Descriptor, thisRef)); public HttpHeaderValueCollection WwwAuthenticate => GetSpecializedCollection(WwwAuthenticateSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.WWWAuthenticate.Descriptor, thisRef)); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs index b399e5674267c9..87e98fb7d4681b 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http3.cs @@ -1349,7 +1349,9 @@ public static TheoryData InteropUrisWithContent() => new TheoryData { { "https://cloudflare-quic.com/" }, // Cloudflare with content - { "https://pgjones.dev/" }, // aioquic with content + // This endpoint is consistently failing. + // [ActiveIssue("https://github.com/dotnet/runtime/issues/63009")] + //{ "https://pgjones.dev/" }, // aioquic with content }; } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index e2c8c2d68891a2..3c011b669ca9a4 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -837,8 +837,10 @@ public async Task Http2GetAsync_NoTrailingHeaders_EmptyCollection() } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] - public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted() + [InlineData(false)] + [InlineData(true)] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] + public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted(bool responseHasContentLength) { using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) using (HttpClient client = CreateHttpClient()) @@ -850,7 +852,14 @@ public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted() int streamId = await connection.ReadRequestHeaderAsync(); // Response header. - await connection.SendDefaultResponseHeadersAsync(streamId); + if (responseHasContentLength) + { + await connection.SendResponseHeadersAsync(streamId, endStream: false, headers: new[] { new HttpHeaderData("Content-Length", DataBytes.Length.ToString()) }); + } + else + { + await connection.SendDefaultResponseHeadersAsync(streamId); + } // Response data, missing Trailers. await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes)); @@ -888,8 +897,10 @@ public async Task Http2GetAsync_TrailerHeaders_TrailingPseudoHeadersThrow() } } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] - public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Available() + [InlineData(false)] + [InlineData(true)] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsAlpn))] + public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Available(bool responseHasContentLength) { using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer()) using (HttpClient client = CreateHttpClient()) @@ -901,7 +912,14 @@ public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Availab int streamId = await connection.ReadRequestHeaderAsync(); // Response header. - await connection.SendDefaultResponseHeadersAsync(streamId); + if (responseHasContentLength) + { + await connection.SendResponseHeadersAsync(streamId, endStream: false, headers: new[] { new HttpHeaderData("Content-Length", DataBytes.Length.ToString()) }); + } + else + { + await connection.SendDefaultResponseHeadersAsync(streamId); + } // Response data, missing Trailers. await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes)); diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs index cab7599b16ea95..dec7eb661f7cf6 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeaderValueCollectionTest.cs @@ -1,12 +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; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; -using System.Text; using Xunit; @@ -18,8 +16,6 @@ public class HttpHeaderValueCollectionTest private static readonly HeaderDescriptor knownStringHeader = (new KnownHeader("known-string-header", HttpHeaderType.General, new MockHeaderParser(typeof(string)))).Descriptor; private static readonly HeaderDescriptor knownUriHeader = (new KnownHeader("known-uri-header", HttpHeaderType.General, new MockHeaderParser(typeof(Uri)))).Descriptor; - private static readonly Uri specialValue = new Uri("http://special/"); - private static readonly Uri invalidValue = new Uri("http://invalid/"); private static readonly TransferCodingHeaderValue specialChunked = new TransferCodingHeaderValue("chunked"); // Note that this type just forwards calls to HttpHeaders. So this test method focuses on making sure @@ -34,45 +30,6 @@ public void IsReadOnly_CallProperty_AlwaysFalse() Assert.False(collection.IsReadOnly); } - [Fact] - public void Count_AddSingleValueThenQueryCount_ReturnsValueCountWithSpecialValues() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers, - "special"); - - Assert.Equal(0, collection.Count); - - headers.Add(knownStringHeader, "value2"); - Assert.Equal(1, collection.Count); - - headers.Clear(); - headers.Add(knownStringHeader, "special"); - Assert.Equal(1, collection.Count); - headers.Add(knownStringHeader, "special"); - headers.Add(knownStringHeader, "special"); - Assert.Equal(3, collection.Count); - } - - [Fact] - public void Count_AddMultipleValuesThenQueryCount_ReturnsValueCountWithSpecialValues() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers, - "special"); - - Assert.Equal(0, collection.Count); - - collection.Add("value1"); - headers.Add(knownStringHeader, "special"); - Assert.Equal(2, collection.Count); - - headers.Add(knownStringHeader, "special"); - headers.Add(knownStringHeader, "value2"); - headers.Add(knownStringHeader, "special"); - Assert.Equal(5, collection.Count); - } - [Fact] public void Add_CallWithNullValue_Throw() { @@ -86,8 +43,7 @@ public void Add_CallWithNullValue_Throw() public void Add_AddValues_AllValuesAdded() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.Add(new Uri("http://www.example.org/1/")); collection.Add(new Uri("http://www.example.org/2/")); @@ -150,7 +106,6 @@ public void ParseAdd_CallWithNullValue_NothingAdded() HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.ParseAdd(null); - Assert.False(collection.IsSpecialValueSet); Assert.Equal(0, collection.Count); Assert.Equal(string.Empty, collection.ToString()); } @@ -159,8 +114,7 @@ public void ParseAdd_CallWithNullValue_NothingAdded() public void ParseAdd_AddValues_AllValuesAdded() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.ParseAdd("http://www.example.org/1/"); collection.ParseAdd("http://www.example.org/2/"); @@ -169,19 +123,6 @@ public void ParseAdd_AddValues_AllValuesAdded() Assert.Equal(3, collection.Count); } - [Fact] - public void ParseAdd_UseSpecialValue_Added() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.ParseAdd(specialValue.AbsoluteUri); - - Assert.True(collection.IsSpecialValueSet); - Assert.Equal(specialValue.ToString(), collection.ToString()); - } - [Fact] public void ParseAdd_AddBadValue_Throws() { @@ -198,7 +139,6 @@ public void TryParseAdd_CallWithNullValue_NothingAdded() Assert.True(headers.WwwAuthenticate.TryParseAdd(null)); - Assert.False(headers.WwwAuthenticate.IsSpecialValueSet); Assert.Equal(0, headers.WwwAuthenticate.Count); Assert.Equal(string.Empty, headers.WwwAuthenticate.ToString()); } @@ -207,8 +147,7 @@ public void TryParseAdd_CallWithNullValue_NothingAdded() public void TryParseAdd_AddValues_AllAdded() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); Assert.True(collection.TryParseAdd("http://www.example.org/1/")); Assert.True(collection.TryParseAdd("http://www.example.org/2/")); @@ -217,19 +156,6 @@ public void TryParseAdd_AddValues_AllAdded() Assert.Equal(3, collection.Count); } - [Fact] - public void TryParseAdd_UseSpecialValue_Added() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - Assert.True(collection.TryParseAdd(specialValue.AbsoluteUri)); - - Assert.True(collection.IsSpecialValueSet); - Assert.Equal(specialValue.ToString(), collection.ToString()); - } - [Fact] public void TryParseAdd_AddBadValue_False() { @@ -268,27 +194,6 @@ public void Clear_AddValuesThenClear_NoElementsInCollection() Assert.Equal(0, collection.Count); } - [Fact] - public void Clear_AddValuesAndSpecialValueThenClear_EverythingCleared() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.Add(new Uri("http://www.example.org/3/")); - - Assert.Equal(4, collection.Count); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - - collection.Clear(); - - Assert.Equal(0, collection.Count); - Assert.False(collection.IsSpecialValueSet, "Special value was removed by Clear()."); - } - [Fact] public void Contains_CallWithNullValue_Throw() { @@ -389,21 +294,13 @@ public void CopyTo_NoValues_DoesNotChangeArray() public void CopyTo_AddSingleValue_ContainsSingleValue() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers); collection.Add(new Uri("http://www.example.org/")); Uri[] array = new Uri[1]; collection.CopyTo(array, 0); Assert.Equal(new Uri("http://www.example.org/"), array[0]); - - // Now only set the special value: nothing should be added to the array. - headers.Clear(); - headers.Add(knownUriHeader, specialValue.ToString()); - array[0] = null; - collection.CopyTo(array, 0); - Assert.Equal(specialValue, array[0]); } [Fact] @@ -426,79 +323,11 @@ public void CopyTo_AddMultipleValues_ContainsAllValuesInTheRightOrder() Assert.Null(array[4]); } - [Fact] - public void CopyTo_AddValuesAndSpecialValue_AllValuesCopied() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.SetSpecialValue(); - collection.Add(new Uri("http://www.example.org/3/")); - - Uri[] array = new Uri[5]; - collection.CopyTo(array, 1); - - Assert.Null(array[0]); - Assert.Equal(new Uri("http://www.example.org/1/"), array[1]); - Assert.Equal(new Uri("http://www.example.org/2/"), array[2]); - Assert.Equal(specialValue, array[3]); - Assert.Equal(new Uri("http://www.example.org/3/"), array[4]); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void CopyTo_OnlySpecialValue_Copied() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - headers.Add(knownUriHeader, specialValue.ToString()); - headers.Add(knownUriHeader, specialValue.ToString()); - headers.Add(knownUriHeader, specialValue.ToString()); - - Uri[] array = new Uri[4]; - array[0] = null; - collection.CopyTo(array, 0); - - Assert.Equal(specialValue, array[0]); - Assert.Equal(specialValue, array[1]); - Assert.Equal(specialValue, array[2]); - Assert.Equal(specialValue, array[3]); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void CopyTo_OnlySpecialValueEmptyDestination_Copied() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - headers.Add(knownUriHeader, specialValue.ToString()); - - Uri[] array = new Uri[2]; - collection.CopyTo(array, 0); - - Assert.Equal(specialValue, array[0]); - Assert.Equal(specialValue, array[1]); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - [Fact] public void CopyTo_ArrayTooSmall_Throw() { MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers, - "special"); + HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownStringHeader, headers); string[] array = new string[1]; array[0] = null; @@ -665,170 +494,6 @@ public void GetEnumerator_AddValuesAndGetEnumeratorFromInterface_AllValuesReturn } } - [Fact] - public void GetEnumerator_AddValuesAndSpecialValueAndGetEnumeratorFromInterface_AllValuesReturned() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.Add(new Uri("http://www.example.org/3/")); - collection.SetSpecialValue(); - - System.Collections.IEnumerable enumerable = collection; - - // The "special value" should be ignored and not part of the resulting collection. - int i = 1; - bool specialFound = false; - foreach (var item in enumerable) - { - if (item.Equals(specialValue)) - { - specialFound = true; - } - else - { - Assert.Equal(new Uri("http://www.example.org/" + i + "/"), item); - i++; - } - } - - Assert.True(specialFound); - - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void GetEnumerator_AddValuesAndSpecialValue_AllValuesReturned() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.SetSpecialValue(); - collection.Add(new Uri("http://www.example.org/3/")); - - System.Collections.IEnumerable enumerable = collection; - - // The special value we added above, must be part of the collection returned by GetEnumerator(). - int i = 1; - bool specialFound = false; - foreach (var item in enumerable) - { - if (item.Equals(specialValue)) - { - specialFound = true; - } - else - { - Assert.Equal(new Uri("http://www.example.org/" + i + "/"), item); - i++; - } - } - - Assert.True(specialFound); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - } - - [Fact] - public void IsSpecialValueSet_NoSpecialValueUsed_ReturnsFalse() - { - // Create a new collection _without_ specifying a special value. - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - null, null); - - Assert.False(collection.IsSpecialValueSet, - "Special value is set even though collection doesn't define a special value."); - } - - [Fact] - public void RemoveSpecialValue_AddRemoveSpecialValue_SpecialValueGetsRemoved() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.SetSpecialValue(); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - Assert.Equal(1, headers.GetValues(knownUriHeader).Count()); - - collection.RemoveSpecialValue(); - Assert.False(collection.IsSpecialValueSet, "Special value is set."); - - // Since the only header value was the "special value", removing it will remove the whole header - // from the collection. - Assert.False(headers.Contains(knownUriHeader)); - } - - [Fact] - public void RemoveSpecialValue_AddValueAndSpecialValueThenRemoveSpecialValue_SpecialValueGetsRemoved() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/")); - collection.SetSpecialValue(); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - Assert.Equal(2, headers.GetValues(knownUriHeader).Count()); - - collection.RemoveSpecialValue(); - Assert.False(collection.IsSpecialValueSet, "Special value is set."); - Assert.Equal(1, headers.GetValues(knownUriHeader).Count()); - } - - [Fact] - public void RemoveSpecialValue_AddTwoValuesAndSpecialValueThenRemoveSpecialValue_SpecialValueGetsRemoved() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue); - - collection.Add(new Uri("http://www.example.org/1/")); - collection.Add(new Uri("http://www.example.org/2/")); - collection.SetSpecialValue(); - Assert.True(collection.IsSpecialValueSet, "Special value not set."); - Assert.Equal(3, headers.GetValues(knownUriHeader).Count()); - - // The difference between this test and the previous one is that HttpHeaders in this case will use - // a List to store the two remaining values, whereas in the previous case it will just store - // the remaining value (no list). - collection.RemoveSpecialValue(); - Assert.False(collection.IsSpecialValueSet, "Special value is set."); - Assert.Equal(2, headers.GetValues(knownUriHeader).Count()); - } - - [Fact] - public void Ctor_ProvideValidator_ValidatorIsUsedWhenAddingValues() - { - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - MockValidator); - - // Adding an arbitrary Uri should not throw. - collection.Add(new Uri("http://some/")); - - // When we add 'invalidValue' our MockValidator will throw. - Assert.Throws(() => { collection.Add(invalidValue); }); - } - - [Fact] - public void Ctor_ProvideValidator_ValidatorIsUsedWhenRemovingValues() - { - // Use different ctor overload than in previous test to make sure all ctor overloads work correctly. - MockHeaders headers = new MockHeaders(); - HttpHeaderValueCollection collection = new HttpHeaderValueCollection(knownUriHeader, headers, - specialValue, MockValidator); - - // When we remove 'invalidValue' our MockValidator will throw. - Assert.Throws(() => { collection.Remove(invalidValue); }); - } - [Fact] public void ToString_SpecialValues_Success() { @@ -895,14 +560,6 @@ public void ToString_EmptyValue_Success() #region Helper methods - private static void MockValidator(HttpHeaderValueCollection collection, Uri value) - { - if (value == invalidValue) - { - throw new MockException(); - } - } - public class MockException : Exception { public MockException() { } diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index 0618f1644ea325..3def281c2bcab2 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -6,10 +6,14 @@ https://github.com/mono/linker/pull/649 --> + - + + 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 4c4c1e0f436704..bfee74c906581c 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 @@ -2111,6 +2111,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContext.cs b/src/libraries/System.Private.CoreLib/src/System/AppContext.cs index 35e45f472bb8b1..6b28c7b2a561d7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppContext.cs @@ -45,6 +45,12 @@ public static partial class AppContext return data; } + /// + /// Sets the value of the named data element assigned to the current application domain. + /// + /// The name of the data element + /// The value of + /// If is public static void SetData(string name, object? data) { if (name == null) diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.Android.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Android.cs similarity index 100% rename from src/mono/System.Private.CoreLib/src/System/Environment.Android.cs rename to src/libraries/System.Private.CoreLib/src/System/Environment.Android.cs 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 98260abc44e3b4..6b0c66fbd361a2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -420,9 +420,9 @@ internal sealed partial class CultureData { return CultureData.Invariant; } - CultureData? retVal = null; + // First check if GetCultureData() can find it (ie: its a real culture) - retVal = GetCultureData(cultureName, useUserOverride); + CultureData? retVal = GetCultureData(cultureName, useUserOverride); if (retVal != null && !retVal.IsNeutralCulture) { return retVal; @@ -853,7 +853,6 @@ private bool InitCompatibilityCultureData() /// We'd rather people use the named version since this doesn't allow custom locales internal static CultureData GetCultureData(int culture, bool bUseUserOverride) { - string? localeName = null; CultureData? retVal = null; if (culture == CultureInfo.LOCALE_INVARIANT) @@ -868,7 +867,7 @@ internal static CultureData GetCultureData(int culture, bool bUseUserOverride) } // Convert the lcid to a name, then use that - localeName = LCIDToLocaleName(culture); + string? localeName = LCIDToLocaleName(culture); if (!string.IsNullOrEmpty(localeName)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs index ccbe08edb6899b..429f55d5db1746 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs @@ -332,7 +332,7 @@ private static StringBuilder FormatCustomized(TimeSpan value, ReadOnlySpan int seconds = (int)(time / TimeSpan.TicksPerSecond % 60); int fraction = (int)(time % TimeSpan.TicksPerSecond); - long tmp = 0; + long tmp; int i = 0; int tokenLen; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs index 39532de1f3e11d..cea8148a7d9186 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs @@ -557,7 +557,7 @@ protected virtual void FillBuffer(int numBytes) } int bytesRead = 0; - int n = 0; + int n; ThrowIfDisposed(); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Exists.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Exists.Unix.cs index 1037b4020f7099..172a956201dd86 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Exists.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Exists.Unix.cs @@ -10,8 +10,7 @@ internal static partial class FileSystem { public static bool DirectoryExists(ReadOnlySpan fullPath) { - Interop.ErrorInfo ignored; - return DirectoryExists(fullPath, out ignored); + return DirectoryExists(fullPath, out _); } private static bool DirectoryExists(ReadOnlySpan fullPath, out Interop.ErrorInfo errorInfo) @@ -30,8 +29,7 @@ private static bool DirectoryExists(ReadOnlySpan fullPath, out Interop.Err public static bool FileExists(ReadOnlySpan fullPath) { - Interop.ErrorInfo ignored; - return FileExists(fullPath, out ignored); + return FileExists(fullPath, out _); } private static bool FileExists(ReadOnlySpan fullPath, out Interop.ErrorInfo errorInfo) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs index a2d35f500e00c3..566d3686ce5e16 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs @@ -159,8 +159,7 @@ public static void ReplaceFile(string sourceFullPath, string destFullPath, strin else { // There is no backup file. Just make sure the destination file exists, throwing if it doesn't. - Interop.Sys.FileStatus ignored; - if (Interop.Sys.Stat(destFullPath, out ignored) != 0) + if (Interop.Sys.Stat(destFullPath, out _) != 0) { Interop.ErrorInfo errno = Interop.Sys.GetLastErrorInfo(); if (errno.Error == Interop.Error.ENOENT) diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs index c940600ee8c256..a053b29f6362c9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs @@ -191,7 +191,7 @@ internal ResourceSet CreateResourceSet(Stream store, Assembly assembly) if (bytes == ResourceManager.MagicNumber) { int resMgrHeaderVersion = br.ReadInt32(); - string? readerTypeName = null, resSetTypeName = null; + string? readerTypeName, resSetTypeName; if (resMgrHeaderVersion == ResourceManager.HeaderVersionNumber) { br.ReadInt32(); // We don't want the number of bytes to skip. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs index b26b993623f1d3..7e3666d23314d7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs @@ -78,7 +78,7 @@ internal TaskAwaiter(Task task) /// The action to invoke when the await operation completes. /// The argument is null (Nothing in Visual Basic). /// The awaiter was not properly initialized. - /// This method is intended for compiler user rather than use directly in code. + /// This method is intended for compiler use rather than use directly in code. public void OnCompleted(Action continuation) { OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeMemory.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeMemory.Unix.cs index 4dc1f1b7f5aa58..dfc3692d1d7416 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeMemory.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeMemory.Unix.cs @@ -148,7 +148,7 @@ public static void AlignedFree(void* ptr) [CLSCompliant(false)] public static void* AllocZeroed(nuint elementCount, nuint elementSize) { - void* result = null; + void* result; if ((elementCount != 0) && (elementSize != 0)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs index 3e7f204573ca05..e2a3b7bdecd9aa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs @@ -153,8 +153,6 @@ public void AcquirePointer(ref byte* pointer) if (_numBytes == Uninitialized) throw NotInitialized(); - pointer = null; - bool junk = false; DangerousAddRef(ref junk); pointer = (byte*)handle; diff --git a/src/libraries/System.Private.CoreLib/src/System/Span.cs b/src/libraries/System.Private.CoreLib/src/System/Span.cs index a5580b2472d078..b512a53a632a7b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Span.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Span.cs @@ -284,18 +284,11 @@ public void Fill(T value) { if (Unsafe.SizeOf() == 1) { -#if MONO - // Mono runtime's implementation of initblk performs a null check on the address. - // We'll perform a length check here to avoid passing a null address in the empty span case. - if (_length != 0) -#endif - { - // Special-case single-byte types like byte / sbyte / bool. - // The runtime eventually calls memset, which can efficiently support large buffers. - // We don't need to check IsReferenceOrContainsReferences because no references - // can ever be stored in types this small. - Unsafe.InitBlockUnaligned(ref Unsafe.As(ref _pointer.Value), Unsafe.As(ref value), (uint)_length); - } + // Special-case single-byte types like byte / sbyte / bool. + // The runtime eventually calls memset, which can efficiently support large buffers. + // We don't need to check IsReferenceOrContainsReferences because no references + // can ever be stored in types this small. + Unsafe.InitBlockUnaligned(ref Unsafe.As(ref _pointer.Value), Unsafe.As(ref value), (uint)_length); } else { diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs index a5c8f9ae79a602..684bce9d96f2fd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs @@ -300,8 +300,8 @@ internal static unsafe int IndexOfValueType(ref T searchSpace, T value, int l if (Vector.IsHardwareAccelerated && Vector.IsTypeSupported && (Vector.Count * 2) <= length) { Vector valueVector = new Vector(value); - Vector compareVector = default; - Vector matchVector = default; + Vector compareVector; + Vector matchVector; if ((uint)length % (uint)Vector.Count != 0) { // Number of elements is not a multiple of Vector.Count, so do one diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/EncoderNLS.cs b/src/libraries/System.Private.CoreLib/src/System/Text/EncoderNLS.cs index 630ebbd3202283..9a1d340ae6617d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/EncoderNLS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/EncoderNLS.cs @@ -300,8 +300,6 @@ internal int DrainLeftoverDataForGetByteCount(ReadOnlySpan chars, out int // fallback buffer with the invalid data. We'll just fall through to the "consume // fallback buffer" logic at the end of the method. - bool didFallback; - if (Rune.TryCreate(_charLeftOver, secondChar, out Rune rune)) { charsConsumed = 1; // consumed the leftover high surrogate + the first char in the input buffer @@ -320,12 +318,12 @@ internal int DrainLeftoverDataForGetByteCount(ReadOnlySpan chars, out int // character from a previous operation, so we provide an index of -1 to convey that the // char immediately before the current buffer was the start of the invalid sequence. - didFallback = FallbackBuffer.Fallback(_charLeftOver, secondChar, index: -1); + FallbackBuffer.Fallback(_charLeftOver, secondChar, index: -1); } } else { - didFallback = FallbackBuffer.Fallback(_charLeftOver, index: -1); + FallbackBuffer.Fallback(_charLeftOver, index: -1); } // Now tally the number of bytes that would've been emitted as part of fallback. diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs index 6ce99198c9c156..c5113ec6365345 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs @@ -158,7 +158,6 @@ private unsafe void ThreadPoolIOEnqueue( bool MultiDequeues, ushort ClrInstanceID = DefaultClrInstanceId) { - int multiDequeuesInt = Convert.ToInt32(MultiDequeues); // bool maps to "win:Boolean", a 4-byte boolean LogThreadPoolIOEnqueue(NativeOverlapped, Overlapped, MultiDequeues, ClrInstanceID); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs index 3a2b10096887d0..7cb860621e3088 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs @@ -447,7 +447,7 @@ private Complex GetWaveComponent(double[] samples, int numSamples, double period double w = 2 * Math.PI / period; double cos = Math.Cos(w); double coeff = 2 * cos; - double q0 = 0, q1 = 0, q2 = 0; + double q0, q1 = 0, q2 = 0; for (int i = 0; i < numSamples; ++i) { q0 = coeff * q1 - q2 + samples[(_totalSamples - numSamples + i) % _samplesToMeasure]; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs index d8767a5158973d..20a3c5b8b3bd62 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs @@ -515,7 +515,7 @@ private bool TryEnterWriteLockCore(TimeoutTracker timeout) } } - bool retVal = true; + bool retVal; int spinCount = 0; while (true) @@ -710,7 +710,6 @@ private bool TryEnterUpgradeableReadLockCore(TimeoutTracker timeout) } } - bool retVal = true; int spinCount = 0; while (true) @@ -748,7 +747,7 @@ private bool TryEnterUpgradeableReadLockCore(TimeoutTracker timeout) } // Only one thread with the upgrade lock held can proceed. - retVal = WaitOnEvent(_upgradeEvent, ref _numUpgradeWaiters, timeout, EnterLockType.UpgradeableRead); + bool retVal = WaitOnEvent(_upgradeEvent, ref _numUpgradeWaiters, timeout, EnterLockType.UpgradeableRead); if (!retVal) return false; } diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs index 9c470c8ac50753..f0b865a3a48578 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs @@ -333,9 +333,8 @@ public static TimeZoneInfo FindSystemTimeZoneById(string id) // DateTime.Now fast path that avoids allocating an historically accurate TimeZoneInfo.Local and just creates a 1-year (current year) accurate time zone internal static TimeSpan GetDateTimeNowUtcOffsetFromUtc(DateTime time, out bool isAmbiguousLocalDst) { - bool isDaylightSavings; // Use the standard code path for Unix since there isn't a faster way of handling current-year-only time zones - return GetUtcOffsetFromUtc(time, Local, out isDaylightSavings, out isAmbiguousLocalDst); + return GetUtcOffsetFromUtc(time, Local, out _, out isAmbiguousLocalDst); } // TZFILE(5) BSD File Formats Manual TZFILE(5) @@ -676,7 +675,7 @@ private static TZifType TZif_GetEarlyDateTransitionType(TZifType[] transitionTyp private static AdjustmentRule? TZif_CreateAdjustmentRuleForPosixFormat(string posixFormat, DateTime startTransitionDate, TimeSpan timeZoneBaseUtcOffset) { if (TZif_ParsePosixFormat(posixFormat, - out ReadOnlySpan standardName, + out _, out ReadOnlySpan standardOffset, out ReadOnlySpan daylightSavingsName, out ReadOnlySpan daylightSavingsOffset, @@ -982,9 +981,6 @@ private static bool TZif_ParsePosixFormat( out ReadOnlySpan end, out ReadOnlySpan endTime) { - standardName = null; - standardOffset = null; - daylightSavingsName = null; daylightSavingsOffset = null; start = null; startTime = null; @@ -1123,13 +1119,6 @@ private static DateTime TZif_UnixTimeToDateTime(long unixTime) => private static void TZif_ParseRaw(byte[] data, out TZifHead t, out DateTime[] dts, out byte[] typeOfLocalTime, out TZifType[] transitionType, out string zoneAbbreviations, out bool[] StandardTime, out bool[] GmtTime, out string? futureTransitionsPosixFormat) { - // initialize the out parameters in case the TZifHead ctor throws - dts = null!; - typeOfLocalTime = null!; - transitionType = null!; - zoneAbbreviations = string.Empty; - StandardTime = null!; - GmtTime = null!; futureTransitionsPosixFormat = null; // read in the 44-byte TZ header containing the count/length fields @@ -1154,7 +1143,6 @@ private static void TZif_ParseRaw(byte[] data, out TZifHead t, out DateTime[] dt dts = new DateTime[t.TimeCount]; typeOfLocalTime = new byte[t.TimeCount]; transitionType = new TZifType[t.TypeCount]; - zoneAbbreviations = string.Empty; StandardTime = new bool[t.TypeCount]; GmtTime = new bool[t.TypeCount]; diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs index c1e1b2e1025576..894779abe2e357 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs @@ -668,7 +668,6 @@ private static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZo sourceOffset += sourceRule.BaseUtcOffsetDelta; if (sourceRule.HasDaylightSaving) { - bool sourceIsDaylightSavings = false; DaylightTimeStruct sourceDaylightTime = sourceTimeZone.GetDaylightTime(dateTime.Year, sourceRule, sourceRuleIndex); // 'dateTime' might be in an invalid time range since it is in an AdjustmentRule @@ -677,7 +676,7 @@ private static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZo { throw new ArgumentException(SR.Argument_DateTimeIsInvalid, nameof(dateTime)); } - sourceIsDaylightSavings = GetIsDaylightSavings(dateTime, sourceRule, sourceDaylightTime); + bool sourceIsDaylightSavings = GetIsDaylightSavings(dateTime, sourceRule, sourceDaylightTime); // adjust the sourceOffset according to the Adjustment Rule / Daylight Saving Rule sourceOffset += (sourceIsDaylightSavings ? sourceRule.DaylightDelta : TimeSpan.Zero /*FUTURE: sourceRule.StandardDelta*/); @@ -2003,11 +2002,10 @@ private static void ValidateTimeZoneInfo(string id, TimeSpan baseUtcOffset, Adju if (adjustmentRules != null && adjustmentRules.Length != 0) { adjustmentRulesSupportDst = true; - AdjustmentRule? prev = null; AdjustmentRule? current = null; for (int i = 0; i < adjustmentRules.Length; i++) { - prev = current; + AdjustmentRule? prev = current; current = adjustmentRules[i]; if (current == null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs index 8915fc43b037a4..50bbf971cf5aee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs @@ -94,7 +94,7 @@ public virtual string[] GetEnumNames() if (!IsEnum) throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); - GetEnumData(out string[] names, out Array values); + GetEnumData(out string[] names, out _); return names; } diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs index b3139a60a93b27..f8955384981e0e 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs @@ -909,9 +909,10 @@ private static async Task MarshalTask(string helperMethodName, string help @"globalThis.__test_promise_resolved = false; " + @"globalThis.__test_promise_failed = false; " + $@"var t = App.call_test_method ('{helperMethodName}', [ {helperMethodArgs} ], 'i'); " + - "t.finally(result => { globalThis.__test_promise_completed = true; }); " + - "t.then(result => { globalThis.__test_promise_resolved = true; " + resolvedBody + " }); " + - "t.catch(e => { globalThis.__test_promise_failed = true; }); " + "t.then(result => { globalThis.__test_promise_resolved = true; " + resolvedBody + " })" + + " .catch(e => { globalThis.__test_promise_failed = true; })" + + " .finally(result => { globalThis.__test_promise_completed = true; }); " + + "" ); await Task.Delay(1); diff --git a/src/libraries/System.Reflection/src/MatchingRefApiCompatBaseline.txt b/src/libraries/System.Reflection/src/MatchingRefApiCompatBaseline.txt index 47ffa8392dfb7b..93972536f0210c 100644 --- a/src/libraries/System.Reflection/src/MatchingRefApiCompatBaseline.txt +++ b/src/libraries/System.Reflection/src/MatchingRefApiCompatBaseline.txt @@ -1,3 +1,6 @@ Compat issues with assembly System.Reflection: MembersMustExist : Member 'protected System.ModuleHandle System.Reflection.Module.GetModuleHandleImpl()' does not exist in the reference but it does exist in the implementation. -Total Issues: 1 +MembersMustExist : Member 'public System.Reflection.ParameterInfo[] System.Reflection.MethodBase.GetParametersNoCopy()' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.Reflection.MethodBase System.Reflection.MethodBase.MetadataDefinitionMethod.get()' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.Int32 System.Reflection.MethodInfo.GenericParameterCount.get()' does not exist in the reference but it does exist in the implementation. +Total Issues: 4 diff --git a/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj b/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj index 54240fecb8f7e5..71788c421b44ed 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj +++ b/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj @@ -76,7 +76,7 @@ - + diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs index eac8bf18bb1206..658447d52339cf 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs @@ -18,13 +18,13 @@ public void TestMachineNameProperty() internal static string GetComputerName() { #if !Unix - return Environment.GetEnvironmentVariable("COMPUTERNAME"); + return Environment.GetEnvironmentVariable("COMPUTERNAME"); #else - if (PlatformDetection.IsBrowser) - return "localhost"; - string temp = Interop.Sys.GetNodeName(); - int index = temp.IndexOf('.'); - return index < 0 ? temp : temp.Substring(0, index); + if (PlatformDetection.IsBrowser) + return "localhost"; + string temp = Interop.Sys.GetHostName(); + int index = temp.IndexOf('.'); + return index < 0 ? temp : temp.Substring(0, index); #endif } } 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 8c95424f15e577..d678320e017407 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 @@ -23,9 +23,13 @@ + + + + System.Reflection.Metadata.ApplyUpdate.Test. + + - - @@ -38,6 +42,10 @@ + + + + @@ -45,7 +53,6 @@ - @@ -55,14 +62,16 @@ - - - - - - - - + + + + + %(ResolvedFileToPublish.FullPath) + + + + diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index f9462613a698b3..435594f5b9402e 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -112,6 +112,7 @@ public static partial class AppContext public static string BaseDirectory { get { throw null; } } public static string? TargetFrameworkName { get { throw null; } } public static object? GetData(string name) { throw null; } + public static void SetData(string name, object? data) { } public static void SetSwitch(string switchName, bool isEnabled) { } public static bool TryGetSwitch(string switchName, out bool isEnabled) { throw null; } } diff --git a/src/libraries/System.Runtime/src/MatchingRefApiCompatBaseline.txt b/src/libraries/System.Runtime/src/MatchingRefApiCompatBaseline.txt index cbe8cabdbb2956..6c58cd1642bf78 100644 --- a/src/libraries/System.Runtime/src/MatchingRefApiCompatBaseline.txt +++ b/src/libraries/System.Runtime/src/MatchingRefApiCompatBaseline.txt @@ -24,4 +24,13 @@ CannotMakeMemberAbstract : Member 'public System.Boolean System.IO.FileSystemInf CannotMakeMemberAbstract : Member 'public System.String System.IO.FileSystemInfo.Name.get()' is abstract in the reference but is not abstract in the implementation. # C# generates backing fields for fixed buffers as public. TypesMustExist : Type 'System.IO.Enumeration.FileSystemEntry.<_fileNameBuffer>e__FixedBuffer' does not exist in the reference but it does exist in the implementation. - +MembersMustExist : Member 'public void System.ModuleHandle..ctor(System.Reflection.Module)' does not exist in the reference but it does exist in the implementation. +CannotRemoveBaseTypeOrInterface : Type 'System.RuntimeTypeHandle' does not implement interface 'System.IEquatable' in the reference but it does in the implementation. +MembersMustExist : Member 'public System.String System.String System.Type.DefaultTypeNameWhenMissingMetadata' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.String System.Type.FormatTypeNameForReflection()' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.String System.Type.InternalGetNameIfAvailable(System.Type)' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.String System.Type.InternalNameIfAvailable.get()' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.Boolean System.TypedReference.IsNull.get()' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.Reflection.ParameterInfo[] System.Reflection.MethodBase.GetParametersNoCopy()' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.Reflection.MethodBase System.Reflection.MethodBase.MetadataDefinitionMethod.get()' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.Int32 System.Reflection.MethodInfo.GenericParameterCount.get()' does not exist in the reference but it does exist in the implementation. diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index 805d3610003be0..92eb65f2c0ebce 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -144,8 +144,9 @@ - - + + + diff --git a/src/libraries/System.Runtime/tests/System/AppContext/AppContext.Switch.Validation.cs b/src/libraries/System.Runtime/tests/System/AppContext/AppContextTests.Switch.Validation.cs similarity index 100% rename from src/libraries/System.Runtime/tests/System/AppContext/AppContext.Switch.Validation.cs rename to src/libraries/System.Runtime/tests/System/AppContext/AppContextTests.Switch.Validation.cs diff --git a/src/libraries/System.Runtime/tests/System/AppContext/AppContext.Switch.cs b/src/libraries/System.Runtime/tests/System/AppContext/AppContextTests.Switch.cs similarity index 100% rename from src/libraries/System.Runtime/tests/System/AppContext/AppContext.Switch.cs rename to src/libraries/System.Runtime/tests/System/AppContext/AppContextTests.Switch.cs diff --git a/src/libraries/System.Runtime/tests/System/AppContext/AppContextTests.cs b/src/libraries/System.Runtime/tests/System/AppContext/AppContextTests.cs new file mode 100644 index 00000000000000..9b47feed876c80 --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/AppContext/AppContextTests.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 Xunit; + +namespace System.Tests +{ + public partial class AppContextTests + { + [Theory] + [InlineData("AppContext_Case1", 123)] + [InlineData("AppContext_Case2", "")] + [InlineData("AppContext_Case3", null)] + public void AppContext_GetSetDataTest(string dataKey, object value) + { + // Set data + AppContext.SetData(dataKey, value); + + // Get previously set data + object actual = AppContext.GetData(dataKey); + + // Validate instance equality + Assert.Same(value, actual); + } + + [Fact] + public void AppContext_ThrowTest() + { + AssertExtensions.Throws("name", () => AppContext.SetData(null, 123)); + } + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs index 07cea199b510fa..f28b67bcfe29f7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs @@ -11,10 +11,10 @@ namespace System.Text.Json public static partial class JsonSerializer { /// - /// Converts the provided value into a . + /// Converts the provided value into a . /// /// The type of the value to serialize. - /// A representation of the JSON value. + /// A representation of the JSON value. /// The value to convert. /// Options to control the conversion behavior. /// @@ -30,9 +30,9 @@ public static JsonElement SerializeToElement(TValue value, JsonSerialize } /// - /// Converts the provided value into a . + /// Converts the provided value into a . /// - /// A representation of the value. + /// A representation of the value. /// The value to convert. /// The type of the to convert. /// Options to control the conversion behavior. @@ -55,10 +55,10 @@ public static JsonElement SerializeToElement(object? value, Type inputType, Json } /// - /// Converts the provided value into a . + /// Converts the provided value into a . /// /// The type of the value to serialize. - /// A representation of the value. + /// A representation of the value. /// The value to convert. /// Metadata about the type to convert. /// @@ -79,9 +79,9 @@ public static JsonElement SerializeToElement(TValue value, JsonTypeInfo< } /// - /// Converts the provided value into a . + /// Converts the provided value into a . /// - /// A representation of the value. + /// A representation of the value. /// The value to convert. /// The type of the to convert. /// A metadata provider for serializable types. 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 4357b7dac9198b..0827931b5df1de 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 @@ -49,6 +49,11 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor else { generator.Emit(OpCodes.Newobj, realMethod); + if (type.IsValueType) + { + // Since C# 10 it's now possible to have parameterless constructors in structs + generator.Emit(OpCodes.Box, type); + } } generator.Emit(OpCodes.Ret); diff --git a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs index 93aff74c1b4d0b..53a89e92028ece 100644 --- a/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs +++ b/src/libraries/System.Text.Json/tests/Common/ConstructorTests/ConstructorTests.ParameterMatching.cs @@ -1322,5 +1322,68 @@ public class ClassWithIgnoredSameType public ClassWithIgnoredSameType(ClassWithIgnoredSameType prop) { } } + + [Fact] + public void StructWithPropertyInit_DeseralizeEmptyObject() + { + string json = @"{}"; + var obj = JsonSerializer.Deserialize(json); + Assert.Equal(42, obj.A); + Assert.Equal(0, obj.B); + } + + [Fact] + public void StructWithPropertyInit_OverrideInitedProperty() + { + string json = @"{""A"":43}"; + var obj = JsonSerializer.Deserialize(json); + Assert.Equal(43, obj.A); + Assert.Equal(0, obj.B); + + json = @"{""A"":0,""B"":44}"; + obj = JsonSerializer.Deserialize(json); + Assert.Equal(0, obj.A); + Assert.Equal(44, obj.B); + + json = @"{""B"":45}"; + obj = JsonSerializer.Deserialize(json); + Assert.Equal(42, obj.A); // JSON doesn't set A property so it's expected to be 42 + Assert.Equal(45, obj.B); + } + + public struct StructWithPropertyInit + { + public long A { get; set; } = 42; + public long B { get; set; } + } + + [Fact] + public void StructWithFieldInit_DeseralizeEmptyObject() + { + string json = @"{}"; + var obj = JsonSerializer.Deserialize(json); + Assert.Equal(0, obj.A); + Assert.Equal(42, obj.B); + } + + public struct StructWithFieldInit + { + public long A; + public long B = 42; + } + + [Fact] + public void StructWithExplicitParameterlessCtor_DeseralizeEmptyObject() + { + string json = @"{}"; + var obj = JsonSerializer.Deserialize(json); + Assert.Equal(42, obj.A); + } + + public struct StructWithExplicitParameterlessCtor + { + public long A; + public StructWithExplicitParameterlessCtor() => A = 42; + } } } diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index 6fcbb9d4e59475..c073cf777c3569 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -36,7 +36,7 @@ <_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == '' and '$(Outerloop)' == 'true'">00:20:00 <_workItemTimeout Condition="'$(Scenario)' == '' and '$(_workItemTimeout)' == ''">00:15:00 <_workItemTimeout Condition="'$(Scenario)' != '' and '$(_workItemTimeout)' == ''">00:30:00 - <_workItemTimeout Condition="'$(Scenario)' == 'wasmtestonbrowser' and '$(BrowserHost)' == 'windows'">00:45:00 + <_workItemTimeout Condition="'$(Scenario)' == 'WasmTestOnBrowser' and '$(BrowserHost)' == 'windows'">00:45:00 @@ -66,10 +66,13 @@ true + $(RepoRoot)src\mono\wasm\emsdk\ + $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasm', 'emsdk')) true true + true true true @@ -104,14 +107,18 @@ + + + + @@ -137,6 +144,13 @@ + + + + + + + @@ -153,6 +167,12 @@ true + + + true + true + + true @@ -363,7 +383,6 @@ - $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasm', 'emsdk')) $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasm', 'build')) $([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'bin', 'NetCoreServer', '$(AspNetCoreAppCurrent)-$(Configuration)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'bin', 'RemoteLoopServer', '$(AspNetCoreAppCurrent)-$(Configuration)')) @@ -399,7 +418,7 @@ - + @@ -430,13 +449,13 @@ - + - + @@ -445,6 +464,10 @@ + + + + @@ -466,7 +489,7 @@ <_WorkItem Include="$(WorkItemArchiveWildCard)" Exclude="$(HelixCorrelationPayload)" /> - <_WorkItem Include="$(TestArchiveRoot)runonly/**/WebAssembly.Console.*.Test.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' != 'WasmTestOnBrowser' and '$(Scenario)' != 'BuildWasmApps'" /> + <_WorkItem Include="$(TestArchiveRoot)runonly/**/WebAssembly.Console.*.Test.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' != 'WasmTestOnBrowser' and '$(Scenario)' != 'BuildWasmApps' and '$(Scenario)' != 'WasmDebuggerTests'" /> <_WorkItem Include="$(TestArchiveRoot)runonly/**/WebAssembly.Browser.*.Test.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnBrowser'" /> <_WorkItem Include="$(TestArchiveRoot)browseronly/**/*.zip" Condition="'$(TargetOS)' == 'Browser' and '$(Scenario)' == 'WasmTestOnBrowser'" /> @@ -517,23 +540,50 @@ dotnet exec %XHARNESS_CLI_PATH% %HELIX_WORKITEM_UPLOAD_ROOT%\xharness-output %XHARNESS_COMMAND% - --browser-path=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe - - - <_RunOnlyWorkItem Include="$(TestArchiveRoot)runonly/**/*.Console.Sample.zip" /> - + + + <_RunOnlyWorkItemCJS Include="$(TestArchiveRoot)runonly/**/*.Console.V8.CJS.Sample.zip" /> + %(Identity) - $(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=test-main.js --output-directory=$(XHarnessOutput) -- --run %(FileName).dll + $(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=main.cjs --output-directory=$(XHarnessOutput) -- --run %(FileName).dll + + <_RunOnlyWorkItemES6 Include="$(TestArchiveRoot)runonly/**/*.Console.V8.ES6.Sample.zip" /> + + %(Identity) + + $(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=v8shim.cjs --output-directory=$(XHarnessOutput) -- --run %(FileName).dll + + + <_RunOnlyWorkItemCJS Include="$(TestArchiveRoot)runonly/**/*.Console.Node.CJS.Sample.zip" /> + + %(Identity) + + $(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --engine=NodeJS --engine-arg=--stack-trace-limit=1000 --js-file=main.cjs --output-directory=$(XHarnessOutput) -- --run %(FileName).dll + + <_RunOnlyWorkItemES6 Include="$(TestArchiveRoot)runonly/**/*.Console.Node.ES6.Sample.zip" /> + + %(Identity) + + $(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --engine=NodeJS --engine-arg=--stack-trace-limit=1000 --js-file=main.mjs --output-directory=$(XHarnessOutput) -- --run %(FileName).dll + + + + - - <_RunOnlyWorkItem Include="$(TestArchiveRoot)runonly/**/*.Browser.Sample.zip" /> - + <_RunOnlyWorkItemCJS Include="$(TestArchiveRoot)runonly/**/*.Browser.CJS.Sample.zip" /> + + %(Identity) + + $(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --browser=Chrome $(XHarnessBrowserPathArg) --html-file=index.html --output-directory=$(XHarnessOutput) -- %(FileName).dll + + <_RunOnlyWorkItemES6 Include="$(TestArchiveRoot)runonly/**/*.Browser.ES6.Sample.zip" /> + %(Identity) $(ExecXHarnessCmd) wasm $(XHarnessCommand) --app=. --browser=Chrome $(XHarnessBrowserPathArg) --html-file=index.html --output-directory=$(XHarnessOutput) -- %(FileName).dll @@ -562,19 +612,16 @@ - + - - $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasm', 'emsdk')) - + <_EmSdkFiles Include="$(EMSDK_PATH)\**\*" Exclude="$(EMSDK_PATH)\.git\**\*" /> - diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index aaf45da17b0032..326cbde18d7d70 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -324,8 +324,12 @@ - - + + + + + + diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 43c990543de589..ffad8eeae9f578 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -272,9 +272,6 @@ Common\Interop\Unix\System.Native\Interop.GetEnviron.cs - - - diff --git a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs index 94cb9eb7feea62..a8bf7fdc42bfc5 100644 --- a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs @@ -144,6 +144,11 @@ private static void Copy(Array sourceArray, int sourceIndex, Array destinationAr if (FastCopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length)) return; + CopySlow(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable); + } + + private static void CopySlow(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable) + { int source_pos = sourceIndex - sourceArray.GetLowerBound(0); int dest_pos = destinationIndex - destinationArray.GetLowerBound(0); diff --git a/src/mono/System.Private.CoreLib/src/System/ModuleHandle.cs b/src/mono/System.Private.CoreLib/src/System/ModuleHandle.cs index 757cab26d6ebac..9f73b99fb6db90 100644 --- a/src/mono/System.Private.CoreLib/src/System/ModuleHandle.cs +++ b/src/mono/System.Private.CoreLib/src/System/ModuleHandle.cs @@ -67,10 +67,9 @@ public RuntimeTypeHandle ResolveTypeHandle(int typeToken) [RequiresUnreferencedCode("Trimming changes metadata tokens")] public RuntimeTypeHandle ResolveTypeHandle(int typeToken, RuntimeTypeHandle[]? typeInstantiationContext, RuntimeTypeHandle[]? methodInstantiationContext) { - ResolveTokenError error; if (value == IntPtr.Zero) throw new ArgumentNullException(string.Empty, "Invalid handle"); - IntPtr res = RuntimeModule.ResolveTypeToken(value, typeToken, ptrs_from_handles(typeInstantiationContext), ptrs_from_handles(methodInstantiationContext), out error); + IntPtr res = RuntimeModule.ResolveTypeToken(value, typeToken, ptrs_from_handles(typeInstantiationContext), ptrs_from_handles(methodInstantiationContext), out _); if (res == IntPtr.Zero) throw new TypeLoadException(string.Format("Could not load type '0x{0:x}' from assembly '0x{1:x}'", typeToken, value.ToInt64())); else @@ -80,10 +79,9 @@ public RuntimeTypeHandle ResolveTypeHandle(int typeToken, RuntimeTypeHandle[]? t [RequiresUnreferencedCode("Trimming changes metadata tokens")] public RuntimeMethodHandle ResolveMethodHandle(int methodToken, RuntimeTypeHandle[]? typeInstantiationContext, RuntimeTypeHandle[]? methodInstantiationContext) { - ResolveTokenError error; if (value == IntPtr.Zero) throw new ArgumentNullException(string.Empty, "Invalid handle"); - IntPtr res = RuntimeModule.ResolveMethodToken(value, methodToken, ptrs_from_handles(typeInstantiationContext), ptrs_from_handles(methodInstantiationContext), out error); + IntPtr res = RuntimeModule.ResolveMethodToken(value, methodToken, ptrs_from_handles(typeInstantiationContext), ptrs_from_handles(methodInstantiationContext), out _); if (res == IntPtr.Zero) throw new Exception(string.Format("Could not load method '0x{0:x}' from assembly '0x{1:x}'", methodToken, value.ToInt64())); else @@ -93,11 +91,10 @@ public RuntimeMethodHandle ResolveMethodHandle(int methodToken, RuntimeTypeHandl [RequiresUnreferencedCode("Trimming changes metadata tokens")] public RuntimeFieldHandle ResolveFieldHandle(int fieldToken, RuntimeTypeHandle[]? typeInstantiationContext, RuntimeTypeHandle[]? methodInstantiationContext) { - ResolveTokenError error; if (value == IntPtr.Zero) throw new ArgumentNullException(string.Empty, "Invalid handle"); - IntPtr res = RuntimeModule.ResolveFieldToken(value, fieldToken, ptrs_from_handles(typeInstantiationContext), ptrs_from_handles(methodInstantiationContext), out error); + IntPtr res = RuntimeModule.ResolveFieldToken(value, fieldToken, ptrs_from_handles(typeInstantiationContext), ptrs_from_handles(methodInstantiationContext), out _); if (res == IntPtr.Zero) throw new Exception(string.Format("Could not load field '0x{0:x}' from assembly '0x{1:x}'", fieldToken, value.ToInt64())); else diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs index 24d588afba9bb9..fc89f24ec66d6d 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs @@ -196,7 +196,7 @@ internal static object[] GetCustomAttributes(ICustomAttributeProvider obj, Type } int initialSize = Math.Max(res.Length, 16); - List? a = null; + List? a; ICustomAttributeProvider? btype = obj; object[] array; @@ -371,7 +371,7 @@ internal static IList GetCustomAttributesData(ICustomAttrib } int initialSize = Math.Max(res.Count, 16); - List? a = null; + List? a; ICustomAttributeProvider? btype = obj; /* Non-inherit case */ @@ -738,7 +738,7 @@ private static AttributeUsageAttribute RetrieveAttributeUsageNoCache(Type attrib private static AttributeUsageAttribute RetrieveAttributeUsage(Type attributeType) { - AttributeUsageAttribute? usageAttribute = null; + AttributeUsageAttribute? usageAttribute; /* Usage a thread-local cache to speed this up, since it is called a lot from GetCustomAttributes () */ if (usage_cache == null) usage_cache = new Dictionary(); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs index a34ea7064705d6..ec4c34d8663252 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs @@ -274,7 +274,7 @@ private void Initialize(ConstructorInfo con, object?[] constructorArgs, /* helper methods */ internal static int decode_len(byte[] data, int pos, out int rpos) { - int len = 0; + int len; if ((data[pos] & 0x80) == 0) { len = (int)(data[pos++] & 0x7f); @@ -317,8 +317,7 @@ internal static string string_from_bytes(byte[] data, int pos, int len) internal string? string_arg() { - int pos = 2; - return decode_string(data, pos, out pos); + return decode_string(data, 2, out _); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2057:UnrecognizedReflectionPattern", @@ -507,7 +506,7 @@ internal static CustomAttributeInfo decode_cattr(CustomAttributeBuilder customBu { byte[] data = customBuilder.Data; ConstructorInfo ctor = customBuilder.Ctor; - int pos = 0; + int pos; CustomAttributeInfo info = default; diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs index 7ce6d2244cd938..51edf3f6448752 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs @@ -754,7 +754,6 @@ public virtual void Emit(OpCode opcode, MethodInfo meth) int token = token_gen.GetToken(meth, true); make_room(6); ll_emit(opcode); - Type? declaringType = meth.DeclaringType; emit_int(token); if (meth.ReturnType != typeof(void)) cur_stack++; diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs index 1e471e8b26805b..66816f9ce5bbfe 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs @@ -307,7 +307,7 @@ internal void RegisterTypeName(TypeBuilder tb, ITypeName name) internal TypeBuilder? GetRegisteredType(ITypeName name) { - TypeBuilder? result = null; + TypeBuilder? result; name_cache.TryGetValue(name, out result); return result; } diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs index b715e4e3869623..7946ad08d88af3 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs @@ -377,7 +377,7 @@ private RuntimeType[] ArgumentTypes private object? InvokeWorker(object? obj, BindingFlags invokeAttr, Span parameters) { Exception? exc; - object? o = null; + object? o; if ((invokeAttr & BindingFlags.DoNotWrapExceptions) == 0) { @@ -541,9 +541,8 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit) private Attribute GetDllImportAttribute() { string entryPoint; - string? dllName = null; - int token = MetadataToken; - PInvokeAttributes flags = 0; + string? dllName; + PInvokeAttributes flags; GetPInvoke(out flags, out entryPoint, out dllName); @@ -624,8 +623,8 @@ private Attribute GetDllImportAttribute() return null; string entryPoint; - string? dllName = null; - PInvokeAttributes flags = 0; + string? dllName; + PInvokeAttributes flags; GetPInvoke(out flags, out entryPoint, out dllName); @@ -885,7 +884,7 @@ internal object InvokeCtorWorker(BindingFlags invokeAttr, Span argument private object? InternalInvoke(object? obj, Span parameters, bool wrapExceptions) { Exception exc; - object? o = null; + object? o; if (wrapExceptions) { diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs index 0da72f4569f01e..49b93940f40348 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs @@ -438,7 +438,7 @@ private static GetterAdapter CreateGetterDelegate(MethodInfo method) public override object? GetValue(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo? culture) { - object? ret = null; + object? ret; MethodInfo? method = GetGetMethod(true); if (method == null) diff --git a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs index dff7e639cb2bce..95e19d9fb365bc 100644 --- a/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs @@ -256,8 +256,7 @@ private static void FilterHelper( // Used by the singular GetXXX APIs (Event, Field, Interface, NestedType) where prefixLookup is not supported. private static void FilterHelper(BindingFlags bindingFlags, ref string? name, out bool ignoreCase, out MemberListType listType) { - bool prefixLookup; - FilterHelper(bindingFlags, ref name, false, out prefixLookup, out ignoreCase, out listType); + FilterHelper(bindingFlags, ref name, false, out _, out ignoreCase, out listType); } // Only called by GetXXXCandidates, GetInterfaces, and GetNestedTypes when FilterHelper has set "prefixLookup" to true. @@ -584,8 +583,7 @@ private ListBuilder GetConstructorCandidates( Type[]? types, bool allowPrefixLookup) { bool prefixLookup, ignoreCase; - MemberListType listType; - FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType); + FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out _); if (!string.IsNullOrEmpty(name) && name != ConstructorInfo.ConstructorName && name != ConstructorInfo.TypeConstructorName) return new ListBuilder(0); @@ -660,7 +658,6 @@ private ListBuilder GetFieldCandidates(string? name, BindingFlags bin FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType); RuntimeFieldInfo[] cache = GetFields_internal(name, bindingAttr, listType, this); - bindingAttr ^= BindingFlags.DeclaredOnly; ListBuilder candidates = new ListBuilder(cache.Length); for (int i = 0; i < cache.Length; i++) @@ -677,12 +674,12 @@ private ListBuilder GetFieldCandidates(string? name, BindingFlags bin private ListBuilder GetNestedTypeCandidates(string? fullname, BindingFlags bindingAttr, bool allowPrefixLookup) { - bool prefixLookup, ignoreCase; + bool prefixLookup; bindingAttr &= ~BindingFlags.Static; string? name, ns; MemberListType listType; SplitName(fullname, out name, out ns); - FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType); + FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out _, out listType); RuntimeType[] cache = GetNestedTypes_internal(name, bindingAttr, listType); ListBuilder candidates = new ListBuilder(cache.Length); @@ -889,9 +886,8 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException(nameof(name)); - bool ignoreCase; MemberListType listType; - FilterHelper(bindingAttr, ref name!, out ignoreCase, out listType); + FilterHelper(bindingAttr, ref name!, out _, out listType); RuntimeEventInfo[] cache = GetEvents_internal(name, listType, this); EventInfo? match = null; @@ -918,14 +914,12 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException(); - bool ignoreCase; MemberListType listType; - FilterHelper(bindingAttr, ref name!, out ignoreCase, out listType); + FilterHelper(bindingAttr, ref name!, out _, out listType); RuntimeFieldInfo[] cache = GetFields_internal(name, bindingAttr, listType, this); FieldInfo? match = null; - bindingAttr ^= BindingFlags.DeclaredOnly; bool multipleStaticFieldMatches = false; for (int i = 0; i < cache.Length; i++) @@ -966,9 +960,8 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) bindingAttr |= BindingFlags.IgnoreCase; string? name, ns; - MemberListType listType; SplitName(fullname, out name, out ns); - FilterHelper(bindingAttr, ref name, out ignoreCase, out listType); + FilterHelper(bindingAttr, ref name, out ignoreCase, out _); List? list = null; StringComparison nameComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; @@ -1012,12 +1005,11 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { if (fullname == null) throw new ArgumentNullException(nameof(fullname)); - bool ignoreCase; bindingAttr &= ~BindingFlags.Static; string? name, ns; MemberListType listType; SplitName(fullname, out name, out ns); - FilterHelper(bindingAttr, ref name, out ignoreCase, out listType); + FilterHelper(bindingAttr, ref name, out _, out listType); RuntimeType[] cache = GetNestedTypes_internal(name, bindingAttr, listType); RuntimeType? match = null; @@ -1401,7 +1393,7 @@ private void CreateInstanceCheckThis() { CreateInstanceCheckThis(); - object? server = null; + object? server; try { @@ -2252,7 +2244,7 @@ public override bool IsSubclassOf(Type type) if (IsInterface || HasElementType || IsGenericParameter) return null; - int pack = 0, size = 0; + int pack, size; LayoutKind layoutKind = LayoutKind.Auto; switch (Attributes & TypeAttributes.LayoutMask) { diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs index 4187cfcb829089..153783fa1707c0 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.Mono.cs @@ -28,10 +28,9 @@ private TimerQueue(int id) } [DynamicDependency("TimeoutCallback")] - // The id argument is unused in netcore // This replaces the current pending setTimeout with shorter one [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern void SetTimeout(int timeout, int id); + private static extern void SetTimeout(int timeout); // Called by mini-wasm.c:mono_set_timeout_exec private static void TimeoutCallback() @@ -78,7 +77,7 @@ private static void ReplaceNextSetTimeout(long shortestDueTimeMs, long currentTi int shortestWait = Math.Max((int)(shortestDueTimeMs - currentTimeMs), 0); // this would cancel the previous schedule and create shorter one // it is expensive call - SetTimeout(shortestWait, 0); + SetTimeout(shortestWait); } } diff --git a/src/mono/System.Private.CoreLib/src/System/TypeNameParser.cs b/src/mono/System.Private.CoreLib/src/System/TypeNameParser.cs index 24102d426a17c9..5f913b4fd28493 100644 --- a/src/mono/System.Private.CoreLib/src/System/TypeNameParser.cs +++ b/src/mono/System.Private.CoreLib/src/System/TypeNameParser.cs @@ -142,7 +142,7 @@ internal static class TypeNameParser [RequiresUnreferencedCode("Types might be removed")] private static Type? ResolveType(Assembly assembly, List names, Func? typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { - Type? type = null; + Type? type; string name = EscapeTypeName(names[0]); // Resolve the top level type. @@ -263,7 +263,6 @@ public override string ToString () { var res = new ParsedName() { Names = new List() }; - int start = pos; int name_start = pos; bool in_modifiers = false; while (pos < name.Length) diff --git a/src/mono/System.Private.CoreLib/src/System/TypeSpec.cs b/src/mono/System.Private.CoreLib/src/System/TypeSpec.cs index c73a1717d306b8..0dd51fe2807703 100644 --- a/src/mono/System.Private.CoreLib/src/System/TypeSpec.cs +++ b/src/mono/System.Private.CoreLib/src/System/TypeSpec.cs @@ -305,27 +305,6 @@ internal static string UnescapeInternalName(string displayName) return res.ToString(); } - internal static bool NeedsEscaping(string internalName) - { - foreach (char c in internalName) - { - switch (c) - { - case ',': - case '+': - case '*': - case '&': - case '[': - case ']': - case '\\': - return true; - default: - break; - } - } - return false; - } - internal Type? Resolve(Func assemblyResolver, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark) { Assembly? asm = null; @@ -347,7 +326,7 @@ internal static bool NeedsEscaping(string internalName) } } - Type? type = null; + Type? type; if (typeResolver != null) type = typeResolver(asm!, name!.DisplayName, ignoreCase); else diff --git a/src/mono/mono/cil/cil-opcodes.xml b/src/mono/mono/cil/cil-opcodes.xml index 50b70144d16a68..5b047e47e1e765 100644 --- a/src/mono/mono/cil/cil-opcodes.xml +++ b/src/mono/mono/cil/cil-opcodes.xml @@ -327,4 +327,5 @@ + diff --git a/src/mono/mono/cil/opcode.def b/src/mono/mono/cil/opcode.def index 4b0769de95ebbb..47bccb295e99b2 100644 --- a/src/mono/mono/cil/opcode.def +++ b/src/mono/mono/cil/opcode.def @@ -327,6 +327,7 @@ OPDEF(CEE_MONO_RETHROW, "mono_rethrow", PopRef, Push0, InlineNone, 0, 2, 0xF0, 0 OPDEF(CEE_MONO_GET_SP, "mono_get_sp", Pop0, PushI, InlineNone, 0, 2, 0xF0, 0x20, NEXT) OPDEF(CEE_MONO_METHODCONST, "mono_methodconst", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x21, NEXT) OPDEF(CEE_MONO_PINVOKE_ADDR_CACHE, "mono_pinvoke_addr_cache", Pop0, PushI, InlineI, 0, 2, 0xF0, 0x22, NEXT) +OPDEF(CEE_MONO_REMAP_OVF_EXC, "mono_remap_ovf_exc", Pop0, Push0, InlineI, 0, 2, 0xF0, 0x23, NEXT) #ifndef OPALIAS #define _MONO_CIL_OPALIAS_DEFINED_ #define OPALIAS(a,s,r) diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 577a14eb656191..804431515d1f4a 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -181,6 +181,7 @@ MONO_JIT_ICALL (mono_delegate_end_invoke) \ MONO_JIT_ICALL (mono_delegate_to_ftnptr) \ MONO_JIT_ICALL (mono_domain_get) \ MONO_JIT_ICALL (mono_dummy_jit_icall) \ +MONO_JIT_ICALL (mono_dummy_jit_icall_val) \ MONO_JIT_ICALL (mono_exception_from_token) \ MONO_JIT_ICALL (mono_fill_class_rgctx) \ MONO_JIT_ICALL (mono_fill_method_rgctx) \ diff --git a/src/mono/mono/metadata/sgen-mono-ilgen.c b/src/mono/mono/metadata/sgen-mono-ilgen.c index f9887161d37df6..aa5e034dbc6f9d 100644 --- a/src/mono/mono/metadata/sgen-mono-ilgen.c +++ b/src/mono/mono/metadata/sgen-mono-ilgen.c @@ -233,11 +233,7 @@ emit_managed_allocator_ilgen (MonoMethodBuilder *mb, gboolean slowpath, gboolean mono_mb_emit_byte (mb, CEE_CONV_I); mono_mb_emit_stloc (mb, size_var); } else if (atype == ATYPE_VECTOR) { - ERROR_DECL (error); - MonoExceptionClause *clause; - int pos, pos_leave, pos_error; - MonoClass *oom_exc_class; - MonoMethod *ctor; + int pos, pos_error; /* * n > MONO_ARRAY_MAX_INDEX => OutOfMemoryException @@ -262,9 +258,6 @@ emit_managed_allocator_ilgen (MonoMethodBuilder *mb, gboolean slowpath, gboolean mono_mb_patch_short_branch (mb, pos); - clause = (MonoExceptionClause *)mono_image_alloc0 (mono_defaults.corlib, sizeof (MonoExceptionClause)); - clause->try_offset = mono_mb_get_label (mb); - /* vtable->klass->sizes.element_size */ mono_mb_emit_ldarg (mb, 0); mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoVTable, klass)); @@ -279,35 +272,15 @@ emit_managed_allocator_ilgen (MonoMethodBuilder *mb, gboolean slowpath, gboolean /* * n */ mono_mb_emit_ldarg (mb, 1); + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); + mono_mb_emit_op (mb, CEE_MONO_REMAP_OVF_EXC, (gpointer)"OutOfMemoryException"); mono_mb_emit_byte (mb, CEE_MUL_OVF_UN); /* + sizeof (MonoArray) */ mono_mb_emit_icon (mb, MONO_SIZEOF_MONO_ARRAY); + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); + mono_mb_emit_op (mb, CEE_MONO_REMAP_OVF_EXC, (gpointer)"OutOfMemoryException"); mono_mb_emit_byte (mb, CEE_ADD_OVF_UN); mono_mb_emit_stloc (mb, size_var); - - pos_leave = mono_mb_emit_branch (mb, CEE_LEAVE); - - /* catch */ - clause->flags = MONO_EXCEPTION_CLAUSE_NONE; - clause->try_len = mono_mb_get_pos (mb) - clause->try_offset; - clause->data.catch_class = mono_class_load_from_name (mono_defaults.corlib, - "System", "OverflowException"); - clause->handler_offset = mono_mb_get_label (mb); - - oom_exc_class = mono_class_load_from_name (mono_defaults.corlib, - "System", "OutOfMemoryException"); - ctor = mono_class_get_method_from_name_checked (oom_exc_class, ".ctor", 0, 0, error); - mono_error_assert_ok (error); - g_assert (ctor); - - mono_mb_emit_byte (mb, CEE_POP); - mono_mb_emit_op (mb, CEE_NEWOBJ, ctor); - mono_mb_emit_byte (mb, CEE_THROW); - - clause->handler_len = mono_mb_get_pos (mb) - clause->handler_offset; - mono_mb_set_clauses (mb, 1, clause); - mono_mb_patch_branch (mb, pos_leave); - /* end catch */ } else if (atype == ATYPE_STRING) { /* * a string allocator method takes the args: (vtable, len) diff --git a/src/mono/mono/mini/decompose.c b/src/mono/mono/mini/decompose.c index 46de11de21c927..efc8bfd6f06bcd 100644 --- a/src/mono/mono/mini/decompose.c +++ b/src/mono/mono/mini/decompose.c @@ -81,7 +81,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins) else opcode = OP_ADDCC; EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2); - MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, OV, ins->inst_exc_name); NULLIFY_INS (ins); break; } @@ -95,7 +95,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins) else opcode = OP_ADDCC; EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2); - MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, C, ins->inst_exc_name); NULLIFY_INS (ins); break; } @@ -110,7 +110,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins) else opcode = OP_SUBCC; EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2); - MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, OV, ins->inst_exc_name); NULLIFY_INS (ins); break; } @@ -124,7 +124,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins) else opcode = OP_SUBCC; EMIT_NEW_BIALU (cfg, repl, opcode, ins->dreg, ins->sreg1, ins->sreg2); - MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, C, ins->inst_exc_name); NULLIFY_INS (ins); break; } @@ -327,7 +327,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) if (COMPILE_LLVM (cfg)) break; ins->opcode = OP_IADDCC; - MONO_EMIT_NEW_COND_EXC (cfg, IC, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, IC, ins->inst_exc_name); break; case OP_ISUB_OVF: if (COMPILE_LLVM (cfg)) @@ -859,25 +859,25 @@ mono_decompose_long_opts (MonoCompile *cfg) /* ADC sets the condition code */ MONO_EMIT_NEW_BIALU (cfg, OP_IADDCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2)); MONO_EMIT_NEW_BIALU (cfg, OP_IADC, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2)); - MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, OV, tree->inst_exc_name); break; case OP_LADD_OVF_UN: /* ADC sets the condition code */ MONO_EMIT_NEW_BIALU (cfg, OP_IADDCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2)); MONO_EMIT_NEW_BIALU (cfg, OP_IADC, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2)); - MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, C, tree->inst_exc_name); break; case OP_LSUB_OVF: /* SBB sets the condition code */ MONO_EMIT_NEW_BIALU (cfg, OP_ISUBCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2)); MONO_EMIT_NEW_BIALU (cfg, OP_ISBB, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2)); - MONO_EMIT_NEW_COND_EXC (cfg, OV, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, OV, tree->inst_exc_name); break; case OP_LSUB_OVF_UN: /* SBB sets the condition code */ MONO_EMIT_NEW_BIALU (cfg, OP_ISUBCC, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2)); MONO_EMIT_NEW_BIALU (cfg, OP_ISBB, MONO_LVREG_MS (tree->dreg), MONO_LVREG_MS (tree->sreg1), MONO_LVREG_MS (tree->sreg2)); - MONO_EMIT_NEW_COND_EXC (cfg, C, "OverflowException"); + MONO_EMIT_NEW_COND_EXC (cfg, C, tree->inst_exc_name); break; case OP_LAND: MONO_EMIT_NEW_BIALU (cfg, OP_IAND, MONO_LVREG_LS (tree->dreg), MONO_LVREG_LS (tree->sreg1), MONO_LVREG_LS (tree->sreg2)); @@ -1445,8 +1445,11 @@ mono_decompose_vtype_opts (MonoCompile *cfg) src->klass = ins->klass; src->dreg = ins->sreg1; } + + cfg->disable_inline_rgctx_fetch = TRUE; MonoInst *tmp = mini_emit_box (cfg, src, ins->klass, mini_class_check_context_used (cfg, ins->klass)); g_assert (tmp); + cfg->disable_inline_rgctx_fetch = FALSE; MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ins->dreg, tmp->dreg); diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 56d4134d91a700..040e1169c77f43 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -6804,18 +6804,20 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; MINT_IN_CASE(MINT_CPBLK) { gpointer dest = LOCAL_VAR (ip [1], gpointer); gpointer src = LOCAL_VAR (ip [2], gpointer); - if (!dest || !src) + guint32 size = LOCAL_VAR (ip [3], guint32); + if (size && (!dest || !src)) THROW_EX (mono_get_exception_null_reference(), ip); - /* FIXME: value and size may be int64... */ - memcpy (dest, src, LOCAL_VAR (ip [3], gint32)); + else + memcpy (dest, src, size); ip += 4; MINT_IN_BREAK; } MINT_IN_CASE(MINT_INITBLK) { gpointer dest = LOCAL_VAR (ip [1], gpointer); - NULL_CHECK (dest); - /* FIXME: value and size may be int64... */ - memset (dest, LOCAL_VAR (ip [2], gint32), LOCAL_VAR (ip [3], gint32)); + guint32 size = LOCAL_VAR (ip [3], guint32); + if (size) + NULL_CHECK (dest); + memset (dest, LOCAL_VAR (ip [2], gint32), size); ip += 4; MINT_IN_BREAK; } diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index a0078c45656987..b55fe7fc2d790b 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -1622,3 +1622,8 @@ void mono_dummy_jit_icall (void) { } + +void +mono_dummy_jit_icall_val (gpointer val) +{ +} diff --git a/src/mono/mono/mini/jit-icalls.h b/src/mono/mono/mini/jit-icalls.h index 646e888b471f84..1df30a95e737f8 100644 --- a/src/mono/mono/mini/jit-icalls.h +++ b/src/mono/mono/mini/jit-icalls.h @@ -229,4 +229,6 @@ ICALL_EXPORT void mono_throw_invalid_program (const char *msg); ICALL_EXPORT void mono_dummy_jit_icall (void); +ICALL_EXPORT void mono_dummy_jit_icall_val (gpointer ptr); + #endif /* __MONO_JIT_ICALLS_H__ */ diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index d1da9506106686..85ca8d262702b6 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -524,6 +524,7 @@ add_widen_op (MonoCompile *cfg, MonoInst *ins, MonoInst **arg1_ref, MonoInst **a ins->sreg2 = sp [1]->dreg; \ type_from_op (cfg, ins, sp [0], sp [1]); \ CHECK_TYPE (ins); \ + if (ovf_exc) ins->inst_exc_name = ovf_exc; else ins->inst_exc_name = "OverflowException"; ovf_exc = NULL; \ /* Have to insert a widening op */ \ add_widen_op (cfg, ins, &sp [0], &sp [1]); \ ins->dreg = alloc_dreg ((cfg), (MonoStackType)(ins)->type); \ @@ -6149,6 +6150,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MonoDebugMethodInfo *minfo; MonoBitSet *seq_point_locs = NULL; MonoBitSet *seq_point_set_locs = NULL; + const char *ovf_exc = NULL; gboolean emitted_funccall_seq_point = FALSE; gboolean detached_before_ret = FALSE; gboolean ins_has_side_effect; @@ -11084,6 +11086,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b *sp++ = ins; break; } + case MONO_CEE_MONO_REMAP_OVF_EXC: + /* Remap the exception thrown by the next _OVF opcode */ + g_assert (method->wrapper_type != MONO_WRAPPER_NONE); + ovf_exc = (const char*)mono_method_get_wrapper_data (method, token); + break; case MONO_CEE_ARGLIST: { /* somewhat similar to LDTOKEN */ diff --git a/src/mono/mono/mini/mini-codegen.c b/src/mono/mono/mini/mini-codegen.c index 44a60604b94068..77464dcf88cbb7 100644 --- a/src/mono/mono/mini/mini-codegen.c +++ b/src/mono/mono/mini/mini-codegen.c @@ -2716,6 +2716,8 @@ mini_exception_id_by_name (const char *name) return MONO_EXC_ARGUMENT; if (strcmp (name, "ArgumentOutOfRangeException") == 0) return MONO_EXC_ARGUMENT_OUT_OF_RANGE; + if (strcmp (name, "OutOfMemoryException") == 0) + return MONO_EXC_ARGUMENT_OUT_OF_MEMORY; g_error ("Unknown intrinsic exception %s\n", name); return -1; } diff --git a/src/mono/mono/mini/mini-llvm-cpp.cpp b/src/mono/mono/mini/mini-llvm-cpp.cpp index d2bf4eb7c77421..fc87c556ae3842 100644 --- a/src/mono/mono/mini/mini-llvm-cpp.cpp +++ b/src/mono/mono/mini/mini-llvm-cpp.cpp @@ -105,7 +105,7 @@ mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty, LLVMValueRef Arr auto sz = unwrap (ArraySize); auto b = unwrap (builder); auto ins = alignment > 0 - ? b->Insert (new AllocaInst (ty, 0, sz, to_align (alignment), Name)) + ? b->Insert (new AllocaInst (ty, 0, sz, to_align (alignment)), Name) : b->CreateAlloca (ty, 0, sz, Name); return wrap (ins); } diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 4193900b324c53..75c45652b06a5a 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -7287,7 +7287,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) val = call_intrins (ctx, intrins, args, ""); values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname); ovf = LLVMBuildExtractValue (builder, val, 1, ""); - emit_cond_system_exception (ctx, bb, "OverflowException", ovf, FALSE); + emit_cond_system_exception (ctx, bb, ins->inst_exc_name, ovf, FALSE); if (!ctx_ok (ctx)) break; builder = ctx->builder; diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 83078470df3b74..0841d15ae72b9d 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4919,6 +4919,7 @@ register_icalls (void) register_icall (mono_throw_platform_not_supported, mono_icall_sig_void, FALSE); register_icall (mono_throw_invalid_program, mono_icall_sig_void_ptr, FALSE); register_icall_no_wrapper (mono_dummy_jit_icall, mono_icall_sig_void); + //register_icall_no_wrapper (mono_dummy_jit_icall_val, mono_icall_sig_void_ptr); register_icall_with_wrapper (mono_monitor_enter_internal, mono_icall_sig_int32_obj); register_icall_with_wrapper (mono_monitor_enter_v4_internal, mono_icall_sig_void_obj_ptr); diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 2b5e7bc22c6640..baa428336a98bc 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -439,10 +439,10 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe //functions exported to be used by JS G_BEGIN_DECLS -EMSCRIPTEN_KEEPALIVE void mono_set_timeout_exec (int id); +EMSCRIPTEN_KEEPALIVE void mono_set_timeout_exec (void); //JS functions imported that we use -extern void mono_set_timeout (int t, int d); +extern void mono_set_timeout (int t); extern void mono_wasm_queue_tp_cb (void); G_END_DECLS @@ -581,21 +581,23 @@ mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo } EMSCRIPTEN_KEEPALIVE void -mono_set_timeout_exec (int id) +mono_set_timeout_exec (void) { ERROR_DECL (error); - MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System.Threading", "TimerQueue"); - g_assert (klass); + static MonoMethod *method = NULL; + if (method == NULL) { + MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System.Threading", "TimerQueue"); + g_assert (klass); - MonoMethod *method = mono_class_get_method_from_name_checked (klass, "TimeoutCallback", -1, 0, error); - mono_error_assert_ok (error); - g_assert (method); + method = mono_class_get_method_from_name_checked (klass, "TimeoutCallback", -1, 0, error); + mono_error_assert_ok (error); + g_assert (method); + } - gpointer params[1] = { &id }; MonoObject *exc = NULL; - mono_runtime_try_invoke (method, NULL, params, &exc, error); + mono_runtime_try_invoke (method, NULL, NULL, &exc, error); //YES we swallow exceptions cuz there's nothing much we can do from here. //FIXME Maybe call the unhandled exception function? @@ -614,10 +616,10 @@ mono_set_timeout_exec (int id) #endif void -mono_wasm_set_timeout (int timeout, int id) +mono_wasm_set_timeout (int timeout) { #ifdef HOST_BROWSER - mono_set_timeout (timeout, id); + mono_set_timeout (timeout); #endif } @@ -626,12 +628,15 @@ tp_cb (void) { ERROR_DECL (error); - MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System.Threading", "ThreadPool"); - g_assert (klass); + static MonoMethod *method = NULL; + if (method == NULL) { + MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System.Threading", "ThreadPool"); + g_assert (klass); - MonoMethod *method = mono_class_get_method_from_name_checked (klass, "Callback", -1, 0, error); - mono_error_assert_ok (error); - g_assert (method); + method = mono_class_get_method_from_name_checked (klass, "Callback", -1, 0, error); + mono_error_assert_ok (error); + g_assert (method); + } MonoObject *exc = NULL; diff --git a/src/mono/mono/mini/mini-wasm.h b/src/mono/mono/mini/mini-wasm.h index df0a852b1a5632..4dfb04059e17b9 100644 --- a/src/mono/mono/mini/mini-wasm.h +++ b/src/mono/mono/mini/mini-wasm.h @@ -100,7 +100,7 @@ typedef struct { // sdks/wasm/driver.c is C and uses this G_EXTERN_C void mono_wasm_enable_debugging (int log_level); -void mono_wasm_set_timeout (int timeout, int id); +void mono_wasm_set_timeout (int timeout); int mono_wasm_assembly_already_added (const char *assembly_name); void mono_wasm_print_stack_trace (void); diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index b693081d6311f8..e671ca86b11ae6 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -757,6 +757,7 @@ struct MonoInst { int *phi_args; MonoCallInst *call_inst; GList *exception_clauses; + const char *exc_name; } op [2]; gint64 i8const; double r8const; @@ -908,6 +909,9 @@ enum { #define inst_newa_len data.op[0].src #define inst_newa_class data.op[1].klass +/* In _OVF opcodes */ +#define inst_exc_name data.op[0].exc_name + #define inst_var data.op[0].var #define inst_vtype data.op[1].vtype /* in branch instructions */ @@ -1991,6 +1995,7 @@ enum { MONO_EXC_ARRAY_TYPE_MISMATCH, MONO_EXC_ARGUMENT, MONO_EXC_ARGUMENT_OUT_OF_RANGE, + MONO_EXC_ARGUMENT_OUT_OF_MEMORY, MONO_EXC_INTRINS_NUM }; diff --git a/src/mono/sample/mbr/browser/index.html b/src/mono/sample/mbr/browser/index.html index 91ccdf9c1e4bc9..b19224774518e3 100644 --- a/src/mono/sample/mbr/browser/index.html +++ b/src/mono/sample/mbr/browser/index.html @@ -19,7 +19,7 @@ const App = { init: function () { const update = BINDING.bind_static_method("[WasmDelta] Sample.Test:Update"); - const testMeaning = BINDING.bind_static_method("[Wasm.Browser.Sample] Sample.Test:TestMeaning"); + const testMeaning = BINDING.bind_static_method("[WasmDelta] Sample.Test:TestMeaning"); const outElement = document.getElementById("out"); document.getElementById("update").addEventListener("click", function () { update(); diff --git a/src/mono/sample/wasm/Directory.Build.targets b/src/mono/sample/wasm/Directory.Build.targets index cebfca1893bba3..8be4c973cf5d6c 100644 --- a/src/mono/sample/wasm/Directory.Build.targets +++ b/src/mono/sample/wasm/Directory.Build.targets @@ -3,8 +3,14 @@ + Inputs=" + Program.cs; + $(_WasmMainJSFileName); + " + Outputs=" + bin/$(Configuration)/AppBundle/dotnet.wasm; + bin/$(Configuration)/AppBundle/$(_WasmMainJSFileName); + "> <_ScriptExt Condition="'$(OS)' == 'Windows_NT'">.cmd @@ -13,7 +19,7 @@ <_AOTFlag Condition="'$(RunAOTCompilation)' != ''">/p:RunAOTCompilation=$(RunAOTCompilation) <_WasmMainJSFileName>$([System.IO.Path]::GetFileName('$(WasmMainJSPath)')) - + diff --git a/src/mono/sample/wasm/browser-es6/Makefile b/src/mono/sample/wasm/browser-es6/Makefile new file mode 100644 index 00000000000000..6be5669382b6e0 --- /dev/null +++ b/src/mono/sample/wasm/browser-es6/Makefile @@ -0,0 +1,11 @@ +TOP=../../../../.. + +include ../wasm.mk + +ifneq ($(AOT),) +override MSBUILD_ARGS+=/p:RunAOTCompilation=true +endif + +PROJECT_NAME=Wasm.Browser.ES6.Sample.csproj + +run: run-browser diff --git a/src/mono/sample/wasm/browser-es6/Program.cs b/src/mono/sample/wasm/browser-es6/Program.cs index 743f481896fcb5..66ff814d0eff82 100644 --- a/src/mono/sample/wasm/browser-es6/Program.cs +++ b/src/mono/sample/wasm/browser-es6/Program.cs @@ -8,9 +8,10 @@ namespace Sample { public class Test { - public static void Main(string[] args) + public static int Main(string[] args) { Console.WriteLine ("Hello, World!"); + return 0; } [MethodImpl(MethodImplOptions.NoInlining)] diff --git a/src/mono/sample/wasm/browser-es6/Wasm.Browser.ES6.Sample.csproj b/src/mono/sample/wasm/browser-es6/Wasm.Browser.ES6.Sample.csproj index a617dd85614f20..2567910bf88061 100644 --- a/src/mono/sample/wasm/browser-es6/Wasm.Browser.ES6.Sample.csproj +++ b/src/mono/sample/wasm/browser-es6/Wasm.Browser.ES6.Sample.csproj @@ -1,6 +1,5 @@ - Debug true main.js true @@ -16,5 +15,6 @@ <_SampleProject>Wasm.Browser.ES6.Sample.csproj + diff --git a/src/mono/sample/wasm/browser-es6/index.html b/src/mono/sample/wasm/browser-es6/index.html index 6dd3faeb7bd7ad..9172b63389a407 100644 --- a/src/mono/sample/wasm/browser-es6/index.html +++ b/src/mono/sample/wasm/browser-es6/index.html @@ -7,8 +7,8 @@ Sample ES6 - - + + diff --git a/src/mono/sample/wasm/browser-es6/main.js b/src/mono/sample/wasm/browser-es6/main.js index 1cfe1fb3da6a59..d35e33db1dfa35 100644 --- a/src/mono/sample/wasm/browser-es6/main.js +++ b/src/mono/sample/wasm/browser-es6/main.js @@ -1,21 +1,25 @@ import createDotnetRuntime from './dotnet.js' -const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime((api) => ({ - disableDotnet6Compatibility: true, - configSrc: "./mono-config.json", - onAbort: () => { - wasm_exit(1); - }, -})); - function wasm_exit(exit_code) { + /* Set result in a tests_done element, to be read by xharness in runonly CI test */ + const tests_done_elem = document.createElement("label"); + tests_done_elem.id = "tests_done"; + tests_done_elem.innerHTML = exit_code.toString(); + document.body.appendChild(tests_done_elem); + console.log(`WASM EXIT ${exit_code}`); } -const testMeaning = BINDING.bind_static_method("[Wasm.Browser.ES6.Sample] Sample.Test:TestMeaning"); -const ret = testMeaning(); -document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`; +try { + const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(); + const testMeaning = BINDING.bind_static_method("[Wasm.Browser.ES6.Sample] Sample.Test:TestMeaning"); + const ret = testMeaning(); + document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`; + console.debug(`ret: ${ret}`); -console.debug(`ret: ${ret}`); -let exit_code = ret == 42 ? 0 : 1; -wasm_exit(exit_code); \ No newline at end of file + let exit_code = await MONO.mono_run_main("Wasm.Browser.ES6.Sample.dll", []); + wasm_exit(exit_code); +} catch (err) { + console.log(`WASM ERROR ${err}`); + wasm_exit(2); +} diff --git a/src/mono/sample/wasm/browser-legacy/Wasm.Browser.LegacySample.csproj b/src/mono/sample/wasm/browser-legacy/Wasm.Browser.LegacySample.csproj index c03897e467d94d..a105c68b663be5 100644 --- a/src/mono/sample/wasm/browser-legacy/Wasm.Browser.LegacySample.csproj +++ b/src/mono/sample/wasm/browser-legacy/Wasm.Browser.LegacySample.csproj @@ -1,12 +1,12 @@ - Debug true main.js true embedded 1 - true + false + false diff --git a/src/mono/sample/wasm/browser-legacy/index.html b/src/mono/sample/wasm/browser-legacy/index.html index a2e7322aecf0e3..7787b101941f4d 100644 --- a/src/mono/sample/wasm/browser-legacy/index.html +++ b/src/mono/sample/wasm/browser-legacy/index.html @@ -35,9 +35,9 @@ }, }; - + - + diff --git a/src/mono/sample/wasm/browser/Makefile b/src/mono/sample/wasm/browser/Makefile index 7ae388cce865d3..7a6b17c4787bc4 100644 --- a/src/mono/sample/wasm/browser/Makefile +++ b/src/mono/sample/wasm/browser/Makefile @@ -6,6 +6,6 @@ ifneq ($(AOT),) override MSBUILD_ARGS+=/p:RunAOTCompilation=true endif -PROJECT_NAME=Wasm.Browser.Sample.csproj +PROJECT_NAME=Wasm.Browser.CJS.Sample.csproj run: run-browser diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj similarity index 83% rename from src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj rename to src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj index eb9934dc662ca6..3cfd138946d40a 100644 --- a/src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj +++ b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj @@ -1,11 +1,11 @@ - Debug true main.js true embedded 1 + false @@ -13,7 +13,7 @@ - <_SampleProject>Wasm.Browser.Sample.csproj + <_SampleProject>Wasm.Browser.CJS.Sample.csproj diff --git a/src/mono/sample/wasm/browser/index.html b/src/mono/sample/wasm/browser/index.html index 340b67d645a756..765d8ccede0849 100644 --- a/src/mono/sample/wasm/browser/index.html +++ b/src/mono/sample/wasm/browser/index.html @@ -4,40 +4,16 @@ - Sample + Sample CJS - - Result from Sample.Test.TestMeaning: - - - - + + Answer to the Ultimate Question of Life, the Universe, and Everything is : + + \ No newline at end of file diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser/main.js index 0c865b3f02719d..661af63b64ba8a 100644 --- a/src/mono/sample/wasm/browser/main.js +++ b/src/mono/sample/wasm/browser/main.js @@ -1,20 +1,38 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. +function wasm_exit(exit_code) { + /* Set result in a tests_done element, to be read by xharness in runonly CI test */ + const tests_done_elem = document.createElement("label"); + tests_done_elem.id = "tests_done"; + tests_done_elem.innerHTML = exit_code.toString(); + document.body.appendChild(tests_done_elem); -"use strict"; + console.log(`WASM EXIT ${exit_code}`); +} -createDotnetRuntime(({ MONO, BINDING, Module }) => ({ - disableDotnet6Compatibility: true, - configSrc: "./mono-config.json", - onDotnetReady: () => { - try { - App.init({ MONO, BINDING, Module }); - } catch (error) { - set_exit_code(1, error); - throw (error); - } - }, - onAbort: (error) => { - set_exit_code(1, error); - }, -})); +async function loadRuntime() { + globalThis.exports = {}; + await import("./dotnet.js"); + return globalThis.exports.createDotnetRuntime; +} + +async function main() { + try { + const createDotnetRuntime = await loadRuntime(); + const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(() => ({ + disableDotnet6Compatibility: true, + configSrc: "./mono-config.json", + })); + + const testMeaning = BINDING.bind_static_method("[Wasm.Browser.CJS.Sample] Sample.Test:TestMeaning"); + const ret = testMeaning(); + document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`; + + console.debug(`ret: ${ret}`); + let exit_code = ret == 42 ? 0 : 1; + wasm_exit(exit_code); + } catch (err) { + console.log(`WASM ERROR ${err}`); + wasm_exit(2) + } +} + +main(); \ No newline at end of file diff --git a/src/mono/sample/wasm/console-node-cjs/Makefile b/src/mono/sample/wasm/console-node-cjs/Makefile new file mode 100644 index 00000000000000..5d6de5e730358b --- /dev/null +++ b/src/mono/sample/wasm/console-node-cjs/Makefile @@ -0,0 +1,17 @@ +TOP=../../../../.. + +include ../wasm.mk + +ifneq ($(AOT),) +override MSBUILD_ARGS+=/p:RunAOTCompilation=true +endif + +ifneq ($(V),) +DOTNET_MONO_LOG_LEVEL=--setenv=MONO_LOG_LEVEL=debug +endif + +PROJECT_NAME=Wasm.Console.Node.CJS.Sample.csproj +CONSOLE_DLL=Wasm.Console.Node.CJS.Sample.dll +MAIN_JS=main.cjs + +run: run-console-node diff --git a/src/mono/sample/wasm/console-node-cjs/Program.cs b/src/mono/sample/wasm/console-node-cjs/Program.cs new file mode 100644 index 00000000000000..f65bd654e98863 --- /dev/null +++ b/src/mono/sample/wasm/console-node-cjs/Program.cs @@ -0,0 +1,15 @@ +// 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; + +public class Test +{ + public static async Task Main(string[] args) + { + await Task.Delay(1); + Console.WriteLine("Hello World!"); + return 42; + } +} diff --git a/src/mono/sample/wasm/console-node-cjs/README.md b/src/mono/sample/wasm/console-node-cjs/README.md new file mode 100644 index 00000000000000..14ccf622c842e4 --- /dev/null +++ b/src/mono/sample/wasm/console-node-cjs/README.md @@ -0,0 +1 @@ +This sample uses CommonJS version of `dotnet.js` running on NodeJS \ No newline at end of file diff --git a/src/mono/sample/wasm/console-node-cjs/Wasm.Console.Node.CJS.Sample.csproj b/src/mono/sample/wasm/console-node-cjs/Wasm.Console.Node.CJS.Sample.csproj new file mode 100644 index 00000000000000..0d0a52d2ff0247 --- /dev/null +++ b/src/mono/sample/wasm/console-node-cjs/Wasm.Console.Node.CJS.Sample.csproj @@ -0,0 +1,18 @@ + + + true + main.cjs + true + embedded + 1 + false + false + + + + <_SampleProject>Wasm.Console.Node.CJS.Sample.csproj + <_SampleAssembly>Wasm.Console.Node.CJS.Sample.dll + + + + diff --git a/src/mono/sample/wasm/console-node-cjs/main.cjs b/src/mono/sample/wasm/console-node-cjs/main.cjs new file mode 100644 index 00000000000000..4e985076e1b56b --- /dev/null +++ b/src/mono/sample/wasm/console-node-cjs/main.cjs @@ -0,0 +1,9 @@ +const createDotnetRuntime = require("./dotnet.js"); + +async function main() { + const { MONO } = await createDotnetRuntime(); + const app_args = process.argv.slice(2); + const dllName = "Wasm.Console.Node.CJS.Sample.dll"; + await MONO.mono_run_main_and_exit(dllName, app_args); +}; +main(); diff --git a/src/mono/sample/wasm/console-node-es6/Makefile b/src/mono/sample/wasm/console-node-es6/Makefile new file mode 100644 index 00000000000000..a97fd6232158cf --- /dev/null +++ b/src/mono/sample/wasm/console-node-es6/Makefile @@ -0,0 +1,17 @@ +TOP=../../../../.. + +include ../wasm.mk + +ifneq ($(AOT),) +override MSBUILD_ARGS+=/p:RunAOTCompilation=true +endif + +ifneq ($(V),) +DOTNET_MONO_LOG_LEVEL=--setenv=MONO_LOG_LEVEL=debug +endif + +PROJECT_NAME=Wasm.Console.Node.ES6.Sample.csproj +CONSOLE_DLL=Wasm.Console.Node.ES6.Sample.dll +MAIN_JS=main.mjs + +run: run-console-node diff --git a/src/mono/sample/wasm/console/Program.cs b/src/mono/sample/wasm/console-node-es6/Program.cs similarity index 100% rename from src/mono/sample/wasm/console/Program.cs rename to src/mono/sample/wasm/console-node-es6/Program.cs diff --git a/src/mono/sample/wasm/console-node-es6/Wasm.Console.Node.ES6.Sample.csproj b/src/mono/sample/wasm/console-node-es6/Wasm.Console.Node.ES6.Sample.csproj new file mode 100644 index 00000000000000..2ea291ea047a75 --- /dev/null +++ b/src/mono/sample/wasm/console-node-es6/Wasm.Console.Node.ES6.Sample.csproj @@ -0,0 +1,20 @@ + + + true + main.mjs + true + true + + + + + + + + + <_SampleProject>Wasm.Console.Node.ES6.Sample.csproj + <_SampleAssembly>Wasm.Console.Node.ES6.Sample.dll + + + + diff --git a/src/mono/sample/wasm/console-node-es6/main.mjs b/src/mono/sample/wasm/console-node-es6/main.mjs new file mode 100644 index 00000000000000..2325a97eb35f3b --- /dev/null +++ b/src/mono/sample/wasm/console-node-es6/main.mjs @@ -0,0 +1,19 @@ +import { createRequire } from 'module'; +import { dirname } from 'path'; +import { fileURLToPath } from 'url'; +import createDotnetRuntime from './dotnet.js' + +const { MONO } = await createDotnetRuntime(() => ({ + imports: { + //TODO internalize into dotnet.js if possible + require: createRequire(import.meta.url) + }, + //TODO internalize into dotnet.js if possible + scriptDirectory: dirname(fileURLToPath(import.meta.url)) + '/', + disableDotnet6Compatibility: true, + configSrc: "./mono-config.json", +})); + +const app_args = process.argv.slice(2); +const dllName = "Wasm.Console.Node.ES6.Sample.dll"; +await MONO.mono_run_main_and_exit(dllName, app_args); diff --git a/src/mono/sample/wasm/console-node-es6/package.json b/src/mono/sample/wasm/console-node-es6/package.json new file mode 100644 index 00000000000000..fd2cb753e7d8b5 --- /dev/null +++ b/src/mono/sample/wasm/console-node-es6/package.json @@ -0,0 +1,3 @@ +{ + "type":"module" +} \ No newline at end of file diff --git a/src/mono/sample/wasm/console/Makefile b/src/mono/sample/wasm/console-v8-cjs/Makefile similarity index 65% rename from src/mono/sample/wasm/console/Makefile rename to src/mono/sample/wasm/console-v8-cjs/Makefile index 20c9da20ad0be5..b2683b63c6847b 100644 --- a/src/mono/sample/wasm/console/Makefile +++ b/src/mono/sample/wasm/console-v8-cjs/Makefile @@ -10,7 +10,8 @@ ifneq ($(V),) DOTNET_MONO_LOG_LEVEL=--setenv=MONO_LOG_LEVEL=debug endif -PROJECT_NAME=Wasm.Console.Sample.csproj -CONSOLE_DLL=Wasm.Console.Sample.dll +PROJECT_NAME=Wasm.Console.V8.CJS.Sample.csproj +CONSOLE_DLL=Wasm.Console.V8.CJS.Sample.dll +MAIN_JS=main.cjs run: run-console diff --git a/src/mono/sample/wasm/console-v8-cjs/Program.cs b/src/mono/sample/wasm/console-v8-cjs/Program.cs index d5ea012a33c792..7d959dedae34d6 100644 --- a/src/mono/sample/wasm/console-v8-cjs/Program.cs +++ b/src/mono/sample/wasm/console-v8-cjs/Program.cs @@ -13,6 +13,6 @@ public static async Task Main(string[] args) for (int i = 0; i < args.Length; i++) { Console.WriteLine($"args[{i}] = {args[i]}"); } - return args.Length; + return 0; } } diff --git a/src/mono/sample/wasm/console-v8-cjs/Wasm.Console.V8.CJS.Sample.csproj b/src/mono/sample/wasm/console-v8-cjs/Wasm.Console.V8.CJS.Sample.csproj index 0b28f10d49c3a9..81de63e08cd5b7 100644 --- a/src/mono/sample/wasm/console-v8-cjs/Wasm.Console.V8.CJS.Sample.csproj +++ b/src/mono/sample/wasm/console-v8-cjs/Wasm.Console.V8.CJS.Sample.csproj @@ -1,7 +1,7 @@ true - main.js + main.cjs true false diff --git a/src/mono/sample/wasm/console-v8-cjs/main.js b/src/mono/sample/wasm/console-v8-cjs/main.cjs similarity index 100% rename from src/mono/sample/wasm/console-v8-cjs/main.js rename to src/mono/sample/wasm/console-v8-cjs/main.cjs diff --git a/src/mono/sample/wasm/console-v8-es6/Makefile b/src/mono/sample/wasm/console-v8-es6/Makefile new file mode 100644 index 00000000000000..7ceb7d3a72d0a4 --- /dev/null +++ b/src/mono/sample/wasm/console-v8-es6/Makefile @@ -0,0 +1,17 @@ +TOP=../../../../.. + +include ../wasm.mk + +ifneq ($(AOT),) +override MSBUILD_ARGS+=/p:RunAOTCompilation=true +endif + +ifneq ($(V),) +DOTNET_MONO_LOG_LEVEL=--setenv=MONO_LOG_LEVEL=debug +endif + +PROJECT_NAME=Wasm.Console.V8.ES6.Sample.csproj +CONSOLE_DLL=Wasm.Console.V8.ES6.Sample.dll +MAIN_JS=v8shim.cjs + +run: run-console diff --git a/src/mono/sample/wasm/console-v8-es6/Program.cs b/src/mono/sample/wasm/console-v8-es6/Program.cs new file mode 100644 index 00000000000000..7d959dedae34d6 --- /dev/null +++ b/src/mono/sample/wasm/console-v8-es6/Program.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; +using System.Threading.Tasks; + +public class Test +{ + public static async Task Main(string[] args) + { + await Task.Delay(1); + Console.WriteLine("Hello World!"); + for (int i = 0; i < args.Length; i++) { + Console.WriteLine($"args[{i}] = {args[i]}"); + } + return 0; + } +} diff --git a/src/mono/sample/wasm/console/Wasm.Console.Sample.csproj b/src/mono/sample/wasm/console-v8-es6/Wasm.Console.V8.ES6.Sample.csproj similarity index 53% rename from src/mono/sample/wasm/console/Wasm.Console.Sample.csproj rename to src/mono/sample/wasm/console-v8-es6/Wasm.Console.V8.ES6.Sample.csproj index 1dabb4aa0c787f..897e9e72482008 100644 --- a/src/mono/sample/wasm/console/Wasm.Console.Sample.csproj +++ b/src/mono/sample/wasm/console-v8-es6/Wasm.Console.V8.ES6.Sample.csproj @@ -1,13 +1,18 @@ true - $(MonoProjectRoot)\wasm\test-main.js + v8shim.cjs true + true + + + + - <_SampleProject>Wasm.Console.Sample.csproj - <_SampleAssembly>Wasm.Console.Sample.dll + <_SampleProject>Wasm.Console.V8.ES6.Sample.csproj + <_SampleAssembly>Wasm.Console.V8.ES6.Sample.dll diff --git a/src/mono/sample/wasm/console-v8-es6/main.mjs b/src/mono/sample/wasm/console-v8-es6/main.mjs new file mode 100644 index 00000000000000..f6bfd7ba8e97dd --- /dev/null +++ b/src/mono/sample/wasm/console-v8-es6/main.mjs @@ -0,0 +1,11 @@ +import createDotnetRuntime from './dotnet.js' + +const dllName = "Wasm.Console.V8.ES6.Sample.dll"; +const app_args = Array.from(arguments); + +async function main() { + const { MONO } = await createDotnetRuntime(); + await MONO.mono_run_main_and_exit(dllName, app_args); +} + +main(); \ No newline at end of file diff --git a/src/mono/sample/wasm/console-v8-es6/v8shim.cjs b/src/mono/sample/wasm/console-v8-es6/v8shim.cjs new file mode 100644 index 00000000000000..f8c2a61fe87fed --- /dev/null +++ b/src/mono/sample/wasm/console-v8-es6/v8shim.cjs @@ -0,0 +1,15 @@ +if (typeof globalThis.URL === 'undefined') { + globalThis.URL = class URL { + constructor(url) { + this.url = url; + } + toString() { + return this.url; + } + }; +} + +import('./main.mjs').catch(err => { + console.log(err); + console.log(err.stack); +}); \ No newline at end of file diff --git a/src/mono/sample/wasm/wasm.mk b/src/mono/sample/wasm/wasm.mk index 624722c2169454..89759c3c7745ca 100644 --- a/src/mono/sample/wasm/wasm.mk +++ b/src/mono/sample/wasm/wasm.mk @@ -30,4 +30,7 @@ run-browser: fi run-console: - cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --stack-trace-limit=1000 --single-threaded --expose_wasm test-main.js -- $(DOTNET_MONO_LOG_LEVEL) --run $(CONSOLE_DLL) $(ARGS) + cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --stack-trace-limit=1000 --single-threaded --expose_wasm $(MAIN_JS) -- $(DOTNET_MONO_LOG_LEVEL) --run $(CONSOLE_DLL) $(ARGS) + +run-console-node: + cd bin/$(CONFIG)/AppBundle && node --stack-trace-limit=1000 --single-threaded --expose_wasm $(MAIN_JS) -- $(DOTNET_MONO_LOG_LEVEL) --run $(CONSOLE_DLL) $(ARGS) diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index d3f9b3bf08cb2a..d171b9395a716a 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -3,6 +3,10 @@ TOP=$(realpath $(CURDIR)/../../..) escape_quote = $(subst ",\",$(1)) +ifneq ($(V),) +MSBUILD_ARGS+=/p:MonoVerboseBuild=true +endif + DOTNET=$(TOP)/dotnet.sh JSVU=$(HOME)/.jsvu CHROMEDRIVER?=$(HOME)/.chromedriver diff --git a/src/mono/wasm/README.md b/src/mono/wasm/README.md index b68aeb2d54c99a..37d5fa29643445 100644 --- a/src/mono/wasm/README.md +++ b/src/mono/wasm/README.md @@ -149,11 +149,11 @@ The samples in `src/mono/sample/wasm` can be build and run like this: * console Hello world sample -`dotnet build /t:RunSample console/Wasm.Console.Sample.csproj` +`dotnet build /t:RunSample console-v8-cjs/Wasm.Console.V8.CJS.Sample.csproj` * browser TestMeaning sample -`dotnet build /t:RunSample browser/Wasm.Browser.Sample.csproj` +`dotnet build /t:RunSample browser/Wasm.Browser.CJS.Sample.csproj` To build and run the samples with AOT, add `/p:RunAOTCompilation=true` to the above command lines. diff --git a/src/mono/wasm/build/WasmApp.InTree.props b/src/mono/wasm/build/WasmApp.InTree.props index e5968f1320a949..ab70ccd739d44a 100644 --- a/src/mono/wasm/build/WasmApp.InTree.props +++ b/src/mono/wasm/build/WasmApp.InTree.props @@ -12,4 +12,10 @@ link false + + + <_MonoRuntimeComponentDontLink Include="libmono-component-debugger-stub-static.a" /> + <_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" /> + <_MonoRuntimeComponentDontLink Include="libmono-component-hot_reload-stub-static.a" /> + diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index ea282f9638cf1e..6fb3e5beda18a7 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -502,6 +502,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_ + <_AotInputAssemblies Include="@(_WasmAssembliesInternal)"> @@ -561,7 +562,8 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_ CacheFilePath="$(_AOTCompilerCacheFile)" LLVMDebug="dwarfdebug" LLVMPath="$(EmscriptenUpstreamBinPath)" - IntermediateOutputPath="$(_WasmIntermediateOutputPath)"> + IntermediateOutputPath="$(_WasmIntermediateOutputPath)" + AotProfilePath="@(AotProfilePath)"> diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 1df620145bea36..145e5c8f7ee909 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -61,6 +61,7 @@ - $(WasmBuildOnlyAfterPublish) - Causes relinking to be done only for Publish. Defaults to false. - $(RunAOTCompilationAfterBuild) - Run AOT compilation even after Build. By default, it is run only for publish. Defaults to false. + - $(WasmAotProfilePath) - Path to an AOT profile file. Public items: - @(WasmExtraFilesToDeploy) - Files to copy to $(WasmAppDir). diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs index ee7def9514c54c..e948c6abe0ebf7 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -60,36 +60,59 @@ public MessageId(string sessionId, int id) internal class DotnetObjectId { public string Scheme { get; } - public string Value { get; } + public int Value { get; } + public int SubValue { get; set; } public static bool TryParse(JToken jToken, out DotnetObjectId objectId) => TryParse(jToken?.Value(), out objectId); public static bool TryParse(string id, out DotnetObjectId objectId) { objectId = null; - if (id == null) - return false; - - if (!id.StartsWith("dotnet:")) - return false; + try { + if (id == null) + return false; - string[] parts = id.Split(":", 3); + if (!id.StartsWith("dotnet:")) + return false; - if (parts.Length < 3) - return false; + string[] parts = id.Split(":"); - objectId = new DotnetObjectId(parts[1], parts[2]); + if (parts.Length < 3) + return false; - return true; + objectId = new DotnetObjectId(parts[1], int.Parse(parts[2])); + switch (objectId.Scheme) + { + case "methodId": + { + parts = id.Split(":"); + objectId.SubValue = int.Parse(parts[3]); + break; + } + } + return true; + } + catch (Exception) + { + return false; + } } - public DotnetObjectId(string scheme, string value) + public DotnetObjectId(string scheme, int value) { Scheme = scheme; Value = value; } - public override string ToString() => $"dotnet:{Scheme}:{Value}"; + public override string ToString() + { + switch (Scheme) + { + case "methodId": + return $"dotnet:{Scheme}:{Value}:{SubValue}"; + } + return $"dotnet:{Scheme}:{Value}"; + } } public struct Result diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 8516b349f4cf23..bcef7dbed5272d 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -53,7 +53,7 @@ public async Task GetValueFromObject(JToken objRet, CancellationToken t { if (DotnetObjectId.TryParse(objRet?["value"]?["objectId"]?.Value(), out DotnetObjectId objectId)) { - var exceptionObject = await context.SdbAgent.GetObjectValues(int.Parse(objectId.Value), GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.OwnProperties, token); + var exceptionObject = await context.SdbAgent.GetObjectValues(objectId.Value, GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.OwnProperties, token); var exceptionObjectMessage = exceptionObject.FirstOrDefault(attr => attr["name"].Value().Equals("_message")); exceptionObjectMessage["value"]["value"] = objRet["value"]?["className"]?.Value() + ": " + exceptionObjectMessage["value"]?["value"]?.Value(); return exceptionObjectMessage["value"]?.Value(); @@ -342,17 +342,15 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, switch (objectId.Scheme) { case "array": - rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(objectId.Value), token); + rootObject["value"] = await context.SdbAgent.GetArrayValues(objectId.Value, token); return (JObject)rootObject["value"][elementIdx]["value"]; case "object": - var typeIds = await context.SdbAgent.GetTypeIdFromObject(int.Parse(objectId.Value), true, token); + var typeIds = await context.SdbAgent.GetTypeIdFromObject(objectId.Value, true, token); int methodId = await context.SdbAgent.GetMethodIdByName(typeIds[0], "ToArray", token); - var commandParamsObjWriter = new MonoBinaryWriter(); - commandParamsObjWriter.WriteObj(objectId, context.SdbAgent); - var toArrayRetMethod = await context.SdbAgent.InvokeMethod(commandParamsObjWriter.GetParameterBuffer(), methodId, elementAccess.Expression.ToString(), token); + var toArrayRetMethod = await context.SdbAgent.InvokeMethodInObject(objectId.Value, methodId, elementAccess.Expression.ToString(), token); rootObject = await GetValueFromObject(toArrayRetMethod, token); DotnetObjectId.TryParse(rootObject?["objectId"]?.Value(), out DotnetObjectId arrayObjectId); - rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(arrayObjectId.Value), token); + rootObject["value"] = await context.SdbAgent.GetArrayValues(arrayObjectId.Value, token); return (JObject)rootObject["value"][elementIdx]["value"]; default: throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of type '{objectId.Scheme}'"); @@ -391,7 +389,7 @@ public async Task Resolve(InvocationExpressionSyntax method, Dictionary if (rootObject != null) { DotnetObjectId.TryParse(rootObject?["objectId"]?.Value(), out DotnetObjectId objectId); - var typeIds = await context.SdbAgent.GetTypeIdFromObject(int.Parse(objectId.Value), true, token); + var typeIds = await context.SdbAgent.GetTypeIdFromObject(objectId.Value, true, token); int methodId = await context.SdbAgent.GetMethodIdByName(typeIds[0], methodName, token); var className = await context.SdbAgent.GetTypeNameOriginal(typeIds[0], token); if (methodId == 0) //try to search on System.Linq.Enumerable diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index e0f796e09c5ad2..b12de2655f70fd 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -411,7 +411,7 @@ protected override async Task AcceptCommand(MessageId id, string method, J { case "scope": return await OnSetVariableValue(id, - int.Parse(objectId.Value), + objectId.Value, args?["variableName"]?.Value(), args?["newValue"], token); @@ -449,7 +449,7 @@ protected override async Task AcceptCommand(MessageId id, string method, J { case "scope": return await OnEvaluateOnCallFrame(id, - int.Parse(objectId.Value), + objectId.Value, args?["expression"]?.Value(), token); default: return false; @@ -586,16 +586,17 @@ private async Task CallOnFunction(MessageId id, JObject args, Cancellation switch (objectId.Scheme) { case "object": - args["details"] = await context.SdbAgent.GetObjectProxy(int.Parse(objectId.Value), token); + case "methodId": + args["details"] = await context.SdbAgent.GetObjectProxy(objectId.Value, token); break; case "valuetype": - args["details"] = await context.SdbAgent.GetValueTypeProxy(int.Parse(objectId.Value), token); + args["details"] = await context.SdbAgent.GetValueTypeProxy(objectId.Value, token); break; case "pointer": - args["details"] = await context.SdbAgent.GetPointerContent(int.Parse(objectId.Value), token); + args["details"] = await context.SdbAgent.GetPointerContent(objectId.Value, token); break; case "array": - args["details"] = await context.SdbAgent.GetArrayValuesProxy(int.Parse(objectId.Value), token); + args["details"] = await context.SdbAgent.GetArrayValuesProxy(objectId.Value, token); break; case "cfo_res": { @@ -680,20 +681,25 @@ internal async Task RuntimeGetPropertiesInternal(SessionId id, DotnetObj { case "scope": { - var res = await GetScopeProperties(id, int.Parse(objectId.Value), token); + var res = await GetScopeProperties(id, objectId.Value, token); return res.Value?["result"]; } case "valuetype": - return await context.SdbAgent.GetValueTypeValues(int.Parse(objectId.Value), accessorPropertiesOnly, token); + return await context.SdbAgent.GetValueTypeValues(objectId.Value, accessorPropertiesOnly, token); case "array": - return await context.SdbAgent.GetArrayValues(int.Parse(objectId.Value), token); + return await context.SdbAgent.GetArrayValues(objectId.Value, token); + case "methodId": + { + var objRet = await context.SdbAgent.InvokeMethodInObject(objectId.Value, objectId.SubValue, "", token); + return new JArray(objRet); + } case "object": - return await context.SdbAgent.GetObjectValues(int.Parse(objectId.Value), objectValuesOpt, token); + return await context.SdbAgent.GetObjectValues(objectId.Value, objectValuesOpt, token); case "pointer": - return new JArray{await context.SdbAgent.GetPointerContent(int.Parse(objectId.Value), token)}; + return new JArray{await context.SdbAgent.GetPointerContent(objectId.Value, token)}; case "cfo_res": { - Result res = await SendMonoCommand(id, MonoCommands.GetDetails(RuntimeId, int.Parse(objectId.Value), args), token); + Result res = await SendMonoCommand(id, MonoCommands.GetDetails(RuntimeId, objectId.Value, args), token); string value_json_str = res.Value["result"]?["value"]?["__value_as_json_string__"]?.Value(); return value_json_str != null ? JArray.Parse(value_json_str) : null; } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index 216f78a53af564..35d1ef4fceba12 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -502,7 +502,7 @@ protected unsafe void WriteBigEndian(T val) where T : struct base.Write(data); } - private void Write(ElementType type, T value) where T : struct => Write((byte)type, value); + internal void Write(ElementType type, T value) where T : struct => Write((byte)type, value); private void Write(T1 type, T2 value) where T1 : struct where T2 : struct { @@ -514,11 +514,11 @@ public void WriteObj(DotnetObjectId objectId, MonoSDBHelper SdbHelper) { if (objectId.Scheme == "object") { - Write(ElementType.Class, int.Parse(objectId.Value)); + Write(ElementType.Class, objectId.Value); } else if (objectId.Scheme == "valuetype") { - Write(SdbHelper.valueTypes[int.Parse(objectId.Value)].valueTypeBuffer); + Write(SdbHelper.valueTypes[objectId.Value].valueTypeBuffer); } } public async Task WriteConst(LiteralExpressionSyntax constValue, MonoSDBHelper SdbHelper, CancellationToken token) @@ -1537,6 +1537,13 @@ public async Task InvokeMethod(ArraySegment valueTypeBuffer, int return await CreateJObjectForVariableValue(retDebuggerCmdReader, varName, false, -1, false, token); } + public async Task InvokeMethodInObject(int objectId, int methodId, string varName, CancellationToken token) + { + using var commandParamsObjWriter = new MonoBinaryWriter(); + commandParamsObjWriter.Write(ElementType.Class, objectId); + return await InvokeMethod(commandParamsObjWriter.GetParameterBuffer(), methodId, varName, token); + } + public async Task GetPropertyMethodIdByName(int typeId, string propertyName, CancellationToken token) { using var retDebuggerCmdReader = await GetTypePropertiesReader(typeId, token); @@ -1559,13 +1566,14 @@ public async Task GetPropertyMethodIdByName(int typeId, string propertyName return -1; } - public async Task CreateJArrayForProperties(int typeId, ArraySegment object_buffer, JArray attributes, bool isAutoExpandable, string objectId, bool isOwn, CancellationToken token) + public async Task CreateJArrayForProperties(int typeId, ArraySegment object_buffer, JArray attributes, bool isAutoExpandable, string objectIdStr, bool isOwn, CancellationToken token) { JArray ret = new JArray(); using var retDebuggerCmdReader = await GetTypePropertiesReader(typeId, token); if (retDebuggerCmdReader == null) return null; - + if (!DotnetObjectId.TryParse(objectIdStr, out DotnetObjectId objectId)) + return null; var nProperties = retDebuggerCmdReader.ReadInt32(); for (int i = 0 ; i < nProperties; i++) { @@ -1595,11 +1603,11 @@ public async Task CreateJArrayForProperties(int typeId, ArraySegment GetHoistedLocalVariables(int objectId, JArray asyncLoc { if (DotnetObjectId.TryParse(asyncLocal?["value"]?["objectId"]?.Value(), out DotnetObjectId dotnetObjectId)) { - if (int.TryParse(dotnetObjectId.Value, out int objectIdToGetInfo) && !objectsAlreadyRead.Contains(objectIdToGetInfo)) + if (!objectsAlreadyRead.Contains(dotnetObjectId.Value)) { - var asyncLocalsFromObject = await GetObjectValues(objectIdToGetInfo, GetObjectCommandOptions.WithProperties, token); - var hoistedLocalVariable = await GetHoistedLocalVariables(objectIdToGetInfo, asyncLocalsFromObject, token); + var asyncLocalsFromObject = await GetObjectValues(dotnetObjectId.Value, GetObjectCommandOptions.WithProperties, token); + var hoistedLocalVariable = await GetHoistedLocalVariables(dotnetObjectId.Value, asyncLocalsFromObject, token); asyncLocalsFull = new JArray(asyncLocalsFull.Union(hoistedLocalVariable)); } } @@ -2295,7 +2303,7 @@ public async Task GetValuesFromDebuggerProxyAttribute(int objectId, int var retMethod = await InvokeMethod(invokeParamsWriter.GetParameterBuffer(), methodId, "methodRet", token); DotnetObjectId.TryParse(retMethod?["value"]?["objectId"]?.Value(), out DotnetObjectId dotnetObjectId); - var displayAttrs = await GetObjectValues(int.Parse(dotnetObjectId.Value), GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.ForDebuggerProxyAttribute, token); + var displayAttrs = await GetObjectValues(dotnetObjectId.Value, GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.ForDebuggerProxyAttribute, token); return displayAttrs; } } @@ -2385,7 +2393,7 @@ public async Task GetObjectValues(int objectId, GetObjectCommandOptions if (!getCommandType.HasFlag(GetObjectCommandOptions.WithProperties)) return ret; using var commandParamsObjWriter = new MonoBinaryWriter(); - commandParamsObjWriter.WriteObj(new DotnetObjectId("object", $"{objectId}"), this); + commandParamsObjWriter.WriteObj(new DotnetObjectId("object", objectId), this); var props = await CreateJArrayForProperties(typeId[i], commandParamsObjWriter.GetParameterBuffer(), ret, getCommandType.HasFlag(GetObjectCommandOptions.ForDebuggerProxyAttribute), $"dotnet:object:{objectId}", i == 0, token); ret = new JArray(ret.Union(props)); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs index fbc176dc2ca5e3..f22b4ae3196bef 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs @@ -623,7 +623,12 @@ internal async Task CheckCustomType(JToken actual_val, JToken exp_val, string la AssertEqual("Function", get["className"]?.Value(), $"{label}-className"); AssertStartsWith($"get {exp_val["type_name"]?.Value()} ()", get["description"]?.Value(), $"{label}-description"); AssertEqual("function", get["type"]?.Value(), $"{label}-type"); - + var expectedValue = exp_val["value"]; + if (expectedValue.Type != JTokenType.Null) + { + var valueAfterRunGet = await GetProperties(get["objectId"]?.Value()); + await CheckValue(valueAfterRunGet[0]?["value"], expectedValue, exp_val["type_name"]?.Value()); + } break; } @@ -1059,7 +1064,7 @@ internal static JObject TDelegate(string className, string target) => JObject.Fr internal static JObject TIgnore() => JObject.FromObject(new { __custom_type = "ignore_me" }); - internal static JObject TGetter(string type) => JObject.FromObject(new { __custom_type = "getter", type_name = type }); + internal static JObject TGetter(string type, JObject value = null) => JObject.FromObject(new { __custom_type = "getter", type_name = type, value = value}); internal static JObject TDateTime(DateTime dt) => JObject.FromObject(new { diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs index ca5afa742cfb3f..f91ba3c012effb 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/GetPropertiesTests.cs @@ -340,7 +340,7 @@ public async Task GetObjectValueWithInheritance() { var pause_location = await EvaluateAndCheck( "window.setTimeout(function() { invoke_static_method('[debugger-test] TestChild:TestWatchWithInheritance'); }, 1);", - "dotnet://debugger-test.dll/debugger-test2.cs", 127, 8, + "dotnet://debugger-test.dll/debugger-test2.cs", 128, 8, "TestWatchWithInheritance"); var frame_id = pause_location["callFrames"][0]["callFrameId"].Value(); var frame_locals = await GetProperties(frame_id); @@ -350,9 +350,10 @@ public async Task GetObjectValueWithInheritance() j = TNumber(20), i = TNumber(50), k = TNumber(30), - GetJ = TGetter("GetJ"), - GetI = TGetter("GetI"), - GetK = TGetter("GetK") + GetJ = TGetter("GetJ", TNumber(20)), + GetI = TGetter("GetI", TNumber(50)), + GetK = TGetter("GetK", TNumber(30)), + GetD = TGetter("GetD", TDateTime(new DateTime(2020, 7, 6, 5, 4, 3))) }, "test_props"); await EvaluateOnCallFrameAndCheck(frame_id, ($"test.GetJ", TNumber(20)), diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessStartup.cs b/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessStartup.cs index e7be4958421bed..c8ac7709007118 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessStartup.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/TestHarnessStartup.cs @@ -114,9 +114,9 @@ public async Task LaunchAndServe(ProcessStartInfo psi, HttpContext context, Func proc.BeginErrorReadLine(); proc.BeginOutputReadLine(); - if (await Task.WhenAny(tcs.Task, Task.Delay(5000)) != tcs.Task) + if (await Task.WhenAny(tcs.Task, Task.Delay(20000)) != tcs.Task) { - Logger.LogError("Didnt get the con string after 5s."); + Logger.LogError("Didnt get the con string after 20s."); throw new Exception("node.js timedout"); } var line = await tcs.Task; diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs index 9756cbe26de449..28c908261a6aa8 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test2.cs @@ -118,6 +118,7 @@ public class TestChild : TestParent { public int i = 50; public int GetI => i; + public DateTime GetD => new DateTime(2020, 7, 6, 5, 4, 3); public TestChild() { Console.WriteLine("Hi"); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index b8e5ca141e2062..98dd8f8e4e9bb5 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -21,7 +21,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_parse_runtime_options", null, ["number", "number"]], ["mono_wasm_strdup", "number", ["string"]], ["mono_background_exec", null, []], - ["mono_set_timeout_exec", null, ["number"]], + ["mono_set_timeout_exec", null, []], ["mono_wasm_load_icu_data", "number", ["number"]], ["mono_wasm_get_icudt_name", "string", ["string"]], ["mono_wasm_add_assembly", "number", ["string", "number", "number"]], @@ -82,7 +82,7 @@ export interface t_Cwraps { mono_wasm_strdup(value: string): number; mono_wasm_parse_runtime_options(length: number, argv: VoidPtr): void; mono_background_exec(): void; - mono_set_timeout_exec(id: number): void; + mono_set_timeout_exec(): void; mono_wasm_load_icu_data(offset: VoidPtr): number; mono_wasm_get_icudt_name(name: string): string; mono_wasm_add_assembly(name: string, data: VoidPtr, size: number): number; diff --git a/src/mono/wasm/runtime/scheduling.ts b/src/mono/wasm/runtime/scheduling.ts index b2b5616738e78f..c997c2ea9ff280 100644 --- a/src/mono/wasm/runtime/scheduling.ts +++ b/src/mono/wasm/runtime/scheduling.ts @@ -38,7 +38,7 @@ export function prevent_timer_throttling(): void { for (let schedule = next_reach_time; schedule < desired_reach_time; schedule += light_throttling_frequency) { const delay = schedule - now; setTimeout(() => { - cwraps.mono_set_timeout_exec(0); + cwraps.mono_set_timeout_exec(); pump_count++; pump_message(); }, delay); @@ -52,9 +52,9 @@ export function schedule_background_exec(): void { } let lastScheduledTimeoutId: any = undefined; -export function mono_set_timeout(timeout: number, id: number): void { +export function mono_set_timeout(timeout: number): void { function mono_wasm_set_timeout_exec() { - cwraps.mono_set_timeout_exec(id); + cwraps.mono_set_timeout_exec(); } if (lastScheduledTimeoutId) { clearTimeout(lastScheduledTimeoutId); diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt index 60780bf85c7089..45bfea5a8e7b62 100644 --- a/src/native/libs/System.Native/CMakeLists.txt +++ b/src/native/libs/System.Native/CMakeLists.txt @@ -27,7 +27,6 @@ set(NATIVE_SOURCES pal_process.c pal_random.c pal_runtimeinformation.c - pal_runtimeextensions.c pal_signal.c pal_string.c pal_tcpstate.c diff --git a/src/native/libs/System.Native/entrypoints.c b/src/native/libs/System.Native/entrypoints.c index 8b251d93e3f1d9..41c379cb90db51 100644 --- a/src/native/libs/System.Native/entrypoints.c +++ b/src/native/libs/System.Native/entrypoints.c @@ -21,7 +21,6 @@ #include "pal_networkstatistics.h" #include "pal_process.h" #include "pal_random.h" -#include "pal_runtimeextensions.h" #include "pal_runtimeinformation.h" #include "pal_searchpath.h" #include "pal_signal.h" @@ -214,7 +213,6 @@ static const Entry s_sysNative[] = DllImportEntry(SystemNative_GetProcessPath) DllImportEntry(SystemNative_GetNonCryptographicallySecureRandomBytes) DllImportEntry(SystemNative_GetCryptographicallySecureRandomBytes) - DllImportEntry(SystemNative_GetNodeName) DllImportEntry(SystemNative_GetUnixName) DllImportEntry(SystemNative_GetUnixRelease) DllImportEntry(SystemNative_GetUnixVersion) diff --git a/src/native/libs/System.Native/pal_runtimeextensions.c b/src/native/libs/System.Native/pal_runtimeextensions.c deleted file mode 100644 index b4690ecd6ef9bf..00000000000000 --- a/src/native/libs/System.Native/pal_runtimeextensions.c +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include "pal_runtimeextensions.h" -#include "pal_types.h" -#include -#include - -int32_t SystemNative_GetNodeName(char* version, int* capacity) -{ - struct utsname _utsname; - if (uname(&_utsname) != -1) - { - int r = snprintf(version, (size_t)(*capacity), "%s", _utsname.nodename); - if (r > *capacity) - { - *capacity = r + 1; - return -1; - } - } - - return 0; -} diff --git a/src/native/libs/System.Native/pal_runtimeextensions.h b/src/native/libs/System.Native/pal_runtimeextensions.h deleted file mode 100644 index 99d14765d412c6..00000000000000 --- a/src/native/libs/System.Native/pal_runtimeextensions.h +++ /dev/null @@ -1,9 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#pragma once - -#include "pal_compiler.h" -#include "pal_types.h" - -PALEXPORT int32_t SystemNative_GetNodeName(char* version, int* capacity); diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 8eadf95602021f..1485dae7cb0069 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -61,6 +61,9 @@ endif() # which are not distinguished from the test failing. So no error for that one. # For clang-5.0 avoid errors like "unused variable 'err' [-Werror,-Wunused-variable]". set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror -Wno-error=unused-value -Wno-error=unused-variable") +if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wno-error=builtin-requires-header") +endif() # Apple platforms like macOS/iOS allow targeting older operating system versions with a single SDK, # the mere presence of a symbol in the SDK doesn't tell us whether the deployment target really supports it. @@ -675,7 +678,16 @@ check_symbol_exists( time.h HAVE_CLOCK_GETTIME_NSEC_NP) -check_library_exists(pthread pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK) +check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) +check_library_exists(c pthread_create "" HAVE_PTHREAD_IN_LIBC) + +if (HAVE_LIBPTHREAD) + set(PTHREAD_LIBRARY pthread) +elseif (HAVE_PTHREAD_IN_LIBC) + set(PTHREAD_LIBRARY c) +endif() + +check_library_exists(${PTHREAD_LIBRARY} pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK) check_symbol_exists( futimes diff --git a/src/tasks/installer.tasks/GenerateRunScript.cs b/src/tasks/installer.tasks/GenerateRunScript.cs index a2629768aa2027..142ac7c996fbd6 100644 --- a/src/tasks/installer.tasks/GenerateRunScript.cs +++ b/src/tasks/installer.tasks/GenerateRunScript.cs @@ -11,6 +11,9 @@ namespace Microsoft.DotNet.Build.Tasks { public class GenerateRunScript : Task { + [Required] + public string[] SetCommands { get; set; } + [Required] public string[] RunCommands { get; set; } @@ -60,6 +63,17 @@ private void WriteRunScript(string templateContent, string extension) bool isUnix = extension == ".sh"; string lineFeed = isUnix ? "\n" : "\r\n"; + var setCommandsBuilder = new StringBuilder(); + for (int i = 0; i < SetCommands.Length; i++) + { + setCommandsBuilder.Append(SetCommands[i]); + if (i < SetCommands.Length - 1) + { + setCommandsBuilder.Append(lineFeed); + } + } + templateContent = templateContent.Replace("[[SetCommands]]", setCommandsBuilder.ToString()); + var runCommandsBuilder = new StringBuilder(); for (int i = 0; i < RunCommands.Length; i++) { @@ -71,29 +85,22 @@ private void WriteRunScript(string templateContent, string extension) } templateContent = templateContent.Replace("[[RunCommands]]", runCommandsBuilder.ToString()); + + var setCommandEchoesBuilder = new StringBuilder(); + foreach (string setCommand in SetCommands) + { + setCommandEchoesBuilder.Append($"echo {SanitizeEcho(setCommand,isUnix)}{lineFeed}"); + } + templateContent = templateContent.Replace("[[SetCommandsEcho]]", setCommandEchoesBuilder.ToString()); + var runCommandEchoesBuilder = new StringBuilder(); foreach (string runCommand in RunCommands) { - // Escape backtick and question mark characters to avoid running commands instead of echo'ing them. - string sanitizedRunCommand = runCommand.Replace("`", "\\`") - .Replace("?", "\\") - .Replace("\r","") - .Replace("\n"," ") - .Replace("&", "^&") - .Replace(">", "^>"); - - if (isUnix) - { - // Remove parentheses and quotes from echo command before wrapping it in quotes to avoid errors on Linux. - sanitizedRunCommand = "\"" + sanitizedRunCommand.Replace("\"", "") - .Replace("(", "") - .Replace(")", "") + "\""; - } - - runCommandEchoesBuilder.Append($"echo {sanitizedRunCommand}{lineFeed}"); + runCommandEchoesBuilder.Append($"echo {SanitizeEcho(runCommand,isUnix)}{lineFeed}"); } templateContent = templateContent.Replace("[[RunCommandsEcho]]", runCommandEchoesBuilder.ToString()); + if (isUnix) { // Just in case any Windows EOLs have made it in by here, clean any up. @@ -109,5 +116,26 @@ private void WriteRunScript(string templateContent, string extension) Log.LogMessage($"Wrote {extension} run script to {OutputPath}"); } + + private static string SanitizeEcho(string command, bool isUnix){ + // Escape backtick and question mark characters to avoid running commands instead of echo'ing them. + string sanitizedRunCommand = command.Replace("`", "\\`") + .Replace("?", "\\") + .Replace("$", "") + .Replace("%", "") + .Replace("\r","") + .Replace("\n"," ") + .Replace("&", "^&") + .Replace(">", "^>"); + + if (isUnix) + { + // Remove parentheses and quotes from echo command before wrapping it in quotes to avoid errors on Linux. + sanitizedRunCommand = "\"" + sanitizedRunCommand.Replace("\"", "") + .Replace("(", "") + .Replace(")", "") + "\""; + } + return sanitizedRunCommand; + } } } \ No newline at end of file diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs index aebb02920310af..ec37a933562bd7 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs @@ -147,8 +147,9 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs, string bundleDir = Path.Combine(GetBinDir(baseDir: buildDir, config: buildArgs.Config), "AppBundle"); (string testCommand, string extraXHarnessArgs) = host switch { - RunHost.V8 => ("wasm test", "--js-file=test-main.js --engine=V8 -v trace"), - _ => ("wasm test-browser", $"-v trace -b {host}") + RunHost.V8 => ("wasm test", "--js-file=test-main.js --engine=V8 -v trace"), + RunHost.NodeJS => ("wasm test", "--js-file=test-main.js --engine=NodeJS -v trace"), + _ => ("wasm test-browser", $"-v trace -b {host}") }; string testLogPath = Path.Combine(_logPath, host.ToString()); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/RunHost.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/RunHost.cs index 0aa1ae14ea8120..137316ebb546c5 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/RunHost.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/RunHost.cs @@ -13,7 +13,8 @@ public enum RunHost Chrome = 2, Safari = 4, Firefox = 8, + NodeJS = 16, - All = V8 | Chrome//| Firefox//Safari + All = V8 | NodeJS | Chrome//| Firefox//Safari } } diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.cmd b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.cmd index 95772327e6a258..b29ec0164d085b 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.cmd +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.cmd @@ -1,15 +1,19 @@ @echo off setlocal enabledelayedexpansion -set EXECUTION_DIR=%~dp0 -set SCENARIO=%3 +:: SetCommands defined in eng\testing\tests.wasm.targets +[[SetCommands]] +[[SetCommandsEcho]] -cd %EXECUTION_DIR% +set EXECUTION_DIR=%~dp0 +if [%3] NEQ [] ( + set SCENARIO=%3 +) if [%HELIX_WORKITEM_UPLOAD_ROOT%] == [] ( - set XHARNESS_OUT=%EXECUTION_DIR%xharness-output + set "XHARNESS_OUT=%EXECUTION_DIR%xharness-output" ) else ( - set XHARNESS_OUT=%HELIX_WORKITEM_UPLOAD_ROOT%\xharness-output + set "XHARNESS_OUT=%HELIX_WORKITEM_UPLOAD_ROOT%\xharness-output" ) if [%XHARNESS_CLI_PATH%] NEQ [] ( @@ -20,16 +24,63 @@ if [%XHARNESS_CLI_PATH%] NEQ [] ( set HARNESS_RUNNER=dotnet.exe xharness ) +if [%XHARNESS_COMMAND%] == [] ( + if /I [%SCENARIO%]==[WasmTestOnBrowser] ( + set XHARNESS_COMMAND=test-browser + ) else ( + set XHARNESS_COMMAND=test + ) +) + +if /I [%XHARNESS_COMMAND%] == [test] ( + if [%JS_ENGINE%] == [] ( + if /I [%SCENARIO%] == [WasmTestOnNodeJs] ( + set "JS_ENGINE=--engine^=NodeJS" + ) else ( + set "JS_ENGINE=--engine^=V8" + ) + ) + + if [%MAIN_JS%] == [] ( + set "MAIN_JS=--js-file^=test-main.js" + ) + + if [%JS_ENGINE_ARGS%] == [] ( + set "JS_ENGINE_ARGS=--engine-arg^=--stack-trace-limit^=1000" + ) +) else ( + if [%BROWSER_PATH%] == [] ( + set "BROWSER_PATH=--browser-path^=%HELIX_CORRELATION_PAYLOAD%\chrome-win\chrome.exe" + ) +) + +if [%XHARNESS_ARGS%] == [] ( + set "XHARNESS_ARGS=%JS_ENGINE% %JS_ENGINE_ARGS% %BROWSER_PATH% %MAIN_JS%" +) + +echo EXECUTION_DIR=%EXECUTION_DIR% +echo SCENARIO=%SCENARIO% +echo XHARNESS_OUT=%XHARNESS_OUT% +echo XHARNESS_CLI_PATH=%XHARNESS_CLI_PATH% +echo HARNESS_RUNNER=%HARNESS_RUNNER% +echo XHARNESS_COMMAND=%XHARNESS_COMMAND% +echo MAIN_JS=%MAIN_JS% +echo JS_ENGINE=%JS_ENGINE% +echo JS_ENGINE_ARGS=%JS_ENGINE_ARGS% +echo XHARNESS_ARGS=%XHARNESS_ARGS% + set TEST_LOG_PATH=%XHARNESS_OUT%\logs :: ========================= BEGIN Test Execution ============================= echo ----- start %DATE% %TIME% =============== To repro directly: ===================================================== echo pushd %EXECUTION_DIR% +:: RunCommands defined in eng\testing\tests.wasm.targets [[RunCommandsEcho]] echo popd echo =========================================================================================================== pushd %EXECUTION_DIR% @echo on +:: RunCommands defined in eng\testing\tests.wasm.targets [[RunCommands]] set EXIT_CODE=%ERRORLEVEL% @echo off diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh index 7965b10230178e..95a4b8200930c6 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/RunScriptTemplate.sh @@ -1,8 +1,13 @@ #!/usr/bin/env bash -EXECUTION_DIR=$(dirname $0) +# SetCommands defined in eng\testing\tests.wasm.targets +[[SetCommands]] +[[SetCommandsEcho]] -cd $EXECUTION_DIR +EXECUTION_DIR=$(dirname $0) +if [[ -n "$3" ]]; then + SCENARIO=$3 +fi if [[ -z "$HELIX_WORKITEM_UPLOAD_ROOT" ]]; then XHARNESS_OUT="$EXECUTION_DIR/xharness-output" @@ -18,6 +23,47 @@ else HARNESS_RUNNER="dotnet xharness" fi +if [[ -z "$XHARNESS_COMMAND" ]]; then + if [[ "$SCENARIO" == "WasmTestOnBrowser" || "$SCENARIO" == "wasmtestonbrowser" ]]; then + XHARNESS_COMMAND="test-browser" + else + XHARNESS_COMMAND="test" + fi +fi + +if [[ "$XHARNESS_COMMAND" == "test" ]]; then + if [[ -z "$JS_ENGINE" ]]; then + if [[ "$SCENARIO" == "WasmTestOnNodeJs" || "$SCENARIO" == "wasmtestonnodejs" ]]; then + JS_ENGINE="--engine=NodeJS" + else + JS_ENGINE="--engine=V8" + fi + fi + + if [[ -z "$MAIN_JS" ]]; then + MAIN_JS="--js-file=test-main.js" + fi + + if [[ -z "$JS_ENGINE_ARGS" ]]; then + JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000" + fi +fi + +if [[ -z "$XHARNESS_ARGS" ]]; then + XHARNESS_ARGS="$JS_ENGINE $JS_ENGINE_ARGS $MAIN_JS" +fi + +echo EXECUTION_DIR=$EXECUTION_DIR +echo SCENARIO=$SCENARIO +echo XHARNESS_OUT=$XHARNESS_OUT +echo XHARNESS_CLI_PATH=$XHARNESS_CLI_PATH +echo HARNESS_RUNNER=$HARNESS_RUNNER +echo XHARNESS_COMMAND=$XHARNESS_COMMAND +echo MAIN_JS=$MAIN_JS +echo JS_ENGINE=$JS_ENGINE +echo JS_ENGINE_ARGS=$JS_ENGINE_ARGS +echo XHARNESS_ARGS=$XHARNESS_ARGS + function set_env_vars() { if [ "x$TEST_USING_WORKLOADS" = "xtrue" ]; then @@ -36,10 +82,22 @@ function set_env_vars() export TEST_LOG_PATH=${XHARNESS_OUT}/logs -[[RunCommands]] +pushd $EXECUTION_DIR +# ========================= BEGIN Test Execution ============================= +echo ----- start $(date) =============== To repro directly: ===================================================== +echo pushd $EXECUTION_DIR +# RunCommands defined in eng\testing\tests.wasm.targets +[[RunCommandsEcho]] +echo popd +echo =========================================================================================================== +pushd $EXECUTION_DIR +# RunCommands defined in eng\testing\tests.wasm.targets +[[RunCommands]] _exitCode=$? +popd +echo ----- end $(date) ----- exit code $_exitCode ---------------------------------------------------------- echo "XHarness artifacts: $XHARNESS_OUT" -exit $_exitCode +exit $_exitCode \ No newline at end of file diff --git a/src/tests/Common/CLRTest.CrossGen.targets b/src/tests/Common/CLRTest.CrossGen.targets index 84ec7a004c6f1e..8c4ac4919c7a09 100644 --- a/src/tests/Common/CLRTest.CrossGen.targets +++ b/src/tests/Common/CLRTest.CrossGen.targets @@ -107,13 +107,13 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then cat $__ResponseFile # Suppress some COMPlus variables for the duration of Crossgen2 execution - export -n COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun + export -n COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun COMPlus_TC_OnStackReplacement COMPlus_TC_PartialCompilation echo "Running CrossGen2: $__Command" $__Command __cg2ExitCode=$? - export COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun + export COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun COMPlus_TC_OnStackReplacement COMPlus_TC_PartialCompilation } if [ ! -z ${CompositeBuildMode+x} ]%3B then @@ -245,6 +245,9 @@ if defined RunCrossGen2 ( set "COMPlus_GCStress=" set "COMPlus_HeapVerify=" set "COMPlus_ReadyToRun=" + REM work around problems in 6.0 OSR + set "COMPlus_TC_OnStackReplacement=" + set "COMPlus_TC_PartialCompilation=" echo "!__Command!" call !__Command! diff --git a/src/tests/Common/CLRTest.NativeAot.targets b/src/tests/Common/CLRTest.NativeAot.targets index 4dc19d233c53fd..ca515f126f5280 100644 --- a/src/tests/Common/CLRTest.NativeAot.targets +++ b/src/tests/Common/CLRTest.NativeAot.targets @@ -139,22 +139,26 @@ if defined RunNativeAot ( Outputs="$(OutputPath)\nativebuild.proj" BeforeTargets="Build"> - <_RootEntryAssemblyLine Condition="$(CLRTestFullTrimming) != 'true'"><TrimmerDefaultAction>copyused</TrimmerDefaultAction> + <_RootEntryAssemblyLine Condition="$(CLRTestFullTrimming) == 'true'"><TrimmerDefaultAction>link</TrimmerDefaultAction> <_NativeAotBuildProjectFile> + $(MSBuildProjectName) - .dll + $(TargetFramework) Exe %24(MSBuildProjectDirectory)\ %24(MSBuildProjectDirectory)\ $(TargetArchitecture) $(Optimize) - true - $(NETCoreSdkVersion) + true + true + false + false + false + $(OutputRid) $(_RootEntryAssemblyLine) @@ -169,9 +173,9 @@ if defined RunNativeAot ( - + - + diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index ee88635a8b65d1..e8cf15ce7cf855 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -27,6 +27,7 @@ private static int Main() // // Tests for dependency graph in the compiler // + TestRunClassConstructor.Run(); #if !OPTIMIZED_MODE_WITHOUT_SCANNER TestContainment.Run(); TestInterfaceMethod.Run(); @@ -1655,6 +1656,26 @@ public static void Run() } } + class TestRunClassConstructor + { + static class TypeWithNoStaticFieldsButACCtor + { + static TypeWithNoStaticFieldsButACCtor() + { + s_cctorRan = true; + } + } + + private static bool s_cctorRan; + + public static void Run() + { + RuntimeHelpers.RunClassConstructor(typeof(TypeWithNoStaticFieldsButACCtor).TypeHandle); + if (!s_cctorRan) + throw new Exception(); + } + } + #region Helpers private static Type GetTestType(string testName, string typeName) diff --git a/src/tests/readytorun/multifolder/multifolder.csproj b/src/tests/readytorun/multifolder/multifolder.csproj index b159a53339245b..99c6f0ff9f12c9 100644 --- a/src/tests/readytorun/multifolder/multifolder.csproj +++ b/src/tests/readytorun/multifolder/multifolder.csproj @@ -53,6 +53,10 @@ $(CLRTestBatchPreCommands) set __Command=%__Command% "%CORE_ROOT%\crossgen2\crossgen2.dll" set __Command=%__Command% @"%__ResponseFile%" + REM work around problems in 6.0 OSR + set "COMPlus_TC_OnStackReplacement=" + set "COMPlus_TC_PartialCompilation=" + echo Response file: %__ResponseFile% type %__ResponseFile% echo ------------------ @@ -85,9 +89,8 @@ $(BashCLRTestPreCommands) echo $__OutputDir/../FolderA/FolderA/FolderA.dll>>$__ResponseFile echo $__OutputDir/../FolderB/FolderB/FolderB.dll>>$__ResponseFile - # Suppress GC standalone mode for the duration of Crossgen2 execution - local gcstandaloneModeToRestore=$COMPlus_GCName; - unset COMPlus_GCName + # Suppress some COMPlus variables for the duration of Crossgen2 execution + export -n COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun COMPlus_TC_OnStackReplacement COMPlus_TC_PartialCompilation __Command=$_DebuggerFullPath # Tests run locally need __TestDotNetCmd (set by runtest.py) or a compatible 5.0 dotnet runtime in the path @@ -105,9 +108,10 @@ $(BashCLRTestPreCommands) echo Running crossgen2: $__Command $__Command + export COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun COMPlus_TC_OnStackReplacement COMPlus_TC_PartialCompilation + ExePath=multifolder/multifolder.dll export COMPlus_NativeImageSearchPaths=$__OutputDir - export COMPlus_GCName=$gcstandaloneModeToRestore ]]>