Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8debc4a
Enable non-AOT WBT tests on CoreCLR in 4 native test classes
maraf Apr 22, 2026
65e6237
Enable ICU, InvariantGlobalization, and Memory tests on CoreCLR
Copilot Apr 24, 2026
1fa4950
Add newly enabled WBT classes to CoreCLR Helix jobs list
maraf Apr 24, 2026
123b863
Fix WBT template install on read-only Helix correlation
maraf Apr 24, 2026
5250927
Fix WBT template install DOTNET_CLI_HOME mismatch on Helix
maraf Apr 27, 2026
14cace4
Fix WBT CoreCLR native relink, ICU pack lookup, variadic test scope
maraf Apr 27, 2026
e17204d
Ship coreclr_compat.h as a static file next to BrowserWasmApp.CoreCLR…
maraf Apr 27, 2026
1eb48af
Use ICU-specific main.js for Wasm.Build.Tests IcuTests
maraf Apr 29, 2026
418cd2b
Split emcc compile pass for user vs generated sources in CoreCLR-Wasm
maraf Apr 29, 2026
827800e
Merge remote-tracking branch 'origin/main' into maraf/wbt-coreclr-ena…
maraf Apr 29, 2026
532e645
Ship minipal/utils.h to WBT Helix payload for CoreCLR re-link
May 5, 2026
7509361
Resolve ICU asset src path from build-resolved runtime pack
May 5, 2026
a7b3362
Ship libSystem.Native.Browser.extpost.js in browser-wasm runtime pack
May 5, 2026
905c755
Install libSystem.Native.Browser.extpost.js into sharedFramework
maraf May 6, 2026
9d4e5ce
Include static libs in browser-wasm CoreCLR runtime pack
maraf May 6, 2026
34f2aa2
Auto-enable WasmBuildNative for CoreCLR when NativeFileReference/Nati…
maraf May 6, 2026
c0b0e63
Exclude duplicate libs from browser-wasm CoreCLR runtime pack
maraf May 7, 2026
51b99d0
Treat CoreCLR as always workload
maraf May 8, 2026
0388696
Use icu_main.js for Wasm.Build.Tests DllImport variadic-function tests
maraf May 8, 2026
45afe55
Use minimal main.js for more Wasm.Build.Tests CoreCLR scenarios
maraf May 8, 2026
bef4e8b
Mark IcallWithOverloadedParametersAndEnum as mono-only
maraf May 8, 2026
37cdc06
Revert "Treat CoreCLR as always workload"
maraf May 9, 2026
8910706
Fix WBT NoWorkload+CoreCLR native file location assertion
maraf May 11, 2026
0eb727a
Don't force wasm_load_icu_data as link-time dep on browserhost
maraf May 11, 2026
e51a126
Wire CoreCLR nested publish into ProcessPublishFilesForWasm
maraf May 11, 2026
a12e506
Read pinvoke-table.cpp on CoreCLR in EnsureWasmAbiRulesAreFollowed
maraf May 12, 2026
8a3a3b0
Override _WasmNativeForBuild in CoreCLR targets
maraf May 13, 2026
b730bfc
Run _GatherWasmFilesToBuild before M2N generator
maraf May 13, 2026
f6e4327
Include user-compiled source files in _WasmPInvokeModules
maraf May 13, 2026
392a9ee
Map non-blittable value types to IND in CoreCLR signature naming
maraf May 13, 2026
2ec813f
Stage CoreCLR wasm relinked native asset before static web assets
maraf May 13, 2026
70bf73d
[wasm][coreclr] Fix UCO export wrapper return type in PInvokeTableGen…
maraf May 13, 2026
b4a93e8
[wasm][wbt] Disable user-UCO PInvokeTableGenerator tests on CoreCLR
maraf May 13, 2026
5cc2e7b
Merge remote-tracking branch 'origin/main' into maraf/wbt-coreclr-ena…
maraf May 14, 2026
3c86968
Move WASM CoreCLR runtime pack Exclude= to ItemGroup with the .a glob
maraf May 14, 2026
f724f75
Revert SignatureHelper.cs
maraf May 14, 2026
683b4cd
Revert UCO return type
maraf May 14, 2026
51b37e5
[wasm][WBT] Gate InvariantGlobalizationTests to Mono only
maraf May 14, 2026
4140758
Merge branch 'main' into maraf/wbt-coreclr-enable-non-aot-tests
maraf May 15, 2026
5b3f18f
Add test structure sizes, regenerate
radekdoulik May 15, 2026
b2d2001
Disable EnsureWasmAbiRulesAreFollowedInInterpreter on coreclr
radekdoulik May 15, 2026
f3f030c
Put the structures into WasmAppBuilderTests namespace
radekdoulik May 15, 2026
8092e25
Restore includes in wasm callhelpers generated files
maraf May 15, 2026
01ed2f0
Mark CallIntoLibrariesWithNonAlphanumericCharactersInTheirNames as na…
maraf May 16, 2026
669125e
Ship real callhelpers.hpp/entrypoints.h to Helix, slim coreclr_compat.h
maraf May 16, 2026
4f1b82a
Merge branch 'main' into maraf/wbt-coreclr-enable-non-aot-tests
maraf May 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions eng/testing/scenarios/BuildWasmAppsJobsListCoreCLR.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,13 @@ Wasm.Build.Tests.WasmRunOutOfAppBundleTests
Wasm.Build.Tests.WasmTemplateTests
Wasm.Build.Tests.MaxParallelDownloadsTests
Wasm.Build.Tests.LibraryInitializerTests
Wasm.Build.Tests.NativeBuildTests
Wasm.Build.Tests.DllImportTests
Wasm.Build.Tests.PInvokeTableGeneratorTests
Wasm.Build.Tests.NativeLibraryTests
Wasm.Build.Tests.IcuShardingTests
Wasm.Build.Tests.IcuShardingTests2
Wasm.Build.Tests.IcuTests
Wasm.Build.Tests.InvariantGlobalizationTests
Wasm.Build.Tests.MemoryTests
Comment on lines +19 to +23

