diff --git a/crates/misc/dotnet/tests/FunctionThunkingTests.cs b/crates/misc/dotnet/tests/FunctionThunkingTests.cs new file mode 100644 index 0000000000..dc7af0bd3b --- /dev/null +++ b/crates/misc/dotnet/tests/FunctionThunkingTests.cs @@ -0,0 +1,71 @@ +using FluentAssertions; +using System; +using System.Linq; +using Xunit; + +namespace Wasmtime.Tests +{ + public class FunctionThunkingFixture : ModuleFixture + { + protected override string ModuleFileName => "FunctionThunking.wasm"; + } + + public class FunctionThunkingTests : IClassFixture + { + const string THROW_MESSAGE = "Test error messages for wasmtime dotnet bidnings unit tests."; + + class MyHost : IHost + { + public Instance Instance { get; set; } + + [Import("add", Module = "env")] + public int Add(int x, int y) => x + y; + + [Import("do_throw", Module = "env")] + public void Throw() => throw new Exception(THROW_MESSAGE); + } + + public FunctionThunkingTests(FunctionThunkingFixture fixture) + { + Fixture = fixture; + } + + private FunctionThunkingFixture Fixture { get; } + + [Fact] + public void ItBindsImportMethodsAndCallsThemCorrectly() + { + var host = new MyHost(); + using (var instance = Fixture.Module.Instantiate(host)) + { + var add_func = instance.Externs.Functions.Where(f => f.Name == "add_wrapper").Single(); + int invoke_add(int x, int y) => (int)add_func.Invoke(new object[] { x, y }); + + invoke_add(40, 2).Should().Be(42); + invoke_add(22, 5).Should().Be(27); + + //Collect garbage to make sure delegate function pointers pasted to wasmtime are rooted. + GC.Collect(); + GC.WaitForPendingFinalizers(); + + invoke_add(1970, 50).Should().Be(2020); + } + } + + [Fact] + public void ItPropegatesExceptionsToCallersViaTraps() + { + var host = new MyHost(); + using (var instance = Fixture.Module.Instantiate(host)) + { + var throw_func = instance.Externs.Functions.Where(f => f.Name == "do_throw_wrapper").Single(); + Action action = () => throw_func.Invoke(); + + action + .Should() + .Throw() + .WithMessage(THROW_MESSAGE); + } + } + } +} diff --git a/crates/misc/dotnet/tests/Modules/FunctionThunking.wasm b/crates/misc/dotnet/tests/Modules/FunctionThunking.wasm new file mode 100644 index 0000000000..a8a67acb1c Binary files /dev/null and b/crates/misc/dotnet/tests/Modules/FunctionThunking.wasm differ diff --git a/crates/misc/dotnet/tests/Modules/FunctionThunking.wat b/crates/misc/dotnet/tests/Modules/FunctionThunking.wat new file mode 100644 index 0000000000..fb487afaa8 --- /dev/null +++ b/crates/misc/dotnet/tests/Modules/FunctionThunking.wat @@ -0,0 +1,20 @@ +(module + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$v (func)) + (import "env" "add" (func $add (param i32 i32) (result i32))) + (import "env" "do_throw" (func $do_throw)) + (table 0 anyfunc) + (memory $0 1) + (export "memory" (memory $0)) + (export "add_wrapper" (func $add_wrapper)) + (export "do_throw_wrapper" (func $do_throw_wrapper)) + (func $add_wrapper (; 2 ;) (param $0 i32) (param $1 i32) (result i32) + (call $add + (get_local $0) + (get_local $1) + ) + ) + (func $do_throw_wrapper (; 3 ;) + (call $do_throw) + ) +)