diff --git a/src/Store.cs b/src/Store.cs index d53295ab..437fc79c 100644 --- a/src/Store.cs +++ b/src/Store.cs @@ -72,6 +72,13 @@ internal void SetWasiConfiguration(WasiConfiguration config) } } + internal void SetWasiConfiguration(Wasi2Configuration config) + { + var wasi = config.Build(); + Native.wasmtime_context_set_wasip2(handle, wasi.DangerousGetHandle()); + wasi.SetHandleAsInvalid(); + } + /// /// Configures the relative deadline at which point WebAssembly code will trap. /// @@ -95,6 +102,9 @@ private static class Native [DllImport(Engine.LibraryName)] public static extern IntPtr wasmtime_context_set_wasi(IntPtr handle, IntPtr config); + [DllImport(Engine.LibraryName)] + public static extern void wasmtime_context_set_wasip2(IntPtr handle, IntPtr config2); + [DllImport(Engine.LibraryName)] public static extern void wasmtime_context_set_epoch_deadline(IntPtr handle, ulong ticksBeyondCurrent); @@ -239,6 +249,16 @@ public void SetWasiConfiguration(WasiConfiguration config) System.GC.KeepAlive(this); } + /// + /// Configures WASI2 within the store. + /// + /// The WASI2 configuration to use. + public void SetWasiConfiguration(Wasi2Configuration config) + { + Context.SetWasiConfiguration(config); + System.GC.KeepAlive(this); + } + /// /// Configures the relative deadline at which point WebAssembly code will trap. /// diff --git a/src/Wasi2Configuration.cs b/src/Wasi2Configuration.cs new file mode 100644 index 00000000..cec2aee6 --- /dev/null +++ b/src/Wasi2Configuration.cs @@ -0,0 +1,110 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.Runtime.InteropServices; + +namespace Wasmtime; + +/// +/// Represents a WASI2 configuration. +/// +public class Wasi2Configuration +{ + private bool _inheritStandardInput; + private bool _inheritStandardOutput; + private bool _inheritStandardError; + + /// + /// Sets the configuration to inherit stdin. + /// + /// Returns the current configuration. + public Wasi2Configuration WithInheritedStandardInput() + { + _inheritStandardInput = true; + return this; + } + + /// + /// Sets the configuration to inherit stdout. + /// + /// Returns the current configuration. + public Wasi2Configuration WithInheritedStandardOutput() + { + _inheritStandardOutput = true; + return this; + } + + /// + /// Sets the configuration to inherit stderr. + /// + /// Returns the current configuration. + public Wasi2Configuration WithInheritedStandardError() + { + _inheritStandardError = true; + return this; + } + + internal Handle Build() + { + var config = new Handle(Native.wasmtime_wasip2_config_new()); + + SetStandardIn(config); + SetStandardOut(config); + SetStandardError(config); + + return config; + } + + private void SetStandardIn(Handle config) + { + if (_inheritStandardInput) + Native.wasmtime_wasip2_config_inherit_stdin(config); + } + + private void SetStandardOut(Handle config) + { + if (_inheritStandardOutput) + Native.wasmtime_wasip2_config_inherit_stdout(config); + } + + private void SetStandardError(Handle config) + { + if (_inheritStandardError) + Native.wasmtime_wasip2_config_inherit_stderr(config); + } + + internal class Handle : SafeHandleZeroOrMinusOneIsInvalid + { + public Handle(IntPtr handle) + : base(true) + { + SetHandle(handle); + } + + protected override bool ReleaseHandle() + { + Native.wasmtime_wasip2_config_delete(handle); + return true; + } + } + + private static class Native + { + [DllImport(Engine.LibraryName)] + public static extern IntPtr wasmtime_wasip2_config_new(); + + [DllImport(Engine.LibraryName)] + public static extern void wasmtime_wasip2_config_delete(IntPtr config); + + [DllImport(Engine.LibraryName)] + public static extern void wasmtime_wasip2_config_inherit_stdin(Handle config); + + [DllImport(Engine.LibraryName)] + public static extern void wasmtime_wasip2_config_inherit_stdout(Handle config); + + [DllImport(Engine.LibraryName)] + public static extern void wasmtime_wasip2_config_inherit_stderr(Handle config); + + [DllImport(Engine.LibraryName)] + public static extern unsafe void wasmtime_wasip2_config_arg(Handle config, char* arg, nuint arg_len); + } +} \ No newline at end of file diff --git a/tests/Wasi2Tests.cs b/tests/Wasi2Tests.cs new file mode 100644 index 00000000..ca89457b --- /dev/null +++ b/tests/Wasi2Tests.cs @@ -0,0 +1,21 @@ +using System; +using Xunit; + +namespace Wasmtime.Tests; + +public class Wasi2Tests +{ + [Fact] + public void ItSetsWasi2Config() + { + using var engine = new Engine(); + using var store = new Store(engine); + + var config = new Wasi2Configuration(); + config.WithInheritedStandardInput(); + config.WithInheritedStandardOutput(); + config.WithInheritedStandardError(); + + store.SetWasiConfiguration(config); + } +} \ No newline at end of file