Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions eng/testing/tests.wasm.targets
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<!-- Run only if previous command succeeded -->
<_ShellCommandSeparator Condition="'$(OS)' == 'Windows_NT'">&amp;&amp;</_ShellCommandSeparator>
<_ShellCommandSeparator Condition="'$(OS)' != 'Windows_NT'">&amp;&amp;</_ShellCommandSeparator>
<WasmNativeStrip>false</WasmNativeStrip>
</PropertyGroup>

<PropertyGroup>
Expand Down
14 changes: 13 additions & 1 deletion src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,24 @@
<TestTrimming Condition="'$(TestTrimming)' == ''">false</TestTrimming>
</PropertyGroup>

<ItemGroup Condition="'$(TargetOS)' == 'Browser' and '$(BuildAOTTestsOnHelix)' == 'true' and '$(RunDisabledWasmTests)' != 'true' and '$(RunAOTCompilation)' == 'true'">
<!-- Wasm aot on !windows -->
<ItemGroup Condition="'$(TargetOS)' == 'Browser' and '$(BuildAOTTestsOnHelix)' == 'true' and '$(RunDisabledWasmTests)' != 'true' and '$(RunAOTCompilation)' == 'true' and '$(BrowserHost)' != 'Windows'">
<!-- Exceeds VM resources in CI on compilation: https://github.com/dotnet/runtime/issues/61339 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)Microsoft.Extensions.Logging.Abstractions\tests\Microsoft.Extensions.Logging.Generators.Tests\Microsoft.Extensions.Logging.Generators.Roslyn3.11.Tests.csproj" />

<!-- https://github.com/dotnet/runtime/issues/61756 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.RegularExpressions\tests\System.Text.RegularExpressions.Tests.csproj" />

<!-- https://github.com/dotnet/runtime/issues/62362 -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Collections.Immutable\tests\System.Collections.Immutable.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Collections\tests\System.Collections.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.IO.Pipelines\tests\System.IO.Pipelines.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Linq.Parallel\tests\System.Linq.Parallel.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Reflection.TypeExtensions\tests\System.Reflection.TypeExtensions.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.Json\tests\System.Text.Json.SourceGeneration.Tests\System.Text.Json.SourceGeneration.Roslyn3.11.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.Json\tests\System.Text.Json.SourceGeneration.Tests\System.Text.Json.SourceGeneration.Roslyn4.0.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Text.Json\tests\System.Text.Json.Tests\System.Text.Json.Tests.csproj" />
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.ValueTuple\tests\System.ValueTuple.Tests.csproj" />
</ItemGroup>

<!-- Projects that don't support code coverage measurement. -->
Expand Down
4 changes: 4 additions & 0 deletions src/mono/wasm/build/WasmApp.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
<WasmUseEMSDK_PATH Condition="'$(WasmUseEMSDK_PATH)' == '' and '$(EMSDK_PATH)' != '' and Exists('$(MSBuildThisFileDirectory)WasmApp.InTree.targets')">true</WasmUseEMSDK_PATH>
</PropertyGroup>

<ItemGroup>
<UpToDateCheckInput Include="@(NativeFileReference)" />
</ItemGroup>

<ItemGroup Condition="'$(Configuration)' == 'Debug' and '@(_MonoComponent->Count())' == 0">
<_MonoComponent Include="hot_reload;debugger" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/mono/wasm/build/WasmApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@

<Target Name="_InitializeCommonProperties">
<Error Condition="'$(MicrosoftNetCoreAppRuntimePackDir)' == '' and ('%(ResolvedRuntimePack.PackageDirectory)' == '' or !Exists(%(ResolvedRuntimePack.PackageDirectory)))"
Text="Could not find %25(ResolvedRuntimePack.PackageDirectory)=%(ResolvedRuntimePack.PackageDirectory)" />
Text="%24(MicrosoftNetCoreAppRuntimePackDir)='', and cannot find %25(ResolvedRuntimePack.PackageDirectory)=%(ResolvedRuntimePack.PackageDirectory). One of these need to be set to a valid path" />
<Error Condition="'$(IntermediateOutputPath)' == ''" Text="%24(IntermediateOutputPath) property needs to be set" />

