Change wasm_module_new to use Module::from_binary.

This commit changes the C API function `wasm_module_new` to use the Rust API
`Module::from_binary` which performs verification of the module, as per the C
API spec.

This also introduces a `EngineBuilder` type to the C# API that can be used to
construct an `Engine` with the various Wasmtime configuration options.  This
is required to get the C# tests passing since they use reference types and
multi-value.

Fixes #859.
This commit is contained in:
Peter Huene
2020-02-27 13:38:08 -08:00
parent 588cdd47f9
commit 7dfb6ebdb6
6 changed files with 341 additions and 4 deletions

View File

@@ -831,7 +831,7 @@ pub unsafe extern "C" fn wasm_module_new(
) -> *mut wasm_module_t { ) -> *mut wasm_module_t {
let binary = (*binary).as_slice(); let binary = (*binary).as_slice();
let store = &(*store).store.borrow(); let store = &(*store).store.borrow();
let module = match Module::from_binary_unchecked(store, binary) { let module = match Module::from_binary(store, binary) {
Ok(module) => module, Ok(module) => module,
Err(_) => return ptr::null_mut(), Err(_) => return ptr::null_mut(),
}; };

View File

@@ -20,6 +20,17 @@ namespace Wasmtime
} }
} }
internal Engine(Interop.WasmConfigHandle config)
{
Handle = Interop.wasm_engine_new_with_config(config);
config.SetHandleAsInvalid();
if (Handle.IsInvalid)
{
throw new WasmtimeException("Failed to create Wasmtime engine.");
}
}
/// <summary> /// <summary>
/// Creates a new Wasmtime <see cref="Store" />. /// Creates a new Wasmtime <see cref="Store" />.
/// </summary> /// </summary>

View File