Copilot AI Apr 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says additional TestCategory("native") classes like IcuTests are "not in scope" and left for follow-up, but this change adds Icu*, InvariantGlobalizationTests, and MemoryTests to the CoreCLR job list. Either update the PR description to reflect the expanded scope or remove these additions to match the stated intent.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
Wasm.Build.Tests.DownloadThenInitTests
98 changes: 46 additions & 52 deletions src/mono/browser/build/BrowserWasmApp.CoreCLR.targets
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
<_WasmIntermediateOutputPath Condition="'$(WasmBuildingForNestedPublish)' == 'true'">$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'wasm', 'for-publish'))</_WasmIntermediateOutputPath>

<_WasmCompileRsp>$(_WasmIntermediateOutputPath)emcc-compile.rsp</_WasmCompileRsp>
<_WasmCompileRspGenerated>$(_WasmIntermediateOutputPath)emcc-compile-generated.rsp</_WasmCompileRspGenerated>
<_WasmLinkRsp>$(_WasmIntermediateOutputPath)emcc-link.rsp</_WasmLinkRsp>
</PropertyGroup>

Expand Down Expand Up @@ -270,20 +271,28 @@
<_EmccCFlags Include="@(_EmccCommonFlags)" />
<_EmccCFlags Include="-DGEN_PINVOKE=1" />
<_EmccCFlags Include="$(EmccExtraCFlags)" />
</ItemGroup>

