diff --git a/eng/native.wasm.targets b/eng/native.wasm.targets
index 23217c416c7fe3..8f5d59d25c05a0 100644
--- a/eng/native.wasm.targets
+++ b/eng/native.wasm.targets
@@ -38,15 +38,9 @@
-
-
-
-
-
-
@@ -60,8 +54,6 @@
-
-
<_EmccExportedRuntimeMethods>@(EmccExportedRuntimeMethod -> '%(Identity)',',')
diff --git a/eng/pipelines/common/templates/browser-wasm-coreclr-build-tests.yml b/eng/pipelines/common/templates/browser-wasm-coreclr-build-tests.yml
index aa776908d79d07..fc3838f838ba5c 100644
--- a/eng/pipelines/common/templates/browser-wasm-coreclr-build-tests.yml
+++ b/eng/pipelines/common/templates/browser-wasm-coreclr-build-tests.yml
@@ -15,7 +15,7 @@ jobs:
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Debug
+ buildConfig: Release
runtimeFlavor: CoreCLR
platforms:
- ${{ platform }}
@@ -42,9 +42,9 @@ jobs:
jobParameters:
dependsOn:
- ${{ if eq(platform, 'browser_wasm') }}:
- - build_browser_wasm_linux_Debug_AllSubsets_CoreCLR
+ - build_browser_wasm_linux_Release_AllSubsets_CoreCLR
- ${{ if eq(platform, 'browser_wasm_win') }}:
- - build_browser_wasm_windows_Debug_AllSubsets_CoreCLR
+ - build_browser_wasm_windows_Release_AllSubsets_CoreCLR
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
testGroup: innerloop
nameSuffix: CoreCLR_WasmBuildTests
@@ -55,14 +55,14 @@ jobs:
displayName: Download built nugets for singlethreaded runtime
inputs:
buildType: current
- artifactName: 'BuildArtifacts_browser_wasm_$(_hostedOs)_Debug_AllSubsets_CoreCLR'
+ artifactName: 'BuildArtifacts_browser_wasm_$(_hostedOs)_Release_AllSubsets_CoreCLR'
downloadType: single
downloadPath: '$(Build.SourcesDirectory)/artifacts'
- task: CopyFiles@2
displayName: Copy single threaded assets
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/artifacts/BuildArtifacts_browser_wasm_$(_hostedOs)_Debug_AllSubsets_CoreCLR'
+ SourceFolder: '$(Build.SourcesDirectory)/artifacts/BuildArtifacts_browser_wasm_$(_hostedOs)_Release_AllSubsets_CoreCLR'
TargetFolder: '$(Build.SourcesDirectory)/artifacts'
CleanTargetFolder: false
diff --git a/eng/pipelines/common/templates/wasm-coreclr-library-tests.yml b/eng/pipelines/common/templates/wasm-coreclr-library-tests.yml
new file mode 100644
index 00000000000000..4f88ac30f32f83
--- /dev/null
+++ b/eng/pipelines/common/templates/wasm-coreclr-library-tests.yml
@@ -0,0 +1,101 @@
+parameters:
+ alwaysRun: false
+ extraBuildArgs: ''
+ extraHelixArguments: ''
+ isExtraPlatformsBuild: false
+ isWasmOnlyBuild: false
+ nameSuffix: ''
+ platforms: []
+ scenarios: ['WasmTestOnChrome']
+ shouldContinueOnError: false
+ shouldRunSmokeOnly: false
+
+jobs:
+
+#
+# Build for Browser/wasm and test it
+#
+- 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: coreclr
+ platforms: ${{ parameters.platforms }}
+ shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
+ variables:
+ # map dependencies variables to local variables
+ - name: alwaysRunVar
+ value: ${{ parameters.alwaysRun }}
+ # - wasm darc deps changed
+ # - any libs that can have wasm specific changes
+ # - any other wasm specific changes that are not wbt, or dbg
+ - name: shouldRunOnDefaultPipelines
+ value: $[
+ or(
+ eq(variables['wasmDarcDependenciesChanged'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_chrome.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_specific_except_wbt_dbg.containsChange'], true))
+ ]
+ # run smoke tests only if:
+ # - explicitly requested
+ # - libraries or illink changed and no wasm specific changes
+ - name: shouldRunSmokeOnlyVar
+ value: $[
+ or(
+ eq('${{ parameters.shouldRunSmokeOnly }}', 'true'),
+ and(
+ eq('${{ parameters.shouldRunSmokeOnly }}', 'onLibrariesAndIllinkChanges'),
+ ne(variables['wasmDarcDependenciesChanged'], true),
+ or(
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true),
+ eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true)
+ ),
+ ne(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_chrome.containsChange'], true),
+ ne(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_specific_except_wbt_dbg.containsChange'], true)
+ )
+ )
+ ]
+ - name: _wasmRunSmokeTestsOnlyArg
+ value: /p:RunSmokeTestsOnly=$(shouldRunSmokeOnlyVar)
+ - name: chromeInstallArg
+ ${{ if containsValue(parameters.scenarios, 'WasmTestOnChrome') }}:
+ value: /p:InstallChromeForTests=true
+ ${{ else }}:
+ value: ''
+ - name: firefoxInstallArg
+ ${{ if containsValue(parameters.scenarios, 'WasmTestOnFirefox') }}:
+ value: /p:InstallFirefoxForTests=true
+ ${{ else }}:
+ value: ''
+ - name: v8InstallArg
+ ${{ if containsValue(parameters.scenarios, 'WasmTestOnV8') }}:
+ value: /p:InstallV8ForTests=true
+ ${{ else }}:
+ value: ''
+
+ jobParameters:
+ isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
+ testGroup: innerloop
+ nameSuffix: LibraryTestsCoreCLR${{ parameters.nameSuffix }}
+ buildArgs: -s clr+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) $(chromeInstallArg) $(firefoxInstallArg) $(v8InstallArg) /maxcpucount:1 ${{ parameters.extraBuildArgs }}
+ timeoutInMinutes: 240
+ # if !alwaysRun, then:
+ # if this is runtime-wasm (isWasmOnlyBuild):
+ # - then run only if it would not have run on default pipelines (based
+ # on path changes)
+ # - else run based on path changes
+ condition: >-
+ or(
+ eq(variables['alwaysRunVar'], true),
+ eq(variables['isDefaultPipeline'], variables['shouldRunOnDefaultPipelines']))
+ # extra steps, run tests
+ postBuildSteps:
+ - template: /eng/pipelines/libraries/helix.yml
+ parameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig)
+ extraHelixArguments: /p:BrowserHost=$(_hostedOs) $(_wasmRunSmokeTestsOnlyArg) ${{ parameters.extraHelixArguments }}
+ scenarios: ${{ parameters.scenarios }}
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 0fa511074568c8..22a8978bd6115d 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -106,7 +106,7 @@ extends:
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
- buildConfig: Debug
+ buildConfig: Release
platforms:
- browser_wasm
- browser_wasm_win
@@ -862,6 +862,18 @@ extends:
scenarios:
- WasmTestOnChrome
+ # WebAssembly CoreCLR
+ - template: /eng/pipelines/common/templates/wasm-coreclr-library-tests.yml
+ parameters:
+ platforms:
+ - browser_wasm
+ alwaysRun: ${{ variables.isRollingBuild }}
+ shouldRunSmokeOnly: true
+ # TODO consider shouldContinueOnError: true
+ extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS)
+ scenarios:
+ - WasmTestOnChrome
+
# EAT Library tests - only run on linux
- template: /eng/pipelines/common/templates/wasm-library-aot-tests.yml
parameters:
diff --git a/eng/testing/tests.browser.targets b/eng/testing/tests.browser.targets
index 4649cbd386d297..8fd7c65c59d926 100644
--- a/eng/testing/tests.browser.targets
+++ b/eng/testing/tests.browser.targets
@@ -12,7 +12,6 @@
true
false
true
- true
<_WasmInTreeDefaults>false
@@ -53,6 +52,18 @@
true
true
+
+ true
+ true
+ true
+ true
+
+
+
+
+ false
+ false
+
diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp
index d04b313f8ca6ac..1299deaf3f44dd 100644
--- a/src/coreclr/interpreter/compiler.cpp
+++ b/src/coreclr/interpreter/compiler.cpp
@@ -4094,6 +4094,8 @@ void InterpCompiler::EmitCanAccessCallout(CORINFO_RESOLVED_TOKEN *pResolvedToken
void InterpCompiler::EmitCallsiteCallout(CorInfoIsAccessAllowedResult accessAllowed, CORINFO_HELPER_DESC* calloutDesc)
{
+// WASM-TODO: https://github.com/dotnet/runtime/issues/121955
+#ifndef TARGET_WASM
if (accessAllowed == CORINFO_ACCESS_ILLEGAL)
{
int32_t svars[CORINFO_ACCESS_ALLOWED_MAX_ARGS];
@@ -4164,6 +4166,7 @@ void InterpCompiler::EmitCallsiteCallout(CorInfoIsAccessAllowedResult accessAllo
}
m_pLastNewIns->data[0] = GetDataForHelperFtn(calloutDesc->helperNum);
}
+#endif // !TARGET_WASM
}
static OpcodePeepElement peepRuntimeAsyncCall[] = {
diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h
index bde859d72dca8d..d243c3a46b54b0 100644
--- a/src/coreclr/vm/corelib.h
+++ b/src/coreclr/vm/corelib.h
@@ -993,6 +993,9 @@ DEFINE_CLASS(THREAD, Threading, Thread)
DEFINE_METHOD(THREAD, START_CALLBACK, StartCallback, IM_RetVoid)
DEFINE_METHOD(THREAD, POLLGC, PollGC, NoSig)
DEFINE_METHOD(THREAD, ON_THREAD_EXITING, OnThreadExiting, IM_RetVoid)
+#ifdef FOR_ILLINK
+DEFINE_METHOD(THREAD, CTOR, .ctor, IM_RetVoid)
+#endif // FOR_ILLINK
#ifdef FEATURE_OBJCMARSHAL
DEFINE_CLASS(AUTORELEASEPOOL, Threading, AutoreleasePool)
diff --git a/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp b/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp
index 91cd17b5a2de1a..2448766c1148d6 100644
--- a/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp
+++ b/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp
@@ -55,6 +55,18 @@ namespace
*((double*)pRet) = (*fptr)(ARG_I32(0));
}
+ static void CallFunc_I32_I32_RetF64(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ double (*fptr)(int32_t, int32_t) = (double (*)(int32_t, int32_t))pcode;
+ *((double*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1));
+ }
+
+ static void CallFunc_Void_RetF32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ float (*fptr)() = (float (*)())pcode;
+ *((float*)pRet) = (*fptr)();
+ }
+
static void CallFunc_F32_RetF32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
float (*fptr)(float) = (float (*)(float))pcode;
@@ -85,12 +97,24 @@ namespace
*((int32_t*)pRet) = (*fptr)();
}
+ static void CallFunc_F64_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int32_t (*fptr)(double) = (int32_t (*)(double))pcode;
+ *((int32_t*)pRet) = (*fptr)(ARG_F64(0));
+ }
+
static void CallFunc_F64_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
int32_t (*fptr)(double, int32_t) = (int32_t (*)(double, int32_t))pcode;
*((int32_t*)pRet) = (*fptr)(ARG_F64(0), ARG_I32(1));
}
+ static void CallFunc_F32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int32_t (*fptr)(float) = (int32_t (*)(float))pcode;
+ *((int32_t*)pRet) = (*fptr)(ARG_F32(0));
+ }
+
static void CallFunc_F32_F32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
int32_t (*fptr)(float, float) = (int32_t (*)(float, float))pcode;
@@ -259,6 +283,12 @@ namespace
*((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_IND(1), ARG_IND(2));
}
+ static void CallFunc_I64_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int32_t (*fptr)(int64_t) = (int32_t (*)(int64_t))pcode;
+ *((int32_t*)pRet) = (*fptr)(ARG_I64(0));
+ }
+
static void CallFunc_I64_I32_I64_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
int32_t (*fptr)(int64_t, int32_t, int64_t, int32_t) = (int32_t (*)(int64_t, int32_t, int64_t, int32_t))pcode;
@@ -373,12 +403,31 @@ namespace
*((int64_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I64(1), ARG_I64(2));
}
+ static void CallFunc_I64_RetI64(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int64_t (*fptr)(int64_t) = (int64_t (*)(int64_t))pcode;
+ *((int64_t*)pRet) = (*fptr)(ARG_I64(0));
+ }
+
+ static void CallFunc_I64_I32_RetI64(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int64_t (*fptr)(int64_t, int32_t) = (int64_t (*)(int64_t, int32_t))pcode;
+ *((int64_t*)pRet) = (*fptr)(ARG_I64(0), ARG_I32(1));
+ }
+
static void CallFunc_I64_I64_RetI64(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
int64_t (*fptr)(int64_t, int64_t) = (int64_t (*)(int64_t, int64_t))pcode;
*((int64_t*)pRet) = (*fptr)(ARG_I64(0), ARG_I64(1));
}
+ static void CallFunc_Void_RetIND(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int32_t (*fptr)() = (int32_t (*)())pcode;
+ PORTABILITY_ASSERT("Indirect struct return is not yet implemented.");
+ *((int32_t*)pRet) = (*fptr)();
+ }
+
static void CallFunc_I32_RetIND(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
int32_t (*fptr)(int32_t) = (int32_t (*)(int32_t))pcode;
@@ -393,18 +442,44 @@ namespace
*((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1));
}
+ static void CallFunc_IND_RetIND(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int32_t (*fptr)(int32_t) = (int32_t (*)(int32_t))pcode;
+ PORTABILITY_ASSERT("Indirect struct return is not yet implemented.");
+ *((int32_t*)pRet) = (*fptr)(ARG_IND(0));
+ }
+
+ static void CallFunc_IND_I32_RetIND(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ int32_t (*fptr)(int32_t, int32_t) = (int32_t (*)(int32_t, int32_t))pcode;
+ PORTABILITY_ASSERT("Indirect struct return is not yet implemented.");
+ *((int32_t*)pRet) = (*fptr)(ARG_IND(0), ARG_I32(1));
+ }
+
static void CallFunc_Void_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
void (*fptr)() = (void (*)())pcode;
(*fptr)();
}
+ static void CallFunc_F64_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ void (*fptr)(double) = (void (*)(double))pcode;
+ (*fptr)(ARG_F64(0));
+ }
+
static void CallFunc_F64_I32_I32_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
void (*fptr)(double, int32_t, int32_t) = (void (*)(double, int32_t, int32_t))pcode;
(*fptr)(ARG_F64(0), ARG_I32(1), ARG_I32(2));
}
+ static void CallFunc_F32_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ void (*fptr)(float) = (void (*)(float))pcode;
+ (*fptr)(ARG_F32(0));
+ }
+
static void CallFunc_F32_I32_I32_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
void (*fptr)(float, int32_t, int32_t) = (void (*)(float, int32_t, int32_t))pcode;
@@ -447,6 +522,12 @@ namespace
(*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), ARG_I32(5));
}
+ static void CallFunc_I32_I32_I32_I32_I32_I32_I32_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet)
+ {
+ void (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t) = (void (*)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t))pcode;
+ (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_I32(3), ARG_I32(4), ARG_I32(5), ARG_I32(6));
+ }
+
static void CallFunc_I32_I32_I32_IND_IND_RetVoid(PCODE pcode, int8_t* pArgs, int8_t* pRet)
{
void (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t) = (void (*)(int32_t, int32_t, int32_t, int32_t, int32_t))pcode;
@@ -569,12 +650,16 @@ const StringToWasmSigThunk g_wasmThunks[] = {
{ "dddd", (void*)&CallFunc_F64_F64_F64_RetF64 },
{ "ddi", (void*)&CallFunc_F64_I32_RetF64 },
{ "di", (void*)&CallFunc_I32_RetF64 },
+ { "dii", (void*)&CallFunc_I32_I32_RetF64 },
+ { "f", (void*)&CallFunc_Void_RetF32 },
{ "ff", (void*)&CallFunc_F32_RetF32 },
{ "fff", (void*)&CallFunc_F32_F32_RetF32 },
{ "ffff", (void*)&CallFunc_F32_F32_F32_RetF32 },
{ "ffi", (void*)&CallFunc_F32_I32_RetF32 },
{ "i", (void*)&CallFunc_Void_RetI32 },
+ { "id", (void*)&CallFunc_F64_RetI32 },
{ "idi", (void*)&CallFunc_F64_I32_RetI32 },
+ { "if", (void*)&CallFunc_F32_RetI32 },
{ "iff", (void*)&CallFunc_F32_F32_RetI32 },
{ "ii", (void*)&CallFunc_I32_RetI32 },
{ "iid", (void*)&CallFunc_I32_F64_RetI32 },
@@ -603,6 +688,7 @@ const StringToWasmSigThunk g_wasmThunks[] = {
{ "iiniii", (void*)&CallFunc_I32_IND_I32_I32_I32_RetI32 },
{ "iinini", (void*)&CallFunc_I32_IND_I32_IND_I32_RetI32 },
{ "iinn", (void*)&CallFunc_I32_IND_IND_RetI32 },
+ { "il", (void*)&CallFunc_I64_RetI32 },
{ "ilili", (void*)&CallFunc_I64_I32_I64_I32_RetI32 },
{ "in", (void*)&CallFunc_IND_RetI32 },
{ "ini", (void*)&CallFunc_IND_I32_RetI32 },
@@ -622,11 +708,18 @@ const StringToWasmSigThunk g_wasmThunks[] = {
{ "lil", (void*)&CallFunc_I32_I64_RetI64 },
{ "lili", (void*)&CallFunc_I32_I64_I32_RetI64 },
{ "lill", (void*)&CallFunc_I32_I64_I64_RetI64 },
+ { "ll", (void*)&CallFunc_I64_RetI64 },
+ { "lli", (void*)&CallFunc_I64_I32_RetI64 },
{ "lll", (void*)&CallFunc_I64_I64_RetI64 },
+ { "n", (void*)&CallFunc_Void_RetIND },
{ "ni", (void*)&CallFunc_I32_RetIND },
{ "nii", (void*)&CallFunc_I32_I32_RetIND },
+ { "nn", (void*)&CallFunc_IND_RetIND },
+ { "nni", (void*)&CallFunc_IND_I32_RetIND },
{ "v", (void*)&CallFunc_Void_RetVoid },
+ { "vd", (void*)&CallFunc_F64_RetVoid },
{ "vdii", (void*)&CallFunc_F64_I32_I32_RetVoid },
+ { "vf", (void*)&CallFunc_F32_RetVoid },
{ "vfii", (void*)&CallFunc_F32_I32_I32_RetVoid },
{ "vi", (void*)&CallFunc_I32_RetVoid },
{ "vii", (void*)&CallFunc_I32_I32_RetVoid },
@@ -634,6 +727,7 @@ const StringToWasmSigThunk g_wasmThunks[] = {
{ "viiii", (void*)&CallFunc_I32_I32_I32_I32_RetVoid },
{ "viiiii", (void*)&CallFunc_I32_I32_I32_I32_I32_RetVoid },
{ "viiiiii", (void*)&CallFunc_I32_I32_I32_I32_I32_I32_RetVoid },
+ { "viiiiiii", (void*)&CallFunc_I32_I32_I32_I32_I32_I32_I32_RetVoid },
{ "viiinn", (void*)&CallFunc_I32_I32_I32_IND_IND_RetVoid },
{ "viiinni", (void*)&CallFunc_I32_I32_I32_IND_IND_I32_RetVoid },
{ "viin", (void*)&CallFunc_I32_I32_IND_RetVoid },
diff --git a/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs
index 8c393b95f69c21..005c736e936594 100644
--- a/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs
+++ b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs
@@ -3,11 +3,13 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.DotNet.XHarness.TestRunners.Common;
using Microsoft.DotNet.XHarness.TestRunners.Xunit;
-using System.Runtime.CompilerServices;
public class WasmTestRunner : WasmApplicationEntryPoint
{
@@ -31,6 +33,14 @@ public static Task Main(string[] args)
}
#endif
+ // WASM-TODO: workaround for https://github.com/dotnet/runtime/issues/122972
+ protected override IEnumerable GetTestAssemblies()
+ {
+ AssemblyName an = new AssemblyName(Path.GetFileNameWithoutExtension(TestAssembly));
+ Assembly assembly = Assembly.Load(an);
+ return new[] { new TestAssemblyInfo(assembly, TestAssembly) };
+ }
+
public static async Task MainAsync(string[] args)
{
if (args.Length == 0)
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs
index 716b4df993a6d3..6f5cf2f0be7dfb 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs
@@ -2702,6 +2702,7 @@ public void ToType_DateTime_ReturnsExpected()
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/123011", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsCoreCLR))]
public void GetObjectData_Invoke_ReturnsExpected()
{
ISerializable serializable = new DateTime(10, DateTimeKind.Utc);
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DecimalTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DecimalTests.cs
index cf62bd32354494..6363e20f02e313 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DecimalTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DecimalTests.cs
@@ -135,6 +135,7 @@ public static IEnumerable
+ Condition="'$(TargetOS)' == 'browser' and '$(ContinuousIntegrationBuild)' == 'true'" />
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index f9f658030da96f..26bb2b4da641f0 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -534,7 +534,7 @@
-
+
diff --git a/src/mono/browser/build/WasmApp.InTree.props b/src/mono/browser/build/WasmApp.InTree.props
index 33a54b83c15236..b83e9994dc24f8 100644
--- a/src/mono/browser/build/WasmApp.InTree.props
+++ b/src/mono/browser/build/WasmApp.InTree.props
@@ -18,8 +18,6 @@
false
false
- false
- false
diff --git a/src/mono/browser/test-main.js b/src/mono/browser/test-main.js
index 8d608317c63762..61c5282e7271b4 100644
--- a/src/mono/browser/test-main.js
+++ b/src/mono/browser/test-main.js
@@ -357,8 +357,9 @@ async function run() {
try {
const main_assembly_name = runArgs.applicationArguments[1];
const app_args = runArgs.applicationArguments.slice(2);
+ const now = Date.now();
const result = await App.runtime.runMain(main_assembly_name, app_args);
- console.log(`test-main.js exiting ${app_args.length > 1 ? main_assembly_name + " " + app_args[0] : main_assembly_name} with result ${result} and linear memory ${App.runtime.Module.HEAPU8.length} bytes`);
+ console.log(`test-main.js exiting ${app_args.length > 1 ? main_assembly_name + " " + app_args[0] : main_assembly_name} after ${(Date.now() - now) / 60000} minutes with result ${result} and linear memory ${App.runtime.Module.HEAPU8.length} bytes`);
mono_exit(result);
} catch (error) {
if (error.name != "ExitStatus") {
diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmBrowserRunMainOnly.cs b/src/mono/wasm/Wasm.Build.Tests/WasmBrowserRunMainOnly.cs
index bc4799a9bf3bb3..5f49a85154d9d6 100644
--- a/src/mono/wasm/Wasm.Build.Tests/WasmBrowserRunMainOnly.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/WasmBrowserRunMainOnly.cs
@@ -7,12 +7,13 @@ namespace Wasm.Build.Tests;
public class WasmBrowserRunMainOnly(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : WasmTemplateTestsBase(output, buildContext)
{
- [Fact, TestCategory("coreclr")]
- public async Task RunMainOnly()
+ [TestCategory("coreclr")]
+ [Theory]
+ [BuildAndRun(config: Configuration.Release)]
+ [BuildAndRun(config: Configuration.Debug)]
+ public async Task RunMainOnly(Configuration config, bool aot)
{
- Configuration config = Configuration.Debug;
-
- ProjectInfo info = CopyTestAsset(config, false, TestAsset.WasmBrowserRunMainOnly, $"WasmBrowserRunMainOnly");
+ ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBrowserRunMainOnly, $"WasmBrowserRunMainOnly");
var (_, buildOutput) = PublishProject(info, config, new PublishOptions(AssertAppBundle: false, EnableDiagnostics: true));
// ** MicrosoftNetCoreAppRuntimePackDir : '....microsoft.netcore.app.runtime.browser-wasm\11.0.0-dev'
diff --git a/src/native/corehost/browserhost/CMakeLists.txt b/src/native/corehost/browserhost/CMakeLists.txt
index 2640458e50d1ed..bbf88764ae9e12 100644
--- a/src/native/corehost/browserhost/CMakeLists.txt
+++ b/src/native/corehost/browserhost/CMakeLists.txt
@@ -102,8 +102,10 @@ if (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)
)
endif ()
+# add -sVERBOSE=1 to debug linking issues
# WASM-TODO -emit-llvm
# WASM-TODO --source-map-base http://microsoft.com
+# WASM-TODO -sSEPARATE_DWARF=1, -gseparate-dwarf
target_link_options(browserhost PRIVATE
-sINITIAL_MEMORY=134217728
-sMAXIMUM_MEMORY=2147483648
@@ -120,10 +122,8 @@ target_link_options(browserhost PRIVATE
-lnodefs.js
-Wl,-error-limit=0)
-target_link_libraries(browserhost PUBLIC
- BrowserHost-Static
-)
target_link_libraries(browserhost PRIVATE
+ BrowserHost-Static
${NATIVE_LIBS}
${START_WHOLE_ARCHIVE}
${RUNTIMEINFO_LIB}
diff --git a/src/native/corehost/browserhost/host/host.ts b/src/native/corehost/browserhost/host/host.ts
index 03ffe7a91eef76..d55d8c3c1ade6d 100644
--- a/src/native/corehost/browserhost/host/host.ts
+++ b/src/native/corehost/browserhost/host/host.ts
@@ -75,7 +75,7 @@ export function installVfsFile(bytes: Uint8Array, asset: VfsAsset) {
_ems_.dotnetLogger.debug(`Creating directory '${parentDirectory}'`);
- _ems_.Module.FS_createPath(
+ _ems_.FS.createPath(
"/", parentDirectory, true, true // fixme: should canWrite be false?
);
} else {
@@ -84,7 +84,7 @@ export function installVfsFile(bytes: Uint8Array, asset: VfsAsset) {
_ems_.dotnetLogger.debug(`Creating file '${fileName}' in directory '${parentDirectory}'`);
- _ems_.Module.FS_createDataFile(
+ _ems_.FS.createDataFile(
parentDirectory, fileName,
bytes, true /* canRead */, true /* canWrite */, true /* canOwn */
);
diff --git a/src/native/corehost/browserhost/libBrowserHost.footer.js b/src/native/corehost/browserhost/libBrowserHost.footer.js
index b37e57dcea93da..49504a4252d243 100644
--- a/src/native/corehost/browserhost/libBrowserHost.footer.js
+++ b/src/native/corehost/browserhost/libBrowserHost.footer.js
@@ -19,7 +19,11 @@
const exports = {};
libBrowserHost(exports);
- let commonDeps = ["$libBrowserHostFn", "$DOTNET", "$DOTNET_INTEROP", "$ENV", "$FS", "$NODEFS", "wasm_load_icu_data", "BrowserHost_InitializeCoreCLR", "BrowserHost_ExecuteAssembly"];
+ let commonDeps = [
+ "$DOTNET", "$DOTNET_INTEROP", "$ENV", "$FS", "$NODEFS",
+ "$libBrowserHostFn",
+ "wasm_load_icu_data", "BrowserHost_InitializeCoreCLR", "BrowserHost_ExecuteAssembly"
+ ];
const lib = {
$BROWSER_HOST: {
selfInitialize: () => {
@@ -64,6 +68,11 @@
}
}
},
+ // libBrowserHostFn is too complex for acorn-optimizer.mjs to find the dependencies
+ AJSDCE_Deps: function () {
+ _BrowserHost_InitializeCoreCLR();
+ _BrowserHost_ExecuteAssembly();
+ },
},
$libBrowserHostFn: libBrowserHost,
$BROWSER_HOST__postset: "BROWSER_HOST.selfInitialize()",
diff --git a/src/native/corehost/browserhost/loader/dotnet.d.ts b/src/native/corehost/browserhost/loader/dotnet.d.ts
index 265014a8f61f04..a4b0273eea0266 100644
--- a/src/native/corehost/browserhost/loader/dotnet.d.ts
+++ b/src/native/corehost/browserhost/loader/dotnet.d.ts
@@ -36,9 +36,6 @@ interface EmscriptenModule {
UTF8ArrayToString(u8Array: Uint8Array, idx?: number, maxBytesToRead?: number): string;
stringToUTF8Array(str: string, heap: Uint8Array, outIdx: number, maxBytesToWrite: number): void;
lengthBytesUTF8(str: string): number;
- FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string;
- FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string;
- addFunction(fn: Function, signature: string): number;
stackSave(): VoidPtr;
stackRestore(stack: VoidPtr): void;
stackAlloc(size: number): VoidPtr;
diff --git a/src/native/libs/Common/JavaScript/ems-ambient/index.ts b/src/native/libs/Common/JavaScript/ems-ambient/index.ts
index 66dc3d452c610c..46a71f13a8f17f 100644
--- a/src/native/libs/Common/JavaScript/ems-ambient/index.ts
+++ b/src/native/libs/Common/JavaScript/ems-ambient/index.ts
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-import type { AssertType, EmscriptenModuleInternal, LoggerType, LoaderExports, InternalExchange, InternalExchangeSubscriber, RuntimeAPI, BrowserUtilsExports, VoidPtr, RuntimeExports } from "../types";
+import type { AssertType, EmscriptenModuleInternal, LoggerType, LoaderExports, InternalExchange, InternalExchangeSubscriber, RuntimeAPI, BrowserUtilsExports, VoidPtr, RuntimeExports, TypedArray } from "../types";
// we want to use the cross-module symbols defined in closure of dotnet.native.js
// which are installed there by libSystem.Native.Browser.Utils.footer.js
@@ -24,6 +24,10 @@ type emAmbientSymbolsType = {
_BrowserHost_InitializeCoreCLR: () => number;
_BrowserHost_ExecuteAssembly: (mainAssemblyNamePtr: number, argsLength: number, argsPtr: number) => number;
_wasm_load_icu_data: (dataPtr: VoidPtr) => number;
+ FS: {
+ createPath: (parent: string, path: string, canRead?: boolean, canWrite?: boolean) => string;
+ createDataFile: (parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean) => string;
+ }
DOTNET: any;
DOTNET_INTEROP: any;
@@ -42,7 +46,6 @@ type emAmbientSymbolsType = {
_emscripten_force_exit: (exitCode: number) => void;
_exit: (exitCode: number, implicit?: boolean) => void;
safeSetTimeout: (func: Function, timeout: number) => number;
- maybeExit: () => void;
exitJS: (status: number, implicit?: boolean | number) => void;
runtimeKeepalivePop: () => void;
runtimeKeepalivePush: () => void;
diff --git a/src/native/libs/Common/JavaScript/types/emscripten.ts b/src/native/libs/Common/JavaScript/types/emscripten.ts
index 9ef24f09274cb2..3a2b4fa5a63988 100644
--- a/src/native/libs/Common/JavaScript/types/emscripten.ts
+++ b/src/native/libs/Common/JavaScript/types/emscripten.ts
@@ -45,9 +45,6 @@ export interface EmscriptenModule {
UTF8ArrayToString(u8Array: Uint8Array, idx?: number, maxBytesToRead?: number): string;
stringToUTF8Array(str: string, heap: Uint8Array, outIdx: number, maxBytesToWrite: number): void;
lengthBytesUTF8(str: string): number;
- FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string;
- FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string;
- addFunction(fn: Function, signature: string): number;
stackSave(): VoidPtr;
stackRestore(stack: VoidPtr): void;
stackAlloc(size: number): VoidPtr;
diff --git a/src/native/rollup.config.defines.js b/src/native/rollup.config.defines.js
index b4bc4f859b4348..af36b8eb99be63 100644
--- a/src/native/rollup.config.defines.js
+++ b/src/native/rollup.config.defines.js
@@ -36,7 +36,7 @@ export const reserved = [
export const externalDependencies = ["module", "process", "perf_hooks", "node:crypto"];
export const artifactsObjDir = "../../artifacts/obj";
-export const isDebug = process.env.Configuration !== "Release" && !isContinuousIntegrationBuild;
+export const isDebug = process.env.Configuration !== "Release";
export let gitHash;
try {
diff --git a/src/tasks/WasmAppBuilder/coreclr/ManagedToNativeGenerator.cs b/src/tasks/WasmAppBuilder/coreclr/ManagedToNativeGenerator.cs
index eee06a7eaeecce..cf6ab46a7d4675 100644
--- a/src/tasks/WasmAppBuilder/coreclr/ManagedToNativeGenerator.cs
+++ b/src/tasks/WasmAppBuilder/coreclr/ManagedToNativeGenerator.cs
@@ -72,17 +72,31 @@ public override bool Execute()
private static readonly string[] missingCookies =
[
"d",
+ "dii",
+ "f",
+ "id",
"idi",
+ "if",
"iff",
"iid",
"iif",
"iifiif",
"iiiiiiiiiiiiiiiiii",
"iin",
+ "iinini",
"iinn",
+ "il",
"lii",
+ "ll",
+ "lli",
+ "n",
"ni",
"nii",
+ "nn",
+ "nni",
+ "vd",
+ "vf",
+ "viiiiiii",
"viin",
"vin",
"vinni",