@@ -0,0 +1,254 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Wasmtime
{
/// <summary>
/// Represents the Wasmtime compiler strategy.
/// </summary>
public enum CompilerStrategy
{
/// <summary>
/// Automatically pick the compiler strategy.
/// </summary>
Auto,
/// <summary>
/// Use the Cranelift compiler.
/// </summary>
Cranelift,
/// <summary>
/// Use the Lightbeam compiler.
/// </summary>
Lightbeam
}
/// <summary>
/// Represents the Wasmtime optimization level.
/// </summary>
public enum OptimizationLevel
{
/// <summary>
/// Disable optimizations.
/// </summary>
None,
/// <summary>
/// Optimize for speed.
/// </summary>
Speed,
/// <summary>
/// Optimize for speed and size.
/// </summary>
SpeedAndSize
}
/// <summary>
/// Represents a builder of <see cref="Engine"/> instances.
/// </summary>
public class EngineBuilder
{
/// <summary>
/// Constructs a new <see cref="EngineBuilder" />.
/// </summary>
public EngineBuilder()
{
}
/// <summary>
/// Sets whether or not to enable debug information.
/// </summary>
/// <param name="enable">True to enable debug information or false to disable.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithDebugInfo(bool enable)
{
_enableDebugInfo = enable;
return this;
}
/// <summary>
/// Sets whether or not enable WebAssembly threads support.
/// </summary>
/// <param name="enable">True to enable WebAssembly threads support or false to disable.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithWasmThreads(bool enable)
{
_enableWasmThreads = enable;
return this;
}
/// <summary>
/// Sets whether or not enable WebAssembly reference types support.
/// </summary>
/// <param name="enable">True to enable WebAssembly reference types support or false to disable.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithReferenceTypes(bool enable)
{
_enableReferenceTypes = enable;
return this;
}
/// <summary>
/// Sets whether or not enable WebAssembly SIMD support.
/// </summary>
/// <param name="enable">True to enable WebAssembly SIMD support or false to disable.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithSIMD(bool enable)
{
_enableSIMD = enable;
return this;
}
/// <summary>
/// Sets whether or not enable WebAssembly multi-value support.
/// </summary>
/// <param name="enable">True to enable WebAssembly multi-value support or false to disable.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithMultiValue(bool enable)
{
_enableMultiValue = enable;
return this;
}
/// <summary>
/// Sets whether or not enable WebAssembly bulk memory support.
/// </summary>
/// <param name="enable">True to enable WebAssembly bulk memory support or false to disable.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithBulkMemory(bool enable)
{
_enableBulkMemory = enable;
return this;
}
/// <summary>
/// Sets the compiler strategy to use.
/// </summary>
/// <param name="strategy">The compiler strategy to use.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithCompilerStrategy(CompilerStrategy strategy)
{
switch (strategy)
{
case CompilerStrategy.Auto:
_strategy = Interop.wasmtime_strategy_t.WASMTIME_STRATEGY_AUTO;
break;
case CompilerStrategy.Cranelift:
_strategy = Interop.wasmtime_strategy_t.WASMTIME_STRATEGY_CRANELIFT;
break;
case CompilerStrategy.Lightbeam:
_strategy = Interop.wasmtime_strategy_t.WASMTIME_STRATEGY_LIGHTBEAM;
break;
default:
throw new ArgumentOutOfRangeException(nameof(strategy));
}
return this;
}
/// <summary>
/// Sets whether or not enable the Cranelift debug verifier.
/// </summary>
/// <param name="enable">True to enable the Cranelift debug verifier or false to disable.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithCraneliftDebugVerifier(bool enable)
{
_enableCraneliftDebugVerifier = enable;
return this;
}
/// <summary>
/// Sets the optimization level to use.
/// </summary>
/// <param name="level">The optimization level to use.</param>
/// <returns>Returns the current builder.</returns>
public EngineBuilder WithOptimizationLevel(OptimizationLevel level)
{
switch (level)
{
case OptimizationLevel.None:
_optLevel = Interop.wasmtime_opt_level_t.WASMTIME_OPT_LEVEL_NONE;
break;
case OptimizationLevel.Speed:
_optLevel = Interop.wasmtime_opt_level_t.WASMTIME_OPT_LEVEL_SPEED;
break;
case OptimizationLevel.SpeedAndSize:
_optLevel = Interop.wasmtime_opt_level_t.WASMTIME_OPT_LEVEL_SPEED_AND_SIZE;
break;
default:
throw new ArgumentOutOfRangeException(nameof(level));
}
return this;
}
/// <summary>
/// Builds the <see cref="Engine" /> instance.
/// </summary>
/// <returns>Returns the new <see cref="Engine" /> instance.</returns>
public Engine Build()
{
var config = Interop.wasm_config_new();
if (_enableDebugInfo.HasValue)
{
Interop.wasmtime_config_debug_info_set(config, _enableDebugInfo.Value);
}
if (_enableWasmThreads.HasValue)
{
Interop.wasmtime_config_wasm_threads_set(config, _enableWasmThreads.Value);
}
if (_enableReferenceTypes.HasValue)
{
Interop.wasmtime_config_wasm_reference_types_set(config, _enableReferenceTypes.Value);
}
if (_enableSIMD.HasValue)
{
Interop.wasmtime_config_wasm_simd_set(config, _enableSIMD.Value);
}
if (_enableBulkMemory.HasValue)
{
Interop.wasmtime_config_wasm_bulk_memory_set(config, _enableBulkMemory.Value);
}
if (_enableMultiValue.HasValue)
{
Interop.wasmtime_config_wasm_multi_value_set(config, _enableMultiValue.Value);
}
if (_strategy.HasValue)
{
Interop.wasmtime_config_strategy_set(config, _strategy.Value);
}
if (_enableCraneliftDebugVerifier.HasValue)
{
Interop.wasmtime_config_cranelift_debug_verifier_set(config, _enableCraneliftDebugVerifier.Value);
}
if (_optLevel.HasValue)
{
Interop.wasmtime_config_cranelift_opt_level_set(config, _optLevel.Value);
}
return new Engine(config);
}
private bool? _enableDebugInfo;
private bool? _enableWasmThreads;
private bool? _enableReferenceTypes;
private bool? _enableSIMD;
private bool? _enableBulkMemory;
private bool? _enableMultiValue;
private Interop.wasmtime_strategy_t? _strategy;
private bool? _enableCraneliftDebugVerifier;
private Interop.wasmtime_opt_level_t? _optLevel;
}
}

View File