<!-- Include paths for ManagedToNativeGenerator output compilation -->
<_EmccCFlags Include="-I&quot;$(RepoRoot)src/coreclr/vm/wasm&quot;" Condition="Exists('$(RepoRoot)src/coreclr/vm/wasm/callhelpers.hpp')" />
<_EmccCFlags Include="-I&quot;$(RepoRoot)src/native&quot;" Condition="Exists('$(RepoRoot)src/native/minipal/entrypoints.h')" />
<_EmccCFlags Include="-include &quot;$(_WasmIntermediateOutputPath)coreclr_compat.h&quot;" />
<!-- Compile flags for ManagedToNativeGenerator output (pinvoke-table.cpp,
wasm_m2n_invoke.g.cpp). All declarations these files need are provided
by coreclr_compat.h (which ships next to this targets file), force-included
here. We keep this off the user-source flags (_EmccCFlags) so user .c/.cpp
in NativeFileReference don't pick up the C++-style struct decls (which
would fail to compile in C without a 'struct' tag).
Avoiding reliance on the in-repo coreclr/vm/wasm and native/minipal headers
is intentional, since those aren't present in the WBT Helix payload. -->
<ItemGroup>
<_EmccCFlagsGenerated Include="@(_EmccCFlags)" />
<_EmccCFlagsGenerated Include="-include &quot;$(MSBuildThisFileDirectory)coreclr_compat.h&quot;" />
</ItemGroup>

<!-- Source files: user NativeFileReference sources -->
<ItemGroup>
<_WasmSourceFileToCompile Remove="@(_WasmSourceFileToCompile)" />
<_WasmSourceFileToCompile Include="@(NativeFileReference)" Condition="'%(Extension)' == '.c' or '%(Extension)' == '.cpp'" />
<_WasmSourceFileToCompile ObjectFile="$(_WasmIntermediateOutputPath)%(FileName).o" />
<!-- Add compile RSP and compat header as dependencies for incremental build -->
<_WasmSourceFileToCompile Dependencies="$(_WasmCompileRsp);$(_WasmIntermediateOutputPath)coreclr_compat.h" />
<!-- Add compile RSP as dependency for incremental build -->
<_WasmSourceFileToCompile Dependencies="$(_WasmCompileRsp)" />
</ItemGroup>

<!-- Native .a files to link: any NativeFileReference that are archives -->
Expand Down Expand Up @@ -352,69 +361,40 @@
cause duplicate symbol errors when the archive object is pulled in for
other required symbols (e.g., SystemInteropJS_*). -->
<ItemGroup>
<_WasmSourceFileToCompile Include="$(_WasmPInvokeTablePath)" ObjectFile="$(_WasmIntermediateOutputPath)pinvoke-table.o"
Dependencies="$(_WasmCompileRsp);$(_WasmIntermediateOutputPath)coreclr_compat.h" />
<_WasmSourceFileToCompile Include="$(_WasmInterpToNativeTablePath)" ObjectFile="$(_WasmIntermediateOutputPath)wasm_m2n_invoke.o"
Dependencies="$(_WasmCompileRsp);$(_WasmIntermediateOutputPath)coreclr_compat.h" />
<_WasmSourceFileToCompileGenerated Remove="@(_WasmSourceFileToCompileGenerated)" />
<_WasmSourceFileToCompileGenerated Include="$(_WasmPInvokeTablePath)" ObjectFile="$(_WasmIntermediateOutputPath)pinvoke-table.o"
Dependencies="$(_WasmCompileRspGenerated);$(MSBuildThisFileDirectory)coreclr_compat.h" />
<_WasmSourceFileToCompileGenerated Include="$(_WasmInterpToNativeTablePath)" ObjectFile="$(_WasmIntermediateOutputPath)wasm_m2n_invoke.o"
Dependencies="$(_WasmCompileRspGenerated);$(MSBuildThisFileDirectory)coreclr_compat.h" />
</ItemGroup>
</Target>

<!-- ======================== Write Compile RSP ======================== -->

