Skip to content

Conversation

@andrewmd5
Copy link

Gives consumers of wasmtime-dotnet the ability to statically link the native libraries into their executable when publishing with AOT compilation.

I also added all the necessary attributes on the reflection codepaths.

using System;
using System.Diagnostics.CodeAnalysis;
using Wasmtime;

[assembly: UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Wasmtime callback wrappers work correctly with AOT")]
[assembly: UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Wasmtime callback wrappers work correctly with AOT")]

const string wat = """
(module
  ;; Import the hello function from C#
  (import "" "hello" (func $hello))
  ;; Import the add function from C#
  (import "" "add" (func $add (param i32 i32) (result i32)))
  ;; Export a run function that calls hello
  (func (export "run")
    call $hello
  )
  ;; Export a test_math function that uses add and returns a value
  (func (export "test_math") (result i32)
    ;; Call add(10, 32) and return the result (should be 42)
    i32.const 10
    i32.const 32
    call $add
  )
)
""";

Console.WriteLine("Loading WebAssembly module from embedded WAT");
using var engine = new Engine();
using var module = Module.FromText(engine, "hello", wat);
using var linker = new Linker(engine);
using var store = new Store(engine);

linker.Define(
    "",
    "hello",
    Function.FromCallback(store, () => Console.WriteLine("Hello from C#, WebAssembly!"))
);

linker.Define(
    "",
    "add",
    Function.FromCallback(store, (int a, int b) => {
        var sum = a + b;
        Console.WriteLine($"C# add function: {a} + {b} = {sum}");
        return sum;
    })
);

var instance = linker.Instantiate(store, module);
var run = instance.GetAction("run");
if (run is null)
{
    Console.WriteLine("error: run export is missing");
    return;
}
run();

var mathTest = instance.GetFunction<int>("test_math");
if (mathTest is not null)
{
    var result = mathTest();
    Console.WriteLine($"test_math returned: {result}");
}
else
{
    Console.WriteLine("warning: test_math export is missing");
}

Console.WriteLine("All tests completed successfully!");

produces:

wasmtime-dotnet git:(main) /Users/andrew/projects/wasmtime-test/bin/Release/net9.0/osx-arm64/publish/test
Loading WebAssembly module from embedded WAT
Hello from C#, WebAssembly!
C# add function: 10 + 32 = 42
test_math returned: 42
All tests completed successfully!wasmtime-dotnet git:(main) otool -L /Users/andrew/projects/wasmtime-test/bin/Release/net9.0/osx-arm64/publish/test
/Users/andrew/projects/wasmtime-test/bin/Release/net9.0/osx-arm64/publish/test:
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1356.0.0)
        /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
        /usr/lib/swift/libswiftCore.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/swift/libswiftFoundation.dylib (compatibility version 1.0.0, current version 120.100.0)
        /usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current version 76.1.0)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 4103.0.0)
        /System/Library/Frameworks/CryptoKit.framework/Versions/A/CryptoKit (compatibility version 1.0.0, current version 1.0.0)
        /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 4103.0.0)
        /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 61901.40.47)
        /System/Library/Frameworks/GSS.framework/Versions/A/GSS (compatibility version 1.0.0, current version 1.0.0)wasmtime-dotnet git:(main)

My recommendation would be to drop support for .NET Standard 2.1 to take advantage of static abstract members in interfaces to avoid using things like Activator.CreateInstance - and introduce a source generator to to remove all dependencies on reflection. But for my use-case this PR is sufficient and unblocks me.

Resolves #293

the project is configured to always download the pre-release version of wasitime outside of a publish workflow - 'dev' has breaking changes. This resolves them and bumps to 38.0.3
@andrewmd5
Copy link
Author

CC: @peterhuene & @jsturtevant

@martindevans
Copy link
Contributor

My recommendation would be to drop support for .NET Standard 2.1

Personally I would like to keep keep .NET Standard 2.1 support until Unity supports CoreCLR, after that I wouldn't have a usecase for it. Anyone stuck using .NET Framework would probably want it kept beyond that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AOT Compatibility

2 participants