<PropertyGroup>
Expand Down
73 changes: 73 additions & 0 deletions src/mono/wasm/sln/WasmBuild.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31722.452
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WasmBuildTasks", "..\..\..\tasks\WasmBuildTasks\WasmBuildTasks.csproj", "{D5BD9C0C-8A05-493E-BE45-13AF8286CD92}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WasmAppBuilder", "..\..\..\tasks\WasmAppBuilder\WasmAppBuilder.csproj", "{8DEBFDE2-B127-46D7-92CF-EEA6D1DA2554}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoAOTCompiler", "..\..\..\tasks\AotCompilerTask\MonoAOTCompiler.csproj", "{A9C02284-0387-42E7-BF78-47DF13656D5E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Build.Tests", "..\..\..\tests\BuildWasmApps\Wasm.Build.Tests\Wasm.Build.Tests.csproj", "{94E18644-B0E5-4DBB-9CE4-EA1515ACE4C2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DebuggerTestSuite", "..\debugger\DebuggerTestSuite\DebuggerTestSuite.csproj", "{4C0EE027-FC30-4167-B2CF-A6D18F00E08F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BrowserDebugHost", "..\debugger\BrowserDebugHost\BrowserDebugHost.csproj", "{292A88FD-795F-467A-8801-B5B791CEF96E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BrowserDebugProxy", "..\debugger\BrowserDebugProxy\BrowserDebugProxy.csproj", "{F5AE2AF5-3C30-45E3-A0C6-D962C51FE5E7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WasmAppHost", "..\host\WasmAppHost.csproj", "{C7099764-EC2E-4FAF-9057-0321893DE4F8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplyUpdateReferencedAssembly", "..\debugger\tests\ApplyUpdateReferencedAssembly\ApplyUpdateReferencedAssembly.csproj", "{75477B6F-DC8E-4002-88B8-017C992C568E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D5BD9C0C-8A05-493E-BE45-13AF8286CD92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5BD9C0C-8A05-493E-BE45-13AF8286CD92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5BD9C0C-8A05-493E-BE45-13AF8286CD92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5BD9C0C-8A05-493E-BE45-13AF8286CD92}.Release|Any CPU.Build.0 = Release|Any CPU
{8DEBFDE2-B127-46D7-92CF-EEA6D1DA2554}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8DEBFDE2-B127-46D7-92CF-EEA6D1DA2554}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8DEBFDE2-B127-46D7-92CF-EEA6D1DA2554}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8DEBFDE2-B127-46D7-92CF-EEA6D1DA2554}.Release|Any CPU.Build.0 = Release|Any CPU
{A9C02284-0387-42E7-BF78-47DF13656D5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A9C02284-0387-42E7-BF78-47DF13656D5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9C02284-0387-42E7-BF78-47DF13656D5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9C02284-0387-42E7-BF78-47DF13656D5E}.Release|Any CPU.Build.0 = Release|Any CPU
{94E18644-B0E5-4DBB-9CE4-EA1515ACE4C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94E18644-B0E5-4DBB-9CE4-EA1515ACE4C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94E18644-B0E5-4DBB-9CE4-EA1515ACE4C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94E18644-B0E5-4DBB-9CE4-EA1515ACE4C2}.Release|Any CPU.Build.0 = Release|Any CPU
{4C0EE027-FC30-4167-B2CF-A6D18F00E08F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C0EE027-FC30-4167-B2CF-A6D18F00E08F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C0EE027-FC30-4167-B2CF-A6D18F00E08F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C0EE027-FC30-4167-B2CF-A6D18F00E08F}.Release|Any CPU.Build.0 = Release|Any CPU
{292A88FD-795F-467A-8801-B5B791CEF96E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{292A88FD-795F-467A-8801-B5B791CEF96E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{292A88FD-795F-467A-8801-B5B791CEF96E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{292A88FD-795F-467A-8801-B5B791CEF96E}.Release|Any CPU.Build.0 = Release|Any CPU
{F5AE2AF5-3C30-45E3-A0C6-D962C51FE5E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5AE2AF5-3C30-45E3-A0C6-D962C51FE5E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5AE2AF5-3C30-45E3-A0C6-D962C51FE5E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5AE2AF5-3C30-45E3-A0C6-D962C51FE5E7}.Release|Any CPU.Build.0 = Release|Any CPU
{75477B6F-DC8E-4002-88B8-017C992C568E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75477B6F-DC8E-4002-88B8-017C992C568E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75477B6F-DC8E-4002-88B8-017C992C568E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75477B6F-DC8E-4002-88B8-017C992C568E}.Release|Any CPU.Build.0 = Release|Any CPU
{C7099764-EC2E-4FAF-9057-0321893DE4F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7099764-EC2E-4FAF-9057-0321893DE4F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7099764-EC2E-4FAF-9057-0321893DE4F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7099764-EC2E-4FAF-9057-0321893DE4F8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2BDE8FDE-4261-4B4D-8B54-ACC88B06C8D1}
EndGlobalSection
EndGlobal
1 change: 1 addition & 0 deletions src/mono/wasm/wasm.proj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<EmccCmd>emcc</EmccCmd>
<WasmObjDir>$(ArtifactsObjDir)wasm</WasmObjDir>
<_EmccDefaultsRspPath>$(NativeBinDir)src\emcc-default.rsp</_EmccDefaultsRspPath>
<WasmNativeStrip Condition="'$(ContinuousIntegrationBuild)' == 'true'">false</WasmNativeStrip>
</PropertyGroup>

<Target Name="CheckEnv">
Expand Down
6 changes: 3 additions & 3 deletions src/tasks/AotCompilerTask/MonoAOTCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -744,13 +744,13 @@ private bool PrecompileLibrary(PrecompileArguments args)
Log.LogMessage(importance, $"{msgPrefix}Exec (with response file contents expanded) in {args.WorkingDir}: {envStr}{CompilerBinaryPath} {File.ReadAllText(args.ResponseFilePath)}");
}

Log.LogMessage(importance, output);

if (exitCode != 0)
{
Log.LogError($"Precompiling failed for {assembly}");
Log.LogError($"Precompiling failed for {assembly}.{Environment.NewLine}{output}");
return false;
}

Log.LogMessage(importance, output);
}
catch (Exception ex)
{
Expand Down
64 changes: 59 additions & 5 deletions src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class PInvokeTableGenerator : Task
[Output]
public string FileWrites { get; private set; } = string.Empty;

private static char[] s_charsToReplace = new[] { '.', '-', };
private static char[] s_charsToReplace = new[] { '.', '-', '+' };

public override bool Execute()
{
Expand Down Expand Up @@ -88,7 +88,21 @@ public void GenPInvokeTable(string[] pinvokeModules, string[] assemblies)

private void CollectPInvokes(List<PInvoke> pinvokes, List<PInvokeCallback> callbacks, Type type)
{
foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance)) {
foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance))
{
try
{
CollectPInvokesForMethod(method);
}
catch (Exception ex)
{
Log.LogMessage(MessageImportance.Low, $"Could not get pinvoke, or callbacks for method {method.Name}: {ex}");
continue;
}
}

void CollectPInvokesForMethod(MethodInfo method)
{
if ((method.Attributes & MethodAttributes.PinvokeImpl) != 0)
{
var dllimport = method.CustomAttributes.First(attr => attr.AttributeType.Name == "DllImportAttribute");
Expand Down Expand Up @@ -164,7 +178,8 @@ private void EmitPInvokeTable(StreamWriter w, Dictionary<string, string> modules
Where(l => l.Module == module && !l.Skip).
OrderBy(l => l.EntryPoint).
GroupBy(d => d.EntryPoint).
Select (l => "{\"" + l.Key + "\", " + l.Key + "}, // " + string.Join (", ", l.Select(c => c.Method.DeclaringType!.Module!.Assembly!.GetName ()!.Name!).Distinct().OrderBy(n => n)));
Select (l => "{\"" + FixupSymbolName(l.Key) + "\", " + FixupSymbolName(l.Key) + "}, " +
"// " + string.Join (", ", l.Select(c => c.Method.DeclaringType!.Module!.Assembly!.GetName ()!.Name!).Distinct().OrderBy(n => n)));

foreach (var pinvoke in assemblies_pinvokes) {
w.WriteLine (pinvoke);
Expand Down Expand Up @@ -216,6 +231,45 @@ static bool ShouldTreatAsVariadic(PInvoke[] candidates)
}
}

private static string FixupSymbolName(string name)
{
UTF8Encoding utf8 = new();
byte[] bytes = utf8.GetBytes(name);
StringBuilder sb = new();

foreach (byte b in bytes)
{
if ((b >= (byte)'0' && b <= (byte)'9') ||
(b >= (byte)'a' && b <= (byte)'z') ||
(b >= (byte)'A' && b <= (byte)'Z') ||
(b == (byte)'_'))
{
sb.Append((char) b);
}
else if (s_charsToReplace.Contains((char) b))
{
sb.Append('_');
}
else
{
sb.Append($"_{b:X}_");
}
}

return sb.ToString();
}

private static string SymbolNameForMethod(MethodInfo method)
{
StringBuilder sb = new();
Type? type = method.DeclaringType;
sb.Append($"{type!.Module!.Assembly!.GetName()!.Name!}_");
sb.Append($"{(type!.IsNested ? type!.FullName : type!.Name)}_");
sb.Append(method.Name);

return FixupSymbolName(sb.ToString());
}

private string MapType (Type t)
{
string name = t.Name;
Expand Down Expand Up @@ -262,7 +316,7 @@ private static bool TryIsMethodGetParametersUnsupported(MethodInfo method, [NotN
if (method.Name == "EnumCalendarInfo") {
// FIXME: System.Reflection.MetadataLoadContext can't decode function pointer types
// https://github.com/dotnet/runtime/issues/43791
sb.Append($"int {pinvoke.EntryPoint} (int, int, int, int, int);");
sb.Append($"int {FixupSymbolName(pinvoke.EntryPoint)} (int, int, int, int, int);");
return sb.ToString();
}

Expand All @@ -274,7 +328,7 @@ private static bool TryIsMethodGetParametersUnsupported(MethodInfo method, [NotN
}

sb.Append(MapType(method.ReturnType));
sb.Append($" {pinvoke.EntryPoint} (");
sb.Append($" {FixupSymbolName(pinvoke.EntryPoint)} (");
int pindex = 0;
var pars = method.GetParameters();
foreach (var p in pars) {
Expand Down
57 changes: 32 additions & 25 deletions src/tests/BuildWasmApps/Wasm.Build.Tests/BuildPublishTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ public void BuildThenPublishNoAOT(BuildArgs buildArgs, RunHost host, string id)
// no relinking for build
bool relinked = false;
BuildProject(buildArgs,
initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
dotnetWasmFromRuntimePack: !relinked,
id: id,
createProject: true,
publish: false);
new BuildProjectOptions(
InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
DotnetWasmFromRuntimePack: !relinked,
CreateProject: true,
Publish: false
));


Run();

Expand All @@ -53,10 +56,11 @@ public void BuildThenPublishNoAOT(BuildArgs buildArgs, RunHost host, string id)
relinked = buildArgs.Config == "Release";
BuildProject(buildArgs,
id: id,
dotnetWasmFromRuntimePack: !relinked,
createProject: false,
publish: true,
useCache: false);
new BuildProjectOptions(
DotnetWasmFromRuntimePack: !relinked,
CreateProject: false,
Publish: true,
UseCache: false));

Run();

Expand All @@ -79,12 +83,13 @@ public void BuildThenPublishWithAOT(BuildArgs buildArgs, RunHost host, string id
// no relinking for build
bool relinked = false;
(_, string output) = BuildProject(buildArgs,
initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
dotnetWasmFromRuntimePack: !relinked,
id: id,
createProject: true,
publish: false,
label: "first_build");
id,
new BuildProjectOptions(
InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
DotnetWasmFromRuntimePack: !relinked,
CreateProject: true,
Publish: false,
Label: "first_build"));

BuildPaths paths = GetBuildPaths(buildArgs);
var pathsDict = GetFilesTable(buildArgs, paths, unchanged: false);
Expand All @@ -109,11 +114,12 @@ public void BuildThenPublishWithAOT(BuildArgs buildArgs, RunHost host, string id
// relink by default for Release+publish
(_, output) = BuildProject(buildArgs,
id: id,
dotnetWasmFromRuntimePack: false,
createProject: false,
publish: true,
useCache: false,
label: "first_publish");
new BuildProjectOptions(
DotnetWasmFromRuntimePack: false,
CreateProject: false,
Publish: true,
UseCache: false,
Label: "first_publish"));

var publishStat = StatFiles(pathsDict.Select(kvp => kvp.Value.fullPath));
Assert.True(publishStat["pinvoke.o"].Exists);
Expand All @@ -125,12 +131,13 @@ public void BuildThenPublishWithAOT(BuildArgs buildArgs, RunHost host, string id

// second build
(_, output) = BuildProject(buildArgs,
initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
dotnetWasmFromRuntimePack: !relinked,
id: id,
createProject: true,
publish: false,
label: "second_build");
id: id,
new BuildProjectOptions(
InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42),
DotnetWasmFromRuntimePack: !relinked,
CreateProject: true,
Publish: false,
Label: "second_build"));
var secondBuildStat = StatFiles(pathsDict.Select(kvp => kvp.Value.fullPath));

// no relinking, or AOT
Expand Down
Loading