<Target Name="_CoreCLRWriteCompileRsp" Condition="@(_WasmSourceFileToCompile->Count()) > 0">
<!-- Generate a compatibility header with type/macro stubs for compiling
ManagedToNativeGenerator output outside the full CoreCLR build context -->
<PropertyGroup>
<_WasmCoreclrCompatHeader>$(_WasmIntermediateOutputPath)coreclr_compat.h</_WasmCoreclrCompatHeader>
</PropertyGroup>
<ItemGroup>
<_CompatHeaderLines Include="// Auto-generated CoreCLR compat header for app native build" />
<_CompatHeaderLines Include="#pragma once" />
<_CompatHeaderLines Include="#include &lt;stddef.h&gt;" />
<_CompatHeaderLines Include="#include &lt;stdint.h&gt;" />
<_CompatHeaderLines Include="#include &lt;stdlib.h&gt;" />
<_CompatHeaderLines Include="#include &lt;stdio.h&gt;" />
<_CompatHeaderLines Include="// CoreCLR type stubs" />
<_CompatHeaderLines Include="#ifndef _CORECLR_COMPAT_TYPES" />
<_CompatHeaderLines Include="#define _CORECLR_COMPAT_TYPES" />
<_CompatHeaderLines Include="typedef void MethodDesc%3B" />
<_CompatHeaderLines Include="typedef uintptr_t PCODE%3B" />
<_CompatHeaderLines Include="typedef uint32_t ULONG%3B" />
<_CompatHeaderLines Include="#define INTERP_STACK_SLOT_SIZE 8u" />
<_CompatHeaderLines Include="#endif" />
<_CompatHeaderLines Include="// CoreCLR logging stubs" />
<_CompatHeaderLines Include="#define LF_INTEROP 0" />
<_CompatHeaderLines Include="#define LL_INFO1000 0" />
<_CompatHeaderLines Include="#define LOG(x)" />
<_CompatHeaderLines Include="// CoreCLR assertion stubs" />
<_CompatHeaderLines Include="#define PORTABILITY_ASSERT(msg) do { fprintf(stderr, &quot;PORTABILITY_ASSERT: %25s&quot;, msg)%3B fprintf(stderr, &quot;\n&quot;)%3B abort()%3B } while(0)" />
</ItemGroup>

<WriteLinesToFile Lines="@(_CompatHeaderLines)" File="$(_WasmCoreclrCompatHeader)" Overwrite="true" WriteOnlyWhenDifferent="true" />
<ItemGroup>
<FileWrites Include="$(_WasmCoreclrCompatHeader)" />
</ItemGroup>

<Target Name="_CoreCLRWriteCompileRsp"
Condition="@(_WasmSourceFileToCompile->Count()) > 0 or @(_WasmSourceFileToCompileGenerated->Count()) > 0">
<ItemGroup>
<_WasmCFlags Include="@(_EmccCFlags)" />
<_WasmCFlagsGenerated Include="@(_EmccCFlagsGenerated)" />
</ItemGroup>
<WriteLinesToFile Lines="@(_WasmCFlags)" File="$(_WasmCompileRsp)" Overwrite="true" WriteOnlyWhenDifferent="true" />
<WriteLinesToFile Lines="@(_WasmCFlags)" File="$(_WasmCompileRsp)" Overwrite="true" WriteOnlyWhenDifferent="true" Condition="@(_WasmSourceFileToCompile->Count()) > 0" />
<WriteLinesToFile Lines="@(_WasmCFlagsGenerated)" File="$(_WasmCompileRspGenerated)" Overwrite="true" WriteOnlyWhenDifferent="true" Condition="@(_WasmSourceFileToCompileGenerated->Count()) > 0" />
<ItemGroup>
<FileWrites Include="$(_WasmCompileRsp)" />
<FileWrites Include="$(_WasmCompileRsp)" Condition="@(_WasmSourceFileToCompile->Count()) > 0" />
<FileWrites Include="$(_WasmCompileRspGenerated)" Condition="@(_WasmSourceFileToCompileGenerated->Count()) > 0" />
</ItemGroup>
</Target>

<!-- ======================== Compile Native Sources ======================== -->

<Target Name="_CoreCLRCompileNativeSources" Condition="@(_WasmSourceFileToCompile->Count()) > 0">
<ItemGroup>
<_WasmCompileArguments Remove="@(_WasmCompileArguments)" />
<_WasmCompileArguments Include="&quot;@$(_WasmCompileRsp)&quot;" Condition="'$(_WasmCompileRsp)' != ''" />
</ItemGroup>
<Target Name="_CoreCLRCompileNativeSources"
Condition="@(_WasmSourceFileToCompile->Count()) > 0 or @(_WasmSourceFileToCompileGenerated->Count()) > 0">