@@ -180,6 +180,21 @@ namespace Wasmtime
} }
} }
internal class WasmConfigHandle : SafeHandle
{
public WasmConfigHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid => handle == IntPtr.Zero;
protected override bool ReleaseHandle()
{
Interop.wasm_config_delete(handle);
return true;
}
}
internal class WasiConfigHandle : SafeHandle internal class WasiConfigHandle : SafeHandle
{ {
public WasiConfigHandle() : base(IntPtr.Zero, true) public WasiConfigHandle() : base(IntPtr.Zero, true)
@@ -277,6 +292,20 @@ namespace Wasmtime
WASM_FUNCREF, WASM_FUNCREF,
} }
internal enum wasmtime_strategy_t : byte
{
WASMTIME_STRATEGY_AUTO,
WASMTIME_STRATEGY_CRANELIFT,
WASMTIME_STRATEGY_LIGHTBEAM
}
internal enum wasmtime_opt_level_t : byte
{
WASMTIME_OPT_LEVEL_NONE,
WASMTIME_OPT_LEVEL_SPEED,
WASMTIME_OPT_LEVEL_SPEED_AND_SIZE
}
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]
internal struct wasm_val_union_t internal struct wasm_val_union_t
{ {
@@ -514,6 +543,9 @@ namespace Wasmtime
[DllImport(LibraryName)] [DllImport(LibraryName)]
public static extern EngineHandle wasm_engine_new(); public static extern EngineHandle wasm_engine_new();
[DllImport(LibraryName)]
public static extern EngineHandle wasm_engine_new_with_config(WasmConfigHandle config);
[DllImport(LibraryName)] [DllImport(LibraryName)]
public static extern void wasm_engine_delete(IntPtr engine); public static extern void wasm_engine_delete(IntPtr engine);
@@ -828,6 +860,14 @@ namespace Wasmtime
[DllImport(LibraryName)] [DllImport(LibraryName)]
public static extern bool wasm_memory_grow(MemoryHandle memory, uint delta); public static extern bool wasm_memory_grow(MemoryHandle memory, uint delta);
// Wasm config
[DllImport(LibraryName)]
public static extern WasmConfigHandle wasm_config_new();
[DllImport(LibraryName)]
public static extern void wasm_config_delete(IntPtr config);
// WASI config // WASI config
[DllImport(LibraryName)] [DllImport(LibraryName)]
@@ -900,5 +940,34 @@ namespace Wasmtime
[DllImport(LibraryName)] [DllImport(LibraryName)]
public static extern IntPtr wasi_instance_bind_import(WasiInstanceHandle instance, IntPtr importType); public static extern IntPtr wasi_instance_bind_import(WasiInstanceHandle instance, IntPtr importType);
// Wasmtime config
[DllImport(LibraryName)]
public static extern void wasmtime_config_debug_info_set(WasmConfigHandle config, [MarshalAs(UnmanagedType.I1)] bool enable);
[DllImport(LibraryName)]
public static extern void wasmtime_config_wasm_threads_set(WasmConfigHandle config, [MarshalAs(UnmanagedType.I1)] bool enable);
[DllImport(LibraryName)]
public static extern void wasmtime_config_wasm_reference_types_set(WasmConfigHandle config, [MarshalAs(UnmanagedType.I1)] bool enable);
[DllImport(LibraryName)]
public static extern IntPtr wasmtime_config_wasm_simd_set(WasmConfigHandle config, [MarshalAs(UnmanagedType.I1)] bool enable);
[DllImport(LibraryName)]
public static extern void wasmtime_config_wasm_bulk_memory_set(WasmConfigHandle config, [MarshalAs(UnmanagedType.I1)] bool enable);
[DllImport(LibraryName)]
public static extern void wasmtime_config_wasm_multi_value_set(WasmConfigHandle config, [MarshalAs(UnmanagedType.I1)] bool enable);
[DllImport(LibraryName)]
public static extern void wasmtime_config_strategy_set(WasmConfigHandle config, wasmtime_strategy_t strategy);
[DllImport(LibraryName)]
public static extern void wasmtime_config_cranelift_debug_verifier_set(WasmConfigHandle config, bool enable);
[DllImport(LibraryName)]
public static extern void wasmtime_config_cranelift_opt_level_set(WasmConfigHandle config, wasmtime_opt_level_t level);
} }
} }

View File

@@ -5,7 +5,7 @@ using System.Linq;
namespace Wasmtime namespace Wasmtime
{ {
/// <summary> /// <summary>
/// Represents a build of WASI instances. /// Represents a builder of <see cref="Wasi"/> instances.
/// </summary> /// </summary>
public class WasiBuilder public class WasiBuilder
{ {

View File

@@ -8,7 +8,10 @@ namespace Wasmtime.Tests
{ {
public ModuleFixture() public ModuleFixture()
{ {
Engine = new Engine(); Engine = new EngineBuilder()
.WithMultiValue(true)
.WithReferenceTypes(true)
.Build();
Store = Engine.CreateStore(); Store = Engine.CreateStore();
Module = Store.CreateModule(Path.Combine("Modules", ModuleFileName)); Module = Store.CreateModule(Path.Combine("Modules", ModuleFileName));
} }