Skip to content

Commit

Permalink
[WASI] improve UCO sample and WBT (dotnet#106632)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelsavara committed Aug 27, 2024
1 parent 00553a8 commit 5d21506
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 50 deletions.
8 changes: 8 additions & 0 deletions src/mono/sample/wasi/native/ILLink.Descriptors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<linker>
<!-- workaround for https://github.com/dotnet/runtime/issues/106627 -->
<assembly fullname="Wasi.Native.Sample">
<type fullname="Sample.Test">
<method signature="System.Int32 MyExport(System.Int32)" />
</type>
</assembly>
</linker>
2 changes: 2 additions & 0 deletions src/mono/sample/wasi/native/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System;
using System.Runtime.InteropServices;

namespace Sample;

public unsafe class Test
{
[UnmanagedCallersOnly(EntryPoint = "ManagedFunc")]
Expand Down
2 changes: 2 additions & 0 deletions src/mono/sample/wasi/native/Wasi.Native.Sample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

<ItemGroup>
<NativeFileReference Include="local.c" />
<!-- workaround for https://github.com/dotnet/runtime/issues/106627 -->
<TrimmerRootDescriptor Include="$(MSBuildThisFileDirectory)ILLink.Descriptors.xml" />
</ItemGroup>
<Target Name="RunSample" DependsOnTargets="RunSampleWithWasmtime" />
</Project>
10 changes: 10 additions & 0 deletions src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,16 @@ public static int Main()
.MultiplyWithSingleArgs(true, false) /*aot*/
.UnwrapItemsAsArrays();

public static IEnumerable<object?[]> TestDataForConsolePublishAndRunRelease() =>
new IEnumerable<object?>[]
{
new object?[] { true },
new object?[] { false }
}
.AsEnumerable()
.MultiplyWithSingleArgs(true, false) /*aot*/
.UnwrapItemsAsArrays();

protected CommandResult RunWithoutBuild(string config, string id, bool enableHttp = false)
{
// wasmtime --wasi http is necessary because the default dotnet.wasm (without native rebuild depends on wasi:http world)
Expand Down
78 changes: 29 additions & 49 deletions src/mono/wasi/Wasi.Build.Tests/PInvokeTableGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,58 +17,38 @@ public PInvokeTableGeneratorTests(ITestOutputHelper output, SharedBuildPerTestCl
{
}

[Fact]
public void InteropSupportForUnmanagedEntryPointWithoutDelegate()
[Theory]
[MemberData(nameof(TestDataForConsolePublishAndRunRelease))]
public void InteropSupportForUnmanagedEntryPointWithoutDelegate(bool singleFileBundle, bool aot)
{
string config = "Release";
string id = $"{config}_{GetRandomId()}";
string projectFile = CreateWasmTemplateProject(id, "wasiconsole");
string code =
"""
using System;
using System.Runtime.InteropServices;
public unsafe class Test
{
[UnmanagedCallersOnly(EntryPoint = "ManagedFunc")]
public static int MyExport(int number)
{
// called from MyImport aka UnmanagedFunc
Console.WriteLine($"MyExport({number}) -> 42");
return 42;
}

[DllImport("*", EntryPoint = "UnmanagedFunc")]
public static extern void MyImport(); // calls ManagedFunc aka MyExport
if(aot)
{
// Active issue https://github.com/dotnet/runtime/issues/101276
return;
}

public unsafe static int Main(string[] args)
{
Console.WriteLine($"main: {args.Length}");
MyImport();
return 0;
}
}
""";
string cCode =
"""
#include <stdio.h>

int ManagedFunc(int number);
string id = $"Release_{GetRandomId()}";
string projectFile = CreateWasmTemplateProject(id, "wasiconsole");
string projectName = Path.GetFileNameWithoutExtension(projectFile);
File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "Native.cs"), Path.Combine(_projectDir!, "Program.cs"), true);
File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "native.c"), Path.Combine(_projectDir!, "native.c")!, true);

// workaround for https://github.com/dotnet/runtime/issues/106627
File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "ILLink.Native.Descriptors.xml"), Path.Combine(_projectDir!, "ILLink.Native.Descriptors.xml")!, true);

void UnmanagedFunc()
{
int ret = 0;
printf("UnmanagedFunc calling ManagedFunc\n");
ret = ManagedFunc(123);
printf("ManagedFunc returned %d\n", ret);
}
""";
File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), code);
File.WriteAllText(Path.Combine(_projectDir!, "local.c"), cCode);
string extraProperties = @"<WasmNativeStrip>false</WasmNativeStrip>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>";
AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties, extraItems: @"<NativeFileReference Include=""local.c"" />");
string projectName = Path.GetFileNameWithoutExtension(projectFile);
var buildArgs = new BuildArgs(projectName, config, AOT: true, ProjectFileContents: id, ExtraBuildArgs: null);
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishTrimmed>true</PublishTrimmed>
<AssemblyName>Wasi.Native.Test</AssemblyName>";
if (aot)
extraProperties += "<RunAOTCompilation>true</RunAOTCompilation><_WasmDevel>false</_WasmDevel>";
if (singleFileBundle)
extraProperties += "<WasmSingleFileBundle>true</WasmSingleFileBundle>";

string itemsProperties = @"<NativeFileReference Include=""native.c"" />
<TrimmerRootDescriptor Include=""$(MSBuildThisFileDirectory)ILLink.Native.Descriptors.xml"" />";
AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties, extraItems: itemsProperties);
var buildArgs = new BuildArgs(projectName, Config: "Release", AOT: true, ProjectFileContents: id, ExtraBuildArgs: null);
buildArgs = ExpandBuildArgs(buildArgs);
BuildProject(buildArgs,
id: id,
Expand All @@ -80,7 +60,7 @@ void UnmanagedFunc()

CommandResult res = new RunCommand(s_buildEnv, _testOutput)
.WithWorkingDirectory(_projectDir!)
.ExecuteWithCapturedOutput($"run --no-silent --no-build -c {config}")
.ExecuteWithCapturedOutput($"run --no-silent --no-build -c Release")
.EnsureSuccessful();
Assert.Contains("MyExport(123) -> 42", res.Output);
}
Expand Down
2 changes: 1 addition & 1 deletion src/mono/wasi/build/WasiApp.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<TargetArchitecture>wasm</TargetArchitecture>
<TargetOS>wasi</TargetOS>
<RuntimeIdentifier>wasi-wasm</RuntimeIdentifier>
<TrimMode Condition="'$(TrimMode)' == ''">partial</TrimMode>
<TrimMode Condition="'$(TrimMode)' == ''">full</TrimMode>
<WasmIsWorkloadAvailable Condition="'$(WasiNativeWorkload)' == 'true'">true</WasmIsWorkloadAvailable>
</PropertyGroup>

Expand Down
8 changes: 8 additions & 0 deletions src/mono/wasi/testassets/ILLink.Native.Descriptors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<linker>
<!-- workaround for https://github.com/dotnet/runtime/issues/106627 -->
<assembly fullname="Wasi.Native.Test">
<type fullname="Sample.Test">
<method signature="System.Int32 MyExport(System.Int32)" />
</type>
</assembly>
</linker>
28 changes: 28 additions & 0 deletions src/mono/wasi/testassets/Native.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;

namespace Sample;

public unsafe class Test
{
[UnmanagedCallersOnly(EntryPoint = "ManagedFunc")]
public static int MyExport(int number)
{
// called from MyImport aka UnmanagedFunc
Console.WriteLine($"MyExport({number}) -> 42");
return 42;
}

[DllImport("*", EntryPoint = "UnmanagedFunc")]
public static extern void MyImport(); // calls ManagedFunc aka MyExport

public unsafe static int Main(string[] args)
{
Console.WriteLine($"main: {args.Length}");
MyImport();
return 0;
}
}
11 changes: 11 additions & 0 deletions src/mono/wasi/testassets/native.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <stdio.h>

int ManagedFunc(int number);

void UnmanagedFunc()
{
int ret = 0;
printf("UnmanagedFunc calling ManagedFunc\n");
ret = ManagedFunc(123);
printf("ManagedFunc returned %d\n", ret);
}

0 comments on commit 5d21506

Please sign in to comment.