<!-- Compile user NativeFileReference sources (no force-included compat header). -->
<EmccCompile
Condition="@(_WasmSourceFileToCompile->Count()) > 0"
SourceFiles="@(_WasmSourceFileToCompile)"
Arguments="@(_WasmCompileArguments, ' ')"
Arguments="&quot;@$(_WasmCompileRsp)&quot;"
CompilerBinaryPath="$(WasmClang)"
EnvironmentVariables="@(EmscriptenEnvVars)"
DisableParallelCompile="$(DisableParallelEmccCompile)"
Expand All @@ -423,8 +403,22 @@
<Output TaskParameter="OutputFiles" ItemName="FileWrites" />
</EmccCompile>

<!-- Compile generated ManagedToNativeGenerator output (force-includes coreclr_compat.h). -->
<EmccCompile
Condition="@(_WasmSourceFileToCompileGenerated->Count()) > 0"
SourceFiles="@(_WasmSourceFileToCompileGenerated)"
Arguments="&quot;@$(_WasmCompileRspGenerated)&quot;"
CompilerBinaryPath="$(WasmClang)"
EnvironmentVariables="@(EmscriptenEnvVars)"
DisableParallelCompile="$(DisableParallelEmccCompile)"
MessageToIndicateCompiling="Compiling generated managed-to-native sources with emcc $(EmccCompileOptimizationFlag) ..."
OutputMessageImportance="$(_WasmCompileOutputMessageImportance)">
<Output TaskParameter="OutputFiles" ItemName="FileWrites" />
</EmccCompile>

<ItemGroup>
<_WasmNativeFileForLinking Include="%(_WasmSourceFileToCompile.ObjectFile)" />
<_WasmNativeFileForLinking Include="%(_WasmSourceFileToCompileGenerated.ObjectFile)" />
</ItemGroup>
</Target>

Expand Down
62 changes: 62 additions & 0 deletions src/mono/browser/build/coreclr_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Auto-included CoreCLR compat header for app native build.
//
// This header is pre-included via -include when compiling pinvoke-table.cpp
Comment on lines +1 to +3

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New header file is missing the standard .NET Foundation MIT license header comment used throughout the repo. Please add the usual "Licensed to the .NET Foundation under one or more agreements..." block at the top for consistency/compliance.

Copilot uses AI. Check for mistakes.
// and wasm_m2n_invoke.g.cpp produced by ManagedToNativeGenerator, so those
// files can be compiled outside the full CoreCLR build context (e.g. in
// Wasm.Build.Tests on Helix where src/coreclr/vm/wasm/callhelpers.hpp and
// src/native/minipal headers are not part of the payload).
//
// Definitions for the symbols declared here live in libcoreclr_static.a (which
// is linked in later) or in the same generated .cpp (e.g. g_wasmThunks /
// g_ReverseThunks tables are emitted by the generator itself).

#pragma once

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// CoreCLR type stubs
#ifndef _CORECLR_COMPAT_TYPES
#define _CORECLR_COMPAT_TYPES
typedef void MethodDesc;
typedef uintptr_t PCODE;
typedef uint32_t ULONG;
#define INTERP_STACK_SLOT_SIZE 8u
#endif

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coreclr_compat.h is intended to replace <minipal/utils.h>, but it doesn’t currently define NOINLINE. The generated wasm_m2n_invoke.g.cpp uses NOINLINE for portable-entrypoint thunks, so compilation will fail unless this macro is provided (or the generator includes the proper header again).

Copilot uses AI. Check for mistakes.

// CoreCLR logging stubs
#define LF_INTEROP 0
#define LL_INFO1000 0
#define LOG(x)

// CoreCLR assertion stub
#define PORTABILITY_ASSERT(msg) do { fprintf(stderr, "PORTABILITY_ASSERT: %s\n", msg); abort(); } while(0)

