diff --git a/Cargo.lock b/Cargo.lock index aaf50dba6c..79865b4ccb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2263,6 +2263,7 @@ dependencies = [ "wasi-common", "wasmtime", "wasmtime-wasi", + "wat", ] [[package]] diff --git a/crates/c-api/Cargo.toml b/crates/c-api/Cargo.toml index 3b17fcce03..e489843651 100644 --- a/crates/c-api/Cargo.toml +++ b/crates/c-api/Cargo.toml @@ -20,3 +20,4 @@ doctest = false wasmtime = { path = "../api" } wasi-common = { path = "../wasi-common" } wasmtime-wasi = { path = "../wasi" } +wat = "1.0" diff --git a/crates/c-api/include/wasmtime.h b/crates/c-api/include/wasmtime.h index 16b463bb5a..f5f2d4df54 100644 --- a/crates/c-api/include/wasmtime.h +++ b/crates/c-api/include/wasmtime.h @@ -38,6 +38,26 @@ WASMTIME_CONFIG_PROP(cranelift_opt_level, wasmtime_opt_level_t) /////////////////////////////////////////////////////////////////////////////// +// Converts from the text format of WebAssembly to to the binary format. +// +// * `engine` - a previously created engine which will drive allocations and +// such +// * `wat` - this it the input buffer with the WebAssembly Text Format inside of +// it. This will be parsed and converted to the binary format. +// * `ret` - if the conversion is successful, this byte vector is filled in with +// the WebAssembly binary format. +// * `error_message` - if the conversion fails, this is filled in with a +// descriptive error message of why parsing failed. This parameter is +// optional. +// +// Returns `true` if conversion succeeded, or `false` if it failed. +bool wasmtime_wat2wasm( + wasm_engine_t *engine, + const wasm_byte_vec_t *wat, + own wasm_byte_vec_t *ret, + own wasm_byte_vec_t *error_message, +); + #ifdef __cplusplus } // extern "C" #endif diff --git a/crates/c-api/src/ext.rs b/crates/c-api/src/ext.rs index 549bb1e604..c61e7ad07d 100644 --- a/crates/c-api/src/ext.rs +++ b/crates/c-api/src/ext.rs @@ -1,7 +1,8 @@ //! This file defines the extern "C" API extension, which are specific //! to the wasmtime implementation. -use crate::wasm_config_t; +use crate::{wasm_byte_vec_t, wasm_config_t, wasm_engine_t}; +use std::str; use wasmtime::{OptLevel, Strategy}; #[repr(u8)] @@ -86,3 +87,33 @@ pub unsafe extern "C" fn wasmtime_config_cranelift_opt_level_set( WASMTIME_OPT_LEVEL_SPEED_AND_SIZE => OptLevel::SpeedAndSize, }); } + +#[no_mangle] +pub unsafe extern "C" fn wasmtime_wat2wasm( + _engine: *mut wasm_engine_t, + wat: *const wasm_byte_vec_t, + ret: *mut wasm_byte_vec_t, + error: *mut wasm_byte_vec_t, +) -> bool { + let wat = match str::from_utf8((*wat).as_slice()) { + Ok(s) => s, + Err(_) => { + if !error.is_null() { + (*error).set_from_slice(b"input was not valid utf-8"); + } + return false; + } + }; + match wat::parse_str(wat) { + Ok(bytes) => { + (*ret).set_from_slice(&bytes); + true + } + Err(e) => { + if !error.is_null() { + (*error).set_from_slice(e.to_string().as_bytes()); + } + false + } + } +} diff --git a/crates/misc/dotnet/src/Engine.cs b/crates/misc/dotnet/src/Engine.cs index 575e94e9bd..bc7a26106c 100644 --- a/crates/misc/dotnet/src/Engine.cs +++ b/crates/misc/dotnet/src/Engine.cs @@ -1,4 +1,6 @@ using System; +using System.Text; +using System.Runtime.InteropServices; namespace Wasmtime { @@ -40,6 +42,34 @@ namespace Wasmtime return new Store(this); } + /// + /// Converts the WebAssembly text format to the binary format + /// + /// Returns the binary-encoded wasm module. + public byte[] WatToWasm(string wat) + { + var watBytes = Encoding.UTF8.GetBytes(wat); + unsafe + { + fixed (byte *ptr = watBytes) + { + Interop.wasm_byte_vec_t watByteVec; + watByteVec.size = (UIntPtr)watBytes.Length; + watByteVec.data = ptr; + if (!Interop.wasmtime_wat2wasm(Handle, ref watByteVec, out var bytes, out var error)) { + var errorSpan = new ReadOnlySpan(error.data, checked((int)error.size)); + var message = Encoding.UTF8.GetString(errorSpan); + Interop.wasm_byte_vec_delete(ref error); + throw new WasmtimeException("failed to parse input wat: " + message); + } + var byteSpan = new ReadOnlySpan(bytes.data, checked((int)bytes.size)); + var ret = byteSpan.ToArray(); + Interop.wasm_byte_vec_delete(ref bytes); + return ret; + } + } + } + /// public void Dispose() { diff --git a/crates/misc/dotnet/src/Interop.cs b/crates/misc/dotnet/src/Interop.cs index 24baac04e3..877b5efd88 100644 --- a/crates/misc/dotnet/src/Interop.cs +++ b/crates/misc/dotnet/src/Interop.cs @@ -899,7 +899,7 @@ namespace Wasmtime public static extern bool wasi_config_set_stdin_file( WasiConfigHandle config, [MarshalAs(UnmanagedType.LPUTF8Str)] string path - ); + ); [DllImport(LibraryName)] public static extern void wasi_config_inherit_stdin(WasiConfigHandle config); @@ -909,7 +909,7 @@ namespace Wasmtime public static extern bool wasi_config_set_stdout_file( WasiConfigHandle config, [MarshalAs(UnmanagedType.LPUTF8Str)] string path - ); + ); [DllImport(LibraryName)] public static extern void wasi_config_inherit_stdout(WasiConfigHandle config); @@ -919,7 +919,7 @@ namespace Wasmtime public static extern bool wasi_config_set_stderr_file( WasiConfigHandle config, [MarshalAs(UnmanagedType.LPUTF8Str)] string path - ); + ); [DllImport(LibraryName)] public static extern void wasi_config_inherit_stderr(WasiConfigHandle config); @@ -974,5 +974,14 @@ namespace Wasmtime [DllImport(LibraryName)] public static extern void wasmtime_config_cranelift_opt_level_set(WasmConfigHandle config, wasmtime_opt_level_t level); + + [DllImport(LibraryName, CharSet=CharSet.Ansi)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool wasmtime_wat2wasm( + EngineHandle engine, + ref wasm_byte_vec_t wat, + out wasm_byte_vec_t vec, + out wasm_byte_vec_t error_message + ); } } diff --git a/crates/misc/dotnet/src/Module.cs b/crates/misc/dotnet/src/Module.cs index 203e5f7a6a..ac520cebe0 100644 --- a/crates/misc/dotnet/src/Module.cs +++ b/crates/misc/dotnet/src/Module.cs @@ -15,15 +15,13 @@ namespace Wasmtime throw new ArgumentNullException(nameof(store)); } - var bytesHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); - - try + unsafe { - unsafe + fixed (byte *ptr = bytes) { Interop.wasm_byte_vec_t vec; vec.size = (UIntPtr)bytes.Length; - vec.data = (byte*)bytesHandle.AddrOfPinnedObject(); + vec.data = ptr; Handle = Interop.wasm_module_new(store.Handle, ref vec); } @@ -33,10 +31,6 @@ namespace Wasmtime throw new WasmtimeException($"WebAssembly module '{name}' is not valid."); } } - finally - { - bytesHandle.Free(); - } Store = store; Name = name; diff --git a/crates/misc/dotnet/tests/Fixtures/ModuleFixture.cs b/crates/misc/dotnet/tests/Fixtures/ModuleFixture.cs index d3a08a6dce..2eeb9f7482 100644 --- a/crates/misc/dotnet/tests/Fixtures/ModuleFixture.cs +++ b/crates/misc/dotnet/tests/Fixtures/ModuleFixture.cs @@ -13,7 +13,9 @@ namespace Wasmtime.Tests .WithReferenceTypes(true) .Build(); Store = Engine.CreateStore(); - Module = Store.CreateModule(Path.Combine("Modules", ModuleFileName)); + var wat = Path.Combine("Modules", ModuleFileName); + var wasm = Engine.WatToWasm(File.ReadAllText(wat)); + Module = Store.CreateModule(wat, wasm); } public void Dispose() diff --git a/crates/misc/dotnet/tests/FunctionExportsTests.cs b/crates/misc/dotnet/tests/FunctionExportsTests.cs index 01d0929216..ff06f14d5c 100644 --- a/crates/misc/dotnet/tests/FunctionExportsTests.cs +++ b/crates/misc/dotnet/tests/FunctionExportsTests.cs @@ -8,7 +8,7 @@ namespace Wasmtime.Tests { public class FunctionExportsFixture : ModuleFixture { - protected override string ModuleFileName => "FunctionExports.wasm"; + protected override string ModuleFileName => "FunctionExports.wat"; } public class FunctionExportsTests : IClassFixture diff --git a/crates/misc/dotnet/tests/FunctionImportsTests.cs b/crates/misc/dotnet/tests/FunctionImportsTests.cs index bb2bdff302..bb90ad5d7b 100644 --- a/crates/misc/dotnet/tests/FunctionImportsTests.cs +++ b/crates/misc/dotnet/tests/FunctionImportsTests.cs @@ -8,7 +8,7 @@ namespace Wasmtime.Tests { public class FunctionImportsFixture : ModuleFixture { - protected override string ModuleFileName => "FunctionImports.wasm"; + protected override string ModuleFileName => "FunctionImports.wat"; } public class FunctionImportsTests : IClassFixture diff --git a/crates/misc/dotnet/tests/FunctionThunkingTests.cs b/crates/misc/dotnet/tests/FunctionThunkingTests.cs index 97eba2a299..116c2c65be 100644 --- a/crates/misc/dotnet/tests/FunctionThunkingTests.cs +++ b/crates/misc/dotnet/tests/FunctionThunkingTests.cs @@ -7,7 +7,7 @@ namespace Wasmtime.Tests { public class FunctionThunkingFixture : ModuleFixture { - protected override string ModuleFileName => "FunctionThunking.wasm"; + protected override string ModuleFileName => "FunctionThunking.wat"; } public class FunctionThunkingTests : IClassFixture diff --git a/crates/misc/dotnet/tests/GlobalExportsTests.cs b/crates/misc/dotnet/tests/GlobalExportsTests.cs index ca143f7286..8dc67f254c 100644 --- a/crates/misc/dotnet/tests/GlobalExportsTests.cs +++ b/crates/misc/dotnet/tests/GlobalExportsTests.cs @@ -10,7 +10,7 @@ namespace Wasmtime.Tests { public class GlobalExportsFixture : ModuleFixture { - protected override string ModuleFileName => "GlobalExports.wasm"; + protected override string ModuleFileName => "GlobalExports.wat"; } public class GlobalExportsTests : IClassFixture diff --git a/crates/misc/dotnet/tests/GlobalImportBindingTests.cs b/crates/misc/dotnet/tests/GlobalImportBindingTests.cs index 7969a90641..c87a9d3b51 100644 --- a/crates/misc/dotnet/tests/GlobalImportBindingTests.cs +++ b/crates/misc/dotnet/tests/GlobalImportBindingTests.cs @@ -6,7 +6,7 @@ namespace Wasmtime.Tests { public class GlobalImportBindingFixture : ModuleFixture { - protected override string ModuleFileName => "GlobalImportBindings.wasm"; + protected override string ModuleFileName => "GlobalImportBindings.wat"; } public class GlobalImportBindingTests : IClassFixture diff --git a/crates/misc/dotnet/tests/GlobalImportsTests.cs b/crates/misc/dotnet/tests/GlobalImportsTests.cs index 2479baf132..4087b503ce 100644 --- a/crates/misc/dotnet/tests/GlobalImportsTests.cs +++ b/crates/misc/dotnet/tests/GlobalImportsTests.cs @@ -8,7 +8,7 @@ namespace Wasmtime.Tests { public class GlobalImportsFixture : ModuleFixture { - protected override string ModuleFileName => "GlobalImports.wasm"; + protected override string ModuleFileName => "GlobalImports.wat"; } public class GlobalImportsTests : IClassFixture diff --git a/crates/misc/dotnet/tests/MemoryExportsTests.cs b/crates/misc/dotnet/tests/MemoryExportsTests.cs index 08242e75c7..30035e21e4 100644 --- a/crates/misc/dotnet/tests/MemoryExportsTests.cs +++ b/crates/misc/dotnet/tests/MemoryExportsTests.cs @@ -8,7 +8,7 @@ namespace Wasmtime.Tests { public class MemoryExportsFixture : ModuleFixture { - protected override string ModuleFileName => "MemoryExports.wasm"; + protected override string ModuleFileName => "MemoryExports.wat"; } public class MemoryExportsTests : IClassFixture diff --git a/crates/misc/dotnet/tests/MemoryImportBindingTests.cs b/crates/misc/dotnet/tests/MemoryImportBindingTests.cs index cab85e2434..6b59064c95 100644 --- a/crates/misc/dotnet/tests/MemoryImportBindingTests.cs +++ b/crates/misc/dotnet/tests/MemoryImportBindingTests.cs @@ -6,7 +6,7 @@ namespace Wasmtime.Tests { public class MemoryImportBindingFixture : ModuleFixture { - protected override string ModuleFileName => "MemoryImportBinding.wasm"; + protected override string ModuleFileName => "MemoryImportBinding.wat"; } public class MemoryImportBindingTests : IClassFixture diff --git a/crates/misc/dotnet/tests/MemoryImportFromModuleTests.cs b/crates/misc/dotnet/tests/MemoryImportFromModuleTests.cs index b47da19374..6396f4c87c 100644 --- a/crates/misc/dotnet/tests/MemoryImportFromModuleTests.cs +++ b/crates/misc/dotnet/tests/MemoryImportFromModuleTests.cs @@ -6,7 +6,7 @@ namespace Wasmtime.Tests { public class MemoryImportFromModuleFixture : ModuleFixture { - protected override string ModuleFileName => "MemoryImportFromModule.wasm"; + protected override string ModuleFileName => "MemoryImportFromModule.wat"; } public class MemoryImportFromModuleTests : IClassFixture diff --git a/crates/misc/dotnet/tests/MemoryImportNoUpperBoundTests.cs b/crates/misc/dotnet/tests/MemoryImportNoUpperBoundTests.cs index 8a9586bd28..47e1ebc042 100644 --- a/crates/misc/dotnet/tests/MemoryImportNoUpperBoundTests.cs +++ b/crates/misc/dotnet/tests/MemoryImportNoUpperBoundTests.cs @@ -6,7 +6,7 @@ namespace Wasmtime.Tests { public class MemoryImportNoUpperBoundFixture : ModuleFixture { - protected override string ModuleFileName => "MemoryImportNoUpperBound.wasm"; + protected override string ModuleFileName => "MemoryImportNoUpperBound.wat"; } public class MemoryImportNoUpperBoundTests : IClassFixture diff --git a/crates/misc/dotnet/tests/MemoryImportWithUpperBoundTests.cs b/crates/misc/dotnet/tests/MemoryImportWithUpperBoundTests.cs index ec73d9da21..0dc9791160 100644 --- a/crates/misc/dotnet/tests/MemoryImportWithUpperBoundTests.cs +++ b/crates/misc/dotnet/tests/MemoryImportWithUpperBoundTests.cs @@ -6,7 +6,7 @@ namespace Wasmtime.Tests { public class MemoryImportWithUpperBoundFixture : ModuleFixture { - protected override string ModuleFileName => "MemoryImportWithUpperBound.wasm"; + protected override string ModuleFileName => "MemoryImportWithUpperBound.wat"; } public class MemoryImportWithUpperBoundTests : IClassFixture diff --git a/crates/misc/dotnet/tests/Modules/FunctionExports.wasm b/crates/misc/dotnet/tests/Modules/FunctionExports.wasm deleted file mode 100644 index 73e90b1387..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/FunctionExports.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/FunctionImports.wasm b/crates/misc/dotnet/tests/Modules/FunctionImports.wasm deleted file mode 100644 index f52c32c22f..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/FunctionImports.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/FunctionThunking.wasm b/crates/misc/dotnet/tests/Modules/FunctionThunking.wasm deleted file mode 100644 index a8a67acb1c..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/FunctionThunking.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/GlobalExports.wasm b/crates/misc/dotnet/tests/Modules/GlobalExports.wasm deleted file mode 100644 index 9e9f358fc5..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/GlobalExports.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/GlobalImportBindings.wasm b/crates/misc/dotnet/tests/Modules/GlobalImportBindings.wasm deleted file mode 100644 index 8933739d65..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/GlobalImportBindings.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/GlobalImports.wasm b/crates/misc/dotnet/tests/Modules/GlobalImports.wasm deleted file mode 100644 index 5a80fbf3e9..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/GlobalImports.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/MemoryExports.wasm b/crates/misc/dotnet/tests/Modules/MemoryExports.wasm deleted file mode 100644 index bc0fe01a33..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/MemoryExports.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/MemoryImportBinding.wasm b/crates/misc/dotnet/tests/Modules/MemoryImportBinding.wasm deleted file mode 100644 index 83e5604526..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/MemoryImportBinding.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/MemoryImportFromModule.wasm b/crates/misc/dotnet/tests/Modules/MemoryImportFromModule.wasm deleted file mode 100644 index 73e12cb7cf..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/MemoryImportFromModule.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/MemoryImportNoUpperBound.wasm b/crates/misc/dotnet/tests/Modules/MemoryImportNoUpperBound.wasm deleted file mode 100644 index 813fefe664..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/MemoryImportNoUpperBound.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/MemoryImportWithUpperBound.wasm b/crates/misc/dotnet/tests/Modules/MemoryImportWithUpperBound.wasm deleted file mode 100644 index 0776ce28e2..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/MemoryImportWithUpperBound.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/TableExports.wasm b/crates/misc/dotnet/tests/Modules/TableExports.wasm deleted file mode 100644 index 8581e98b95..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/TableExports.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/TableImports.wasm b/crates/misc/dotnet/tests/Modules/TableImports.wasm deleted file mode 100644 index 0bb86637f4..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/TableImports.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/Modules/Wasi.wasm b/crates/misc/dotnet/tests/Modules/Wasi.wasm deleted file mode 100644 index 62644ebfed..0000000000 Binary files a/crates/misc/dotnet/tests/Modules/Wasi.wasm and /dev/null differ diff --git a/crates/misc/dotnet/tests/TableExportsTests.cs b/crates/misc/dotnet/tests/TableExportsTests.cs index ebd86658c6..bacc818b93 100644 --- a/crates/misc/dotnet/tests/TableExportsTests.cs +++ b/crates/misc/dotnet/tests/TableExportsTests.cs @@ -8,7 +8,7 @@ namespace Wasmtime.Tests { public class TableExportsFixture : ModuleFixture { - protected override string ModuleFileName => "TableExports.wasm"; + protected override string ModuleFileName => "TableExports.wat"; } public class TableExportsTests : IClassFixture diff --git a/crates/misc/dotnet/tests/TableImportsTests.cs b/crates/misc/dotnet/tests/TableImportsTests.cs index 265205e0c1..8b730fd6b4 100644 --- a/crates/misc/dotnet/tests/TableImportsTests.cs +++ b/crates/misc/dotnet/tests/TableImportsTests.cs @@ -8,7 +8,7 @@ namespace Wasmtime.Tests { public class TableImportsFixture : ModuleFixture { - protected override string ModuleFileName => "TableImports.wasm"; + protected override string ModuleFileName => "TableImports.wat"; } public class TableImportsTests : IClassFixture diff --git a/crates/misc/dotnet/tests/TempFile.cs b/crates/misc/dotnet/tests/TempFile.cs index 6456b37b72..03ecd908b9 100644 --- a/crates/misc/dotnet/tests/TempFile.cs +++ b/crates/misc/dotnet/tests/TempFile.cs @@ -21,4 +21,4 @@ namespace Wasmtime.Tests public string Path { get; private set; } } -} \ No newline at end of file +} diff --git a/crates/misc/dotnet/tests/WasiTests.cs b/crates/misc/dotnet/tests/WasiTests.cs index 06d332634d..44696ee9dc 100644 --- a/crates/misc/dotnet/tests/WasiTests.cs +++ b/crates/misc/dotnet/tests/WasiTests.cs @@ -9,7 +9,7 @@ namespace Wasmtime.Tests { public class WasiFixture : ModuleFixture { - protected override string ModuleFileName => "Wasi.wasm"; + protected override string ModuleFileName => "Wasi.wat"; } public class WasiTests : IClassFixture diff --git a/crates/misc/dotnet/tests/Wasmtime.Tests.csproj b/crates/misc/dotnet/tests/Wasmtime.Tests.csproj index 20f4181420..e3f9717d33 100644 --- a/crates/misc/dotnet/tests/Wasmtime.Tests.csproj +++ b/crates/misc/dotnet/tests/Wasmtime.Tests.csproj @@ -27,7 +27,7 @@ - +