From ffa88ab2374339a5037682db3f4196aba55a9e43 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Wed, 15 Feb 2023 15:34:12 +0000 Subject: [PATCH 1/6] Converted `Memory` into a `readonly struct` --- src/Memory.cs | 5 +++-- tests/CallerTests.cs | 6 +++--- tests/FunctionTests.cs | 2 +- tests/LinkerFunctionsTests.cs | 2 +- tests/Memory64AccessTests.cs | 5 +++-- tests/MemoryAccessTests.cs | 12 ++++++++++-- tests/MemoryExportsTests.cs | 8 ++------ tests/WasiTests.cs | 18 +++++++++--------- 8 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/Memory.cs b/src/Memory.cs index 9a85fb3..3e44e24 100644 --- a/src/Memory.cs +++ b/src/Memory.cs @@ -8,7 +8,7 @@ namespace Wasmtime /// /// Represents a WebAssembly memory. /// - public class Memory : IExternal + public readonly struct Memory : IExternal { /// /// Creates a new WebAssembly memory. @@ -553,6 +553,7 @@ internal Memory(Store store, ExternMemory memory) { this.memory = memory; this.store = store; + this.Maximum = null; var typeHandle = Native.wasmtime_memory_type(store.Context.handle, this.memory); try @@ -580,7 +581,7 @@ internal static class Native public static extern IntPtr wasmtime_memory_new(IntPtr context, IntPtr typeHandle, out ExternMemory memory); [DllImport(Engine.LibraryName)] - public static unsafe extern byte* wasmtime_memory_data(IntPtr context, in ExternMemory memory); + public static extern unsafe byte* wasmtime_memory_data(IntPtr context, in ExternMemory memory); [DllImport(Engine.LibraryName)] public static extern nuint wasmtime_memory_data_size(IntPtr context, in ExternMemory memory); diff --git a/tests/CallerTests.cs b/tests/CallerTests.cs index f1a8648..35fc2c8 100644 --- a/tests/CallerTests.cs +++ b/tests/CallerTests.cs @@ -80,7 +80,7 @@ public void ItCanReadAndWriteMemoryFromCaller() { Linker.DefineFunction("env", "callback", (Caller c) => { - var mem = c.GetMemory("memory"); + var mem = c.GetMemory("memory")!.Value; mem.ReadByte(10).Should().Be(20); mem.WriteByte(10, 21); @@ -90,7 +90,7 @@ public void ItCanReadAndWriteMemoryFromCaller() var callback = instance.GetFunction("call_callback")!; // Write a value into memory - var memory = instance.GetMemory("memory")!; + var memory = instance.GetMemory("memory")!.Value; memory.WriteByte(10, 20); // Callback checks that value and writes another @@ -116,7 +116,7 @@ public void ItCanReadAndWriteMemorySpanFromCaller() var callback = instance.GetFunction("call_callback")!; // Write a value into memory - var memory = instance.GetMemory("memory")!; + var memory = instance.GetMemory("memory")!.Value; memory.WriteByte(10, 20); // Callback checks that value and writes another diff --git a/tests/FunctionTests.cs b/tests/FunctionTests.cs index 5d04bcb..3ee5535 100644 --- a/tests/FunctionTests.cs +++ b/tests/FunctionTests.cs @@ -29,7 +29,7 @@ public FunctionTests(FunctionsFixture fixture) Linker.Define("env", "do_throw", Function.FromCallback(Store, () => throw new Exception(THROW_MESSAGE))); Linker.Define("env", "check_string", Function.FromCallback(Store, (Caller caller, int address, int length) => { - caller.GetMemory("mem").ReadString(address, length).Should().Be("Hello World"); + caller.GetMemory("mem")!.Value.ReadString(address, length).Should().Be("Hello World"); })); Linker.Define("env", "return_i32", Function.FromCallback(Store, GetBoundFuncIntDelegate())); diff --git a/tests/LinkerFunctionsTests.cs b/tests/LinkerFunctionsTests.cs index 91b830e..69b8ded 100644 --- a/tests/LinkerFunctionsTests.cs +++ b/tests/LinkerFunctionsTests.cs @@ -29,7 +29,7 @@ public LinkerFunctionTests(LinkerFunctionsFixture fixture) Linker.DefineFunction("env", "do_throw", () => throw new Exception(THROW_MESSAGE)); Linker.DefineFunction("env", "check_string", (Caller caller, int address, int length) => { - caller.GetMemory("mem").ReadString(address, length).Should().Be("Hello World"); + caller.GetMemory("mem")!.Value.ReadString(address, length).Should().Be("Hello World"); }); Linker.DefineFunction("env", "return_i32", GetBoundFuncIntDelegate()); diff --git a/tests/Memory64AccessTests.cs b/tests/Memory64AccessTests.cs index 015c8e9..11400e8 100644 --- a/tests/Memory64AccessTests.cs +++ b/tests/Memory64AccessTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using FluentAssertions; +using FluentAssertions.Execution; using Xunit; namespace Wasmtime.Tests @@ -34,7 +35,7 @@ public unsafe void ItCanAccessMemoryWith65537Pages() memoryExport.Is64Bit.Should().BeTrue(); var instance = Linker.Instantiate(Store, Fixture.Module); - var memory = instance.GetMemory("mem"); + var memory = instance.GetMemory("mem")!.Value; memory.Minimum.Should().Be(0x10001); memory.Maximum.Should().Be(0x1000000000000); @@ -75,7 +76,7 @@ public unsafe void ItCanAccessMemoryWith65537Pages() public void ItThrowsForOutOfBoundsAccess() { var instance = Linker.Instantiate(Store, Fixture.Module); - var memory = instance.GetMemory("mem"); + var memory = instance.GetMemory("mem")!.Value; #pragma warning disable CS0618 // Type or member is obsolete Action action = () => memory.GetSpan(); diff --git a/tests/MemoryAccessTests.cs b/tests/MemoryAccessTests.cs index 483eeda..3d68573 100644 --- a/tests/MemoryAccessTests.cs +++ b/tests/MemoryAccessTests.cs @@ -25,6 +25,14 @@ public MemoryAccessTests(MemoryAccessFixture fixture) Linker = new Linker(Fixture.Engine); } + [Fact] + public void AccessDefaultThrows() + { + var memory = default(Memory); + + Assert.Throws(() => memory.GetLength()); + } + [Fact] public void ItGrows() { @@ -67,7 +75,7 @@ public unsafe void ItCanAccessMemoryWith65536Pages() memoryExport.Is64Bit.Should().BeFalse(); var instance = Linker.Instantiate(Store, Fixture.Module); - var memory = instance.GetMemory("mem"); + var memory = instance.GetMemory("mem")!.Value; memory.Minimum.Should().Be(0x10000); memory.Maximum.Should().BeNull(); @@ -108,7 +116,7 @@ public unsafe void ItCanAccessMemoryWith65536Pages() public void ItThrowsForOutOfBoundsAccess() { var instance = Linker.Instantiate(Store, Fixture.Module); - var memory = instance.GetMemory("mem"); + var memory = instance.GetMemory("mem")!.Value; #pragma warning disable CS0618 // Type or member is obsolete Action action = () => memory.GetSpan(); diff --git a/tests/MemoryExportsTests.cs b/tests/MemoryExportsTests.cs index 8af11d9..321c481 100644 --- a/tests/MemoryExportsTests.cs +++ b/tests/MemoryExportsTests.cs @@ -57,9 +57,7 @@ public void ItHasTheExpectedNumberOfExportedTables() public void ItReadsAndWritesGenericTypes() { var instance = Linker.Instantiate(Store, Fixture.Module); - var memory = instance.GetMemory("mem"); - - memory.Should().NotBeNull(); + var memory = instance.GetMemory("mem")!.Value; memory.Write(11, new TestStruct { A = 17, B = -34346 }); var result = memory.Read(11); @@ -78,9 +76,7 @@ struct TestStruct public void ItCreatesExternsForTheMemories() { var instance = Linker.Instantiate(Store, Fixture.Module); - var memory = instance.GetMemory("mem"); - - memory.Should().NotBeNull(); + var memory = instance.GetMemory("mem")!.Value; memory.ReadString(0, 11).Should().Be("Hello World"); int written = memory.WriteString(0, "WebAssembly Rocks!"); diff --git a/tests/WasiTests.cs b/tests/WasiTests.cs index 1f2e845..dc88401 100644 --- a/tests/WasiTests.cs +++ b/tests/WasiTests.cs @@ -24,7 +24,7 @@ public void ItHasNoEnvironmentByDefault(string path) store.SetWasiConfiguration(new WasiConfiguration()); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_environ_sizes_get = instance.GetFunction("call_environ_sizes_get"); call_environ_sizes_get.Should().NotBeNull(); @@ -58,7 +58,7 @@ public void ItHasSpecifiedEnvironment(string path) store.SetWasiConfiguration(config); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_environ_sizes_get = instance.GetFunction("call_environ_sizes_get"); call_environ_sizes_get.Should().NotBeNull(); @@ -95,7 +95,7 @@ public void ItInheritsEnvironment(string path) store.SetWasiConfiguration(config); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_environ_sizes_get = instance.GetFunction("call_environ_sizes_get"); call_environ_sizes_get.Should().NotBeNull(); @@ -119,7 +119,7 @@ public void ItHasNoArgumentsByDefault(string path) store.SetWasiConfiguration(new WasiConfiguration()); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_args_sizes_get = instance.GetFunction("call_args_sizes_get"); call_args_sizes_get.Should().NotBeNull(); @@ -154,7 +154,7 @@ public void ItHasSpecifiedArguments(string path) store.SetWasiConfiguration(config); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_args_sizes_get = instance.GetFunction("call_args_sizes_get"); call_args_sizes_get.Should().NotBeNull(); @@ -191,7 +191,7 @@ public void ItInheritsArguments(string path) store.SetWasiConfiguration(config); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_args_sizes_get = instance.GetFunction("call_args_sizes_get"); call_args_sizes_get.Should().NotBeNull(); @@ -223,7 +223,7 @@ public void ItSetsStdIn(string path) store.SetWasiConfiguration(config); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_fd_read = instance.GetFunction("call_fd_read"); call_fd_read.Should().NotBeNull(); @@ -267,7 +267,7 @@ public void ItSetsStdOutAndStdErr(string path, int fd) store.SetWasiConfiguration(config); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_fd_write = instance.GetFunction("call_fd_write"); call_fd_write.Should().NotBeNull(); @@ -306,7 +306,7 @@ public void ItSetsPreopenDirectories(string path) store.SetWasiConfiguration(config); var instance = linker.Instantiate(store, module); - var memory = instance.GetMemory("memory"); + var memory = instance.GetMemory("memory")!.Value; memory.Should().NotBeNull(); var call_path_open = instance.GetFunction("call_path_open"); call_path_open.Should().NotBeNull(); From 7e2d02a8ae896e63271d8e9c89b1acfa7efcc841 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Wed, 15 Mar 2023 15:39:54 +0000 Subject: [PATCH 2/6] Fixed memory example --- examples/memory/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/memory/Program.cs b/examples/memory/Program.cs index d6d6705..174ec25 100644 --- a/examples/memory/Program.cs +++ b/examples/memory/Program.cs @@ -11,7 +11,7 @@ "log", Function.FromCallback(store, (Caller caller, int address, int length) => { - var message = caller.GetMemory("mem").ReadString(address, length); + var message = caller.GetMemory("mem")?.ReadString(address, length); Console.WriteLine($"Message from WebAssembly: {message}"); } )); From 8d5d2c26b6d94dec9ba4f7c51d6263c73d7ba2b3 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Tue, 28 Mar 2023 16:16:40 +0100 Subject: [PATCH 3/6] Skipped 3 tests, to debug macOS CI crash --- tests/MemoryAccessTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/MemoryAccessTests.cs b/tests/MemoryAccessTests.cs index 3d68573..588979f 100644 --- a/tests/MemoryAccessTests.cs +++ b/tests/MemoryAccessTests.cs @@ -25,7 +25,7 @@ public MemoryAccessTests(MemoryAccessFixture fixture) Linker = new Linker(Fixture.Engine); } - [Fact] + [Fact(Skip = "Test skip for MacOS CI crash")] public void AccessDefaultThrows() { var memory = default(Memory); From afabdd0f9e998baf490cedbe9652c0d50c32cfc4 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Tue, 28 Mar 2023 16:23:14 +0100 Subject: [PATCH 4/6] Removed one skip (debugging CI) --- tests/MemoryAccessTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/MemoryAccessTests.cs b/tests/MemoryAccessTests.cs index 588979f..ae8cc57 100644 --- a/tests/MemoryAccessTests.cs +++ b/tests/MemoryAccessTests.cs @@ -112,7 +112,7 @@ public unsafe void ItCanAccessMemoryWith65536Pages() memory.ReadString(0xFFFFFFFF - str1.Length, str1.Length).Should().Be(str1); } - [Fact] + [Fact(Skip = "Test skip for MacOS CI crash")] public void ItThrowsForOutOfBoundsAccess() { var instance = Linker.Instantiate(Store, Fixture.Module); From 616035e6da4ef6d59e9e35025f09f9bb9769777e Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Tue, 28 Mar 2023 16:30:53 +0100 Subject: [PATCH 5/6] Removed a test skip --- tests/MemoryAccessTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/MemoryAccessTests.cs b/tests/MemoryAccessTests.cs index ae8cc57..588979f 100644 --- a/tests/MemoryAccessTests.cs +++ b/tests/MemoryAccessTests.cs @@ -112,7 +112,7 @@ public unsafe void ItCanAccessMemoryWith65536Pages() memory.ReadString(0xFFFFFFFF - str1.Length, str1.Length).Should().Be(str1); } - [Fact(Skip = "Test skip for MacOS CI crash")] + [Fact] public void ItThrowsForOutOfBoundsAccess() { var instance = Linker.Instantiate(Store, Fixture.Module); From d15be1abb8bd673cb18fee676abeef99a63ceb09 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Tue, 28 Mar 2023 16:37:02 +0100 Subject: [PATCH 6/6] Added a single simple test that might crash the macOS test runner --- tests/MemoryAccessTests.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/MemoryAccessTests.cs b/tests/MemoryAccessTests.cs index 588979f..2bcd5bd 100644 --- a/tests/MemoryAccessTests.cs +++ b/tests/MemoryAccessTests.cs @@ -33,6 +33,22 @@ public void AccessDefaultThrows() Assert.Throws(() => memory.GetLength()); } + [Fact] + public void TestMacOsCI() + { + try + { + object? o = null; + o.Equals(o).Should().BeTrue(); + } + catch (NullReferenceException) + { + return; + } + + Assert.False(true); + } + [Fact] public void ItGrows() {