// Mirrors of declarations from src/coreclr/vm/wasm/callhelpers.hpp.
#define TERMINATE_R2R_STACK_WALK 1
struct StringToWasmSigThunk { const char* key; void* value; };
extern const StringToWasmSigThunk g_wasmThunks[];
extern const size_t g_wasmThunksCount;
struct ReverseThunkMapValue { MethodDesc** Target; void* EntryPoint; };
struct ReverseThunkMapEntry { ULONG hashCode; const char* Source; ReverseThunkMapValue value; };
extern const ReverseThunkMapEntry g_ReverseThunks[];
extern const size_t g_ReverseThunksCount;

// Mirrors of declarations from src/native/minipal/entrypoints.h, used by
// pinvoke-table.cpp. Marked static inline (rather than the upstream 'static')
// so cpp files that #include this compat header but don't call the helper
// don't trigger -Wunused-function.
typedef struct { const char* name; const void* method; } Entry;
#define DllImportEntry(impl) {#impl, (void*)&impl},
static inline const void* minipal_resolve_dllimport(const Entry* resolutionTable, size_t tableLength, const char* name)
{
for (size_t i = 0; i < tableLength; i++)
{
if (strcmp(name, resolutionTable[i].name) == 0)
return resolutionTable[i].method;
}
return NULL;
}
18 changes: 13 additions & 5 deletions src/mono/wasm/Wasm.Build.Tests/Common/BuildEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,19 @@ public string GetRuntimePackVersion(string tfm)
: throw new ArgumentException($"No runtime pack version found for tfm={tfm} .");

public string GetRuntimePackDir(string tfm, RuntimeVariant runtimeType = RuntimeVariant.SingleThreaded)
=> Path.Combine(WorkloadPacksDir,
runtimeType is RuntimeVariant.SingleThreaded
? $"Microsoft.NETCore.App.Runtime.Mono.{DefaultRuntimeIdentifier}"
: $"Microsoft.NETCore.App.Runtime.Mono.multithread.{DefaultRuntimeIdentifier}",
GetRuntimePackVersion(tfm));
=> Path.Combine(WorkloadPacksDir, GetRuntimePackName(runtimeType), GetRuntimePackVersion(tfm));

private string GetRuntimePackName(RuntimeVariant runtimeType)
{
// CoreCLR ships browser-wasm via Microsoft.NETCore.App.Runtime.{rid} (no flavor segment).
// Mono uses Microsoft.NETCore.App.Runtime.Mono.{rid}, with a separate .multithread. variant.
if (IsCoreClrRuntime)
return $"Microsoft.NETCore.App.Runtime.{DefaultRuntimeIdentifier}";

return runtimeType is RuntimeVariant.SingleThreaded
? $"Microsoft.NETCore.App.Runtime.Mono.{DefaultRuntimeIdentifier}"
: $"Microsoft.NETCore.App.Runtime.Mono.multithread.{DefaultRuntimeIdentifier}";
Comment on lines +204 to +213
}
Comment on lines +204 to +214
public string GetRuntimeNativeDir(string tfm, RuntimeVariant runtimeType = RuntimeVariant.SingleThreaded)
=> Path.Combine(GetRuntimePackDir(tfm, runtimeType), "runtimes", DefaultRuntimeIdentifier, "native");
public bool IsMultiThreadingRuntimePackAvailableFor(string tfm)
Expand Down
4 changes: 3 additions & 1 deletion src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

