From 5561ec03c5af262263b75e71ade85263c4e33402 Mon Sep 17 00:00:00 2001 From: redradist Date: Sat, 2 May 2020 20:33:31 +0300 Subject: [PATCH 1/8] Added two methods for loading embedded .wasm and .wat --- src/Host.cs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/Host.cs b/src/Host.cs index 619c4d70..dd577909 100644 --- a/src/Host.cs +++ b/src/Host.cs @@ -2,6 +2,8 @@ using System.IO; using System.Text; using System.Collections.Generic; +using System.Linq; +using System.Reflection; using System.Runtime.InteropServices; namespace Wasmtime @@ -641,11 +643,61 @@ public Module LoadModuleText(string name, string text) /// /// The path to the WebAssembly text format file. /// Returns a new . - public Module LoadModuleText(string path) + public Module LoadModuleText(string path, bool isEmbedded=false) { return LoadModuleText(Path.GetFileNameWithoutExtension(path), File.ReadAllText(path)); } + public Module LoadEmbeddedModule(string resourceName) + { + var assembly = Assembly.GetCallingAssembly(); + var allResources = new List( + assembly.GetManifestResourceNames().Where(str => str.EndsWith(resourceName)) + ); + if (allResources.Count == 0) + { + throw new ArgumentException($"Could not find resource: {resourceName} !!"); + } + if (allResources.Count > 1) + { + throw new ArgumentException(@$"Found more than one resource with name {resourceName}: {allResources} !! Consider specify full path to resource ..."); + } + var assemblyResourceName = allResources.First(); + using (Stream stream = assembly.GetManifestResourceStream(assemblyResourceName)) + using (StreamReader reader = new StreamReader(stream)) + { + using (MemoryStream ms = new MemoryStream()) + { + reader.BaseStream.CopyTo(ms); + byte[] bytes = ms.ToArray(); + return new Module(Store, assemblyResourceName, bytes); + } + } + } + + public Module LoadEmbeddedModuleText(string resourceName) + { + var assembly = Assembly.GetCallingAssembly(); + var allResources = new List( + assembly.GetManifestResourceNames().Where(str => str.EndsWith(resourceName)) + ); + if (allResources.Count == 0) + { + throw new ArgumentException($"Could not find resource: {resourceName} !!"); + } + if (allResources.Count > 1) + { + throw new ArgumentException(@$"Found more than one resource with name {resourceName}: {allResources} !! Consider specify full path to resource ..."); + } + var assemblyResourceName = allResources.First(); + using (Stream stream = assembly.GetManifestResourceStream(assemblyResourceName)) + using (StreamReader reader = new StreamReader(stream)) + { + string text = reader.ReadToEnd(); + return LoadModuleText(assemblyResourceName, text); + } + } + /// /// Instantiates a WebAssembly module. /// From 1bb1b710fa68c0b2ef7c7cc220ce6e59207fc714 Mon Sep 17 00:00:00 2001 From: redradist Date: Sat, 2 May 2020 20:35:03 +0300 Subject: [PATCH 2/8] Reverted change in LoadModuleText --- src/Host.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Host.cs b/src/Host.cs index dd577909..c66f5555 100644 --- a/src/Host.cs +++ b/src/Host.cs @@ -643,7 +643,7 @@ public Module LoadModuleText(string name, string text) /// /// The path to the WebAssembly text format file. /// Returns a new . - public Module LoadModuleText(string path, bool isEmbedded=false) + public Module LoadModuleText(string path) { return LoadModuleText(Path.GetFileNameWithoutExtension(path), File.ReadAllText(path)); } From 87ffee163a520dfd88c7fa96f4f665d5d9f7e35d Mon Sep 17 00:00:00 2001 From: redradist Date: Sat, 2 May 2020 20:43:55 +0300 Subject: [PATCH 3/8] Removed in name of module extension --- src/Host.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Host.cs b/src/Host.cs index c66f5555..b742d074 100644 --- a/src/Host.cs +++ b/src/Host.cs @@ -670,7 +670,7 @@ public Module LoadEmbeddedModule(string resourceName) { reader.BaseStream.CopyTo(ms); byte[] bytes = ms.ToArray(); - return new Module(Store, assemblyResourceName, bytes); + return new Module(Store, Path.GetFileNameWithoutExtension(assemblyResourceName), bytes); } } } @@ -694,7 +694,7 @@ public Module LoadEmbeddedModuleText(string resourceName) using (StreamReader reader = new StreamReader(stream)) { string text = reader.ReadToEnd(); - return LoadModuleText(assemblyResourceName, text); + return LoadModuleText(Path.GetFileNameWithoutExtension(assemblyResourceName), text); } } From ce805f37d6a85d0f22da70004f371cedc4d3d76b Mon Sep 17 00:00:00 2001 From: redradist Date: Sun, 17 May 2020 21:31:40 +0300 Subject: [PATCH 4/8] Small changes in src/Host.cs --- src/Host.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Host.cs b/src/Host.cs index b742d074..02158bb2 100644 --- a/src/Host.cs +++ b/src/Host.cs @@ -670,7 +670,7 @@ public Module LoadEmbeddedModule(string resourceName) { reader.BaseStream.CopyTo(ms); byte[] bytes = ms.ToArray(); - return new Module(Store, Path.GetFileNameWithoutExtension(assemblyResourceName), bytes); + return LoadModule(Path.GetFileNameWithoutExtension(assemblyResourceName), bytes); } } } From 7bbd7e1e280e684f9548c725dab83ea7d2de489a Mon Sep 17 00:00:00 2001 From: redradist Date: Tue, 19 May 2020 18:36:44 +0300 Subject: [PATCH 5/8] First iteration for test --- tests/Fixtures/ModuleFixture.cs | 11 ++++++++++- tests/Wasmtime.Tests.csproj | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/Fixtures/ModuleFixture.cs b/tests/Fixtures/ModuleFixture.cs index 7c2b840b..e4663fdb 100644 --- a/tests/Fixtures/ModuleFixture.cs +++ b/tests/Fixtures/ModuleFixture.cs @@ -13,7 +13,9 @@ public ModuleFixture() .WithReferenceTypes(true) .Build(); - Module = Host.LoadModuleText(Path.Combine("Modules", ModuleFileName)); + var modulePath = Path.Combine("Modules", ModuleFileName); + Module = Host.LoadModuleText(modulePath); + EmbeddedModule = Host.LoadEmbeddedModuleText(modulePath); } public void Dispose() @@ -24,6 +26,12 @@ public void Dispose() Module = null; } + if (!(EmbeddedModule is null)) + { + EmbeddedModule.Dispose(); + EmbeddedModule = null; + } + if (!(Host is null)) { Host.Dispose(); @@ -33,6 +41,7 @@ public void Dispose() public Host Host { get; set; } public Module Module { get; set; } + public Module EmbeddedModule { get; set; } protected abstract string ModuleFileName { get; } } diff --git a/tests/Wasmtime.Tests.csproj b/tests/Wasmtime.Tests.csproj index ee1f462a..41b172f8 100644 --- a/tests/Wasmtime.Tests.csproj +++ b/tests/Wasmtime.Tests.csproj @@ -19,6 +19,7 @@ + - + From 8b2feb3f7c6d174c802f3b87ce684ea092f97d05 Mon Sep 17 00:00:00 2001 From: redradist Date: Thu, 18 Jun 2020 23:07:59 +0300 Subject: [PATCH 6/8] Changed API to accept Stream --- src/Host.cs | 72 +++++++++++++-------------------- tests/Fixtures/ModuleFixture.cs | 13 +++--- tests/Wasmtime.Tests.csproj | 2 +- 3 files changed, 36 insertions(+), 51 deletions(-) diff --git a/src/Host.cs b/src/Host.cs index 02158bb2..404f593b 100644 --- a/src/Host.cs +++ b/src/Host.cs @@ -595,6 +595,24 @@ public Module LoadModule(string path) return LoadModule(Path.GetFileNameWithoutExtension(path), File.ReadAllBytes(path)); } + /// + /// Loads a given stream as WebAssembly. + /// + /// Name of the module + /// Stream with module data + /// Returns a new . + public Module LoadModule(string moduleName, Stream moduleStream) + { + using (StreamReader reader = new StreamReader(moduleStream)) + { + using (MemoryStream ms = new MemoryStream()) + { + reader.BaseStream.CopyTo(ms); + return LoadModule(moduleName, ms.ToArray()); + } + } + } + /// /// Loads a based on a WebAssembly text format representation. /// @@ -648,53 +666,17 @@ public Module LoadModuleText(string path) return LoadModuleText(Path.GetFileNameWithoutExtension(path), File.ReadAllText(path)); } - public Module LoadEmbeddedModule(string resourceName) - { - var assembly = Assembly.GetCallingAssembly(); - var allResources = new List( - assembly.GetManifestResourceNames().Where(str => str.EndsWith(resourceName)) - ); - if (allResources.Count == 0) - { - throw new ArgumentException($"Could not find resource: {resourceName} !!"); - } - if (allResources.Count > 1) - { - throw new ArgumentException(@$"Found more than one resource with name {resourceName}: {allResources} !! Consider specify full path to resource ..."); - } - var assemblyResourceName = allResources.First(); - using (Stream stream = assembly.GetManifestResourceStream(assemblyResourceName)) - using (StreamReader reader = new StreamReader(stream)) - { - using (MemoryStream ms = new MemoryStream()) - { - reader.BaseStream.CopyTo(ms); - byte[] bytes = ms.ToArray(); - return LoadModule(Path.GetFileNameWithoutExtension(assemblyResourceName), bytes); - } - } - } - - public Module LoadEmbeddedModuleText(string resourceName) + /// + /// Loads a given stream as WebAssembly text format stream. + /// + /// Name of the module + /// WebAssembly text format stream with module data + /// Returns a new . + public Module LoadModuleText(string moduleName, Stream moduleStream) { - var assembly = Assembly.GetCallingAssembly(); - var allResources = new List( - assembly.GetManifestResourceNames().Where(str => str.EndsWith(resourceName)) - ); - if (allResources.Count == 0) - { - throw new ArgumentException($"Could not find resource: {resourceName} !!"); - } - if (allResources.Count > 1) - { - throw new ArgumentException(@$"Found more than one resource with name {resourceName}: {allResources} !! Consider specify full path to resource ..."); - } - var assemblyResourceName = allResources.First(); - using (Stream stream = assembly.GetManifestResourceStream(assemblyResourceName)) - using (StreamReader reader = new StreamReader(stream)) + using (StreamReader reader = new StreamReader(moduleStream)) { - string text = reader.ReadToEnd(); - return LoadModuleText(Path.GetFileNameWithoutExtension(assemblyResourceName), text); + return LoadModuleText(moduleName, reader.ReadToEnd()); } } diff --git a/tests/Fixtures/ModuleFixture.cs b/tests/Fixtures/ModuleFixture.cs index e4663fdb..21604363 100644 --- a/tests/Fixtures/ModuleFixture.cs +++ b/tests/Fixtures/ModuleFixture.cs @@ -15,7 +15,10 @@ public ModuleFixture() var modulePath = Path.Combine("Modules", ModuleFileName); Module = Host.LoadModuleText(modulePath); - EmbeddedModule = Host.LoadEmbeddedModuleText(modulePath); + using (FileStream fs = File.OpenRead(modulePath)) + { + StreamModule = Host.LoadModuleText(modulePath, fs); + } } public void Dispose() @@ -26,10 +29,10 @@ public void Dispose() Module = null; } - if (!(EmbeddedModule is null)) + if (!(StreamModule is null)) { - EmbeddedModule.Dispose(); - EmbeddedModule = null; + StreamModule.Dispose(); + StreamModule = null; } if (!(Host is null)) @@ -41,7 +44,7 @@ public void Dispose() public Host Host { get; set; } public Module Module { get; set; } - public Module EmbeddedModule { get; set; } + public Module StreamModule { get; set; } protected abstract string ModuleFileName { get; } } diff --git a/tests/Wasmtime.Tests.csproj b/tests/Wasmtime.Tests.csproj index 41b172f8..7ca33398 100644 --- a/tests/Wasmtime.Tests.csproj +++ b/tests/Wasmtime.Tests.csproj @@ -19,7 +19,7 @@ - + From 4d9678f361991521d8214bba9a6a47425026c75b Mon Sep 17 00:00:00 2001 From: redradist Date: Thu, 25 Jun 2020 21:05:40 +0300 Subject: [PATCH 7/8] Updated implementation of LoadModule and LoadModuleText as was suggested --- src/Host.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/Host.cs b/src/Host.cs index 404f593b..44415611 100644 --- a/src/Host.cs +++ b/src/Host.cs @@ -603,14 +603,9 @@ public Module LoadModule(string path) /// Returns a new . public Module LoadModule(string moduleName, Stream moduleStream) { - using (StreamReader reader = new StreamReader(moduleStream)) - { - using (MemoryStream ms = new MemoryStream()) - { - reader.BaseStream.CopyTo(ms); - return LoadModule(moduleName, ms.ToArray()); - } - } + byte[] byteArray = new byte[moduleStream.Length]; + moduleStream.Read(byteArray); + return LoadModule(moduleName, byteArray); } /// @@ -674,10 +669,9 @@ public Module LoadModuleText(string path) /// Returns a new . public Module LoadModuleText(string moduleName, Stream moduleStream) { - using (StreamReader reader = new StreamReader(moduleStream)) - { - return LoadModuleText(moduleName, reader.ReadToEnd()); - } + byte[] byteArray = new byte[moduleStream.Length]; + moduleStream.Read(byteArray); + return LoadModuleText(moduleName, Encoding.UTF8.GetString(byteArray, 0, byteArray.Length)); } /// From cea0d9fce53d02071d91a8c1dc97ba917a774c5c Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 25 Jun 2020 12:33:19 -0700 Subject: [PATCH 8/8] Minor code cleanup and add test to load module from embedded resource. A minor cleanup to the new overloads of `LoadModule` and `LoadModuleText`. Added test cases to cover loading a module from an embedded resource stream. --- src/Host.cs | 48 +++++++++++++++++++++----------- tests/Fixtures/ModuleFixture.cs | 14 +--------- tests/ModuleLoadTests.cs | 31 +++++++++++++++++++++ tests/Modules/hello.wasm | Bin 0 -> 47 bytes tests/Modules/hello.wat | 8 ++++++ tests/Wasmtime.Tests.csproj | 5 ++-- 6 files changed, 75 insertions(+), 31 deletions(-) create mode 100644 tests/ModuleLoadTests.cs create mode 100644 tests/Modules/hello.wasm create mode 100644 tests/Modules/hello.wat diff --git a/src/Host.cs b/src/Host.cs index 44415611..b93d7de2 100644 --- a/src/Host.cs +++ b/src/Host.cs @@ -2,9 +2,6 @@ using System.IO; using System.Text; using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; namespace Wasmtime { @@ -596,16 +593,26 @@ public Module LoadModule(string path) } /// - /// Loads a given stream as WebAssembly. + /// Loads a given a stream. /// - /// Name of the module - /// Stream with module data + /// The name of the module. + /// The stream of the module data. /// Returns a new . - public Module LoadModule(string moduleName, Stream moduleStream) + public Module LoadModule(string name, Stream stream) { - byte[] byteArray = new byte[moduleStream.Length]; - moduleStream.Read(byteArray); - return LoadModule(moduleName, byteArray); + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + + if (stream is null) + { + throw new ArgumentNullException(nameof(stream)); + } + + using var ms = new MemoryStream(); + stream.CopyTo(ms); + return LoadModule(name, ms.ToArray()); } /// @@ -664,14 +671,23 @@ public Module LoadModuleText(string path) /// /// Loads a given stream as WebAssembly text format stream. /// - /// Name of the module - /// WebAssembly text format stream with module data + /// The name of the module. + /// The stream of the module data. /// Returns a new . - public Module LoadModuleText(string moduleName, Stream moduleStream) + public Module LoadModuleText(string name, Stream stream) { - byte[] byteArray = new byte[moduleStream.Length]; - moduleStream.Read(byteArray); - return LoadModuleText(moduleName, Encoding.UTF8.GetString(byteArray, 0, byteArray.Length)); + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + + if (stream is null) + { + throw new ArgumentNullException(nameof(stream)); + } + + using var reader = new StreamReader(stream); + return LoadModuleText(name, reader.ReadToEnd()); } /// diff --git a/tests/Fixtures/ModuleFixture.cs b/tests/Fixtures/ModuleFixture.cs index 21604363..7c2b840b 100644 --- a/tests/Fixtures/ModuleFixture.cs +++ b/tests/Fixtures/ModuleFixture.cs @@ -13,12 +13,7 @@ public ModuleFixture() .WithReferenceTypes(true) .Build(); - var modulePath = Path.Combine("Modules", ModuleFileName); - Module = Host.LoadModuleText(modulePath); - using (FileStream fs = File.OpenRead(modulePath)) - { - StreamModule = Host.LoadModuleText(modulePath, fs); - } + Module = Host.LoadModuleText(Path.Combine("Modules", ModuleFileName)); } public void Dispose() @@ -29,12 +24,6 @@ public void Dispose() Module = null; } - if (!(StreamModule is null)) - { - StreamModule.Dispose(); - StreamModule = null; - } - if (!(Host is null)) { Host.Dispose(); @@ -44,7 +33,6 @@ public void Dispose() public Host Host { get; set; } public Module Module { get; set; } - public Module StreamModule { get; set; } protected abstract string ModuleFileName { get; } } diff --git a/tests/ModuleLoadTests.cs b/tests/ModuleLoadTests.cs new file mode 100644 index 00000000..efebe5f5 --- /dev/null +++ b/tests/ModuleLoadTests.cs @@ -0,0 +1,31 @@ +using System; +using System.Reflection; +using FluentAssertions; +using Wasmtime; +using Xunit; + +namespace Wasmtime.Tests +{ + public class ModuleLoadTests + { + [Fact] + public void ItLoadsModuleFromEmbeddedResource() + { + using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("hello.wasm"); + stream.Should().NotBeNull(); + + using var host = new Host(); + host.LoadModule("hello.wasm", stream).Should().NotBeNull(); + } + + [Fact] + public void ItLoadsModuleTextFromEmbeddedResource() + { + using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("hello.wat"); + stream.Should().NotBeNull(); + + using var host = new Host(); + host.LoadModuleText("hello.wat", stream).Should().NotBeNull(); + } + } +} diff --git a/tests/Modules/hello.wasm b/tests/Modules/hello.wasm new file mode 100644 index 0000000000000000000000000000000000000000..dbc6d58cb17eb2fc852b806ba726a718d6573089 GIT binary patch literal 47 zcmZQbEY4+QU|?WmVN76PVB%tAV9iL)$;oG6U}j=uU}tA!E-KAqVB}(BWML3s;06GZ Cwgqhf literal 0 HcmV?d00001 diff --git a/tests/Modules/hello.wat b/tests/Modules/hello.wat new file mode 100644 index 00000000..f7fb8df1 --- /dev/null +++ b/tests/Modules/hello.wat @@ -0,0 +1,8 @@ +(module + (type $t0 (func)) + (import "" "hello" (func $.hello (type $t0))) + (func $run + call $.hello + ) + (export "run" (func $run)) +) diff --git a/tests/Wasmtime.Tests.csproj b/tests/Wasmtime.Tests.csproj index 7ca33398..9d82fd3c 100644 --- a/tests/Wasmtime.Tests.csproj +++ b/tests/Wasmtime.Tests.csproj @@ -19,7 +19,8 @@ - + + - +