namespace Wasm.Build.Tests
{
[TestCategory("native")]
public class DllImportTests : PInvokeTableGeneratorTestsBase
{
public DllImportTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
Expand All @@ -24,6 +23,9 @@ public DllImportTests(ITestOutputHelper output, SharedBuildPerTestClassFixture b

[Theory]
[BuildAndRun(aot: false)]
// The "warning ... native function ... varargs" check is emitted by Mono's PInvokeTableGenerator.
// CoreCLR's PInvokeTableGenerator does not emit that warning, so this test is Mono-only.
[TestCategory("mono")]
public async Task NativeLibraryWithVariadicFunctions(Configuration config, bool aot)
{
ProjectInfo info = PrepareProjectForVariadicFunction(config, aot, "variadic");
Expand Down
4 changes: 2 additions & 2 deletions src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ from locale in locales

[Theory]
[MemberData(nameof(IcuExpectedAndMissingCustomShardTestData), parameters: new object[] { Configuration.Release })]
[TestCategory("native")]
[TestCategory("native-coreclr")]
public async Task CustomIcuShard(Configuration config, bool aot, string customIcuPath, string customLocales, bool onlyPredefinedCultures) =>
Comment on lines 42 to 45

Copilot AI Apr 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests use boolOptions for the aot parameter (so they generate AOT and non-AOT variants). Retagging them to native-coreclr will cause the AOT variants to run on the CoreCLR lane (since only category=native is excluded), which is likely unsupported for CoreCLR (UseMonoRuntime=false). Split/tag AOT variants as category=native (excluded on CoreCLR) or filter aot=true out for CoreCLR runs.

Copilot uses AI. Check for mistakes.
await TestIcuShards(config, Template.WasmBrowser, aot, customIcuPath, customLocales, GlobalizationMode.Custom, onlyPredefinedCultures);

[Theory]
[MemberData(nameof(IcuExpectedAndMissingAutomaticShardTestData), parameters: new object[] { Configuration.Release })]
[TestCategory("native")]
[TestCategory("native-coreclr")]
public async Task AutomaticShardSelectionDependingOnEnvLocale(Configuration config, bool aot, string environmentLocale, string testedLocales) =>
await PublishAndRunIcuTest(config, Template.WasmBrowser, aot, testedLocales, GlobalizationMode.Sharded, locale: environmentLocale);
}
2 changes: 1 addition & 1 deletion src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ from locale in locales

[Theory]
[MemberData(nameof(IcuExpectedAndMissingShardFromRuntimePackTestData), parameters: new object[] { Configuration.Release })]
[TestCategory("native")]
[TestCategory("native-coreclr")]
public async Task DefaultAvailableIcuShardsFromRuntimePack(Configuration config, bool aot, string shardName, string testedLocales) =>
Comment on lines 39 to 42

Copilot AI Apr 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This theory generates both aot=false and aot=true cases via boolOptions. After changing the category to native-coreclr, the AOT variants will no longer be excluded by the CoreCLR trait filter (-notrait category=native) and may run on CoreCLR where AOT is likely unsupported. Consider splitting/tagging AOT variants as category=native (excluded) or changing the data source to omit aot=true on CoreCLR.

Copilot uses AI. Check for mistakes.
await TestIcuShards(config, Template.WasmBrowser, aot, shardName, testedLocales, GlobalizationMode.Custom);
}
4 changes: 2 additions & 2 deletions src/mono/wasm/Wasm.Build.Tests/IcuTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static IEnumerable<object[]> IncorrectIcuTestData(Configuration config)

[Theory]
[MemberData(nameof(FullIcuWithInvariantTestData), parameters: new object[] { Configuration.Release })]
[TestCategory("native")]
[TestCategory("native-coreclr")]
public async Task FullIcuFromRuntimePackWithInvariant(Configuration config=Configuration.Release, bool aot=false, bool invariant=true, bool fullIcu=true, string testedLocales="Array.Empty<Locale>()") =>
Comment on lines 54 to 57

Copilot AI Apr 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing these theories to TestCategory("native-coreclr") makes them eligible to run under the CoreCLR lane filter (which only excludes category=native). However, the test data includes aot=true cases (boolOptions), and CoreCLR builds set <UseMonoRuntime>false</UseMonoRuntime>; AOT compilation is likely unsupported and will attempt to run anyway. Consider splitting into non-AOT methods (tagged native-coreclr) and AOT methods (keep category=native so they remain excluded on CoreCLR), or adjust the MemberData to exclude aot=true when BuildTestBase.IsCoreClrRuntime.

Copilot uses AI. Check for mistakes.
await PublishAndRunIcuTest(
config,
Expand All @@ -67,7 +67,7 @@ await PublishAndRunIcuTest(

[Theory]
[MemberData(nameof(FullIcuWithICustomIcuTestData), parameters: new object[] { Configuration.Release })]
[TestCategory("native")]
[TestCategory("native-coreclr")]
Comment on lines 56 to +70
public async Task FullIcuFromRuntimePackWithCustomIcu(Configuration config, bool aot, bool fullIcu)
{
string customIcuProperty = "BlazorIcuDataFileName";
Expand Down
6 changes: 5 additions & 1 deletion src/mono/wasm/Wasm.Build.Tests/IcuTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ protected ProjectInfo CreateIcuProject(
File.WriteAllText(programPath, programText);
_testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------");

UpdateBrowserMainJs();
// The template main.js calls JS interop APIs (setModuleImports, getAssemblyExports)
// which the ICU test program does not use. Replace it with a minimal version tailored
// for ICU tests, otherwise the JS interop assembly would be linked away by the trimmer.
Comment on lines +134 to +136

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new comment says the template main.js would cause the JS interop assembly to be linked away by the trimmer, but the reason to replace main.js seems to be the opposite: avoid calling JS interop APIs (setModuleImports/getAssemblyExports) so the app doesn't depend on JS interop being preserved. Please clarify the comment to reflect the actual failure mode/intent (e.g., default main.js calls these APIs but the app doesn't reference the managed JS interop pieces, so trimming can remove them and the default main.js would then fail at runtime).

Suggested change
// The template main.js calls JS interop APIs (setModuleImports, getAssemblyExports)
// which the ICU test program does not use. Replace it with a minimal version tailored
// for ICU tests, otherwise the JS interop assembly would be linked away by the trimmer.
// The template main.js calls JS interop APIs (setModuleImports, getAssemblyExports),
// but the ICU test program does not reference the managed JS interop pieces. Trimming
// can therefore remove them, and the default main.js would then fail at runtime, so
// replace it with a minimal version tailored for ICU tests that avoids those APIs.

Copilot uses AI. Check for mistakes.
string mainJsPath = Path.Combine(projectDirectory, "wwwroot", "main.js");
File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "EntryPoints", "icu_main.js"), mainJsPath, overwrite: true);
return info;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public async Task AOT_InvariantGlobalization(Configuration config, bool aot, boo
// TODO: What else should we use to verify a relinked build?
[Theory]
[MemberData(nameof(InvariantGlobalizationTestData), parameters: new object[] { /*aot*/ false })]
[TestCategory("native")]
[TestCategory("native-coreclr")]
public async Task RelinkingWithoutAOT(Configuration config, bool aot, bool? invariantGlobalization)
=> await TestInvariantGlobalization(config, aot, invariantGlobalization, isNativeBuild: true);

Expand Down
2 changes: 1 addition & 1 deletion src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Wasm.Build.Tests;

[TestCategory("native")]
[TestCategory("native-coreclr")]
public class MemoryTests : WasmTemplateTestsBase
Comment on lines +16 to 17

Copilot AI Apr 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the class retagged to native-coreclr, this test will start running in the CoreCLR lane. The build assertion currently uses ExpectSuccess: BuildTestBase.IsUsingWorkloads, but CoreCLR WBT runs with TestUsingWorkloads=false while native relink is now supported (emsdk is provisioned separately). That combination likely makes the test fail (it will expect the native build to fail even if it succeeds). Consider basing ExpectSuccess/execution on whether native builds are actually available (e.g., IsUsingWorkloads || IsCoreClrRuntime), or keep the test excluded until its expectations are updated.

Copilot uses AI. Check for mistakes.
{
Comment on lines +16 to 18

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the class category changed to "native-coreclr", this test class will now run on the CoreCLR WBT lane (which sets SDK_HAS_WORKLOAD_INSTALLED=false). In that lane, AllocateLargeHeapThenRepeatedlyInterop calls BuildProject(... ExpectSuccess: BuildTestBase.IsUsingWorkloads) which becomes false, so the test effectively expects the build to fail and then doesn't run/validate anything. If the intent is to start exercising this scenario on CoreCLR, consider splitting the workload/no-workload variants (or tagging the workload-only [Fact] with TestCategory("workload")) and making the CoreCLR-enabled path assert a successful native rebuild instead of treating failure as success.

Copilot uses AI. Check for mistakes.
public MemoryTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
Expand Down
Loading
Loading