Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
<WasmtimePackageVersion Condition="'$(DevBuild)'=='true'">$(WasmtimeVersion)$(WasmtimeDotnetVersion)-dev</WasmtimePackageVersion>
<WasmtimePackageVersion Condition="'$(WasmtimePackageVersion)'==''">$(WasmtimeVersion)$(WasmtimeDotnetVersion)</WasmtimePackageVersion>
</PropertyGroup>
</Project>
<PropertyGroup Condition="'$(DevBuild)'=='true'">
<DefineConstants>$(DefineConstants);WASMTIME_DEV</DefineConstants>
</PropertyGroup>
</Project>
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ $ dotnet build Wasmtime.sln
This will download the latest development snapshot of Wasmtime for your
platform.

By default, local builds set `DevBuild=true`, which uses the dev C API artifacts
(`wasmtime-dev-*`) and enables a `WASMTIME_DEV` build define to match the dev
ABI (value/trap layouts). To build against the stable Wasmtime release instead,
override the flag:

```
$ dotnet build Wasmtime.sln -p:DevBuild=false
```

If you switch between `DevBuild=true` and `DevBuild=false`, you may need to
delete `src/obj` to force the correct C API download.

### Testing

Use `dotnet` to run the unit tests:
Expand Down
107 changes: 106 additions & 1 deletion src/TrapException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,112 @@ public enum TrapCode
Unreachable = 9,
/// <summary>The trap was the result of interrupting execution.</summary>
Interrupt = 10,
#if WASMTIME_DEV
/// <summary>The trap was the result of running out of the configured fuel amount.</summary>
OutOfFuel = 11,
/// <summary>
/// The trap was the result of atomic wait operations on non-shared memory.
/// </summary>
AtomicWaitNonSharedMemory = 12,
/// <summary>
/// The trap was the result of a call to a null reference.
/// </summary>
NullReference = 13,
/// <summary>
/// The trap was the result of an attempt to access beyond the bounds of an array.
/// </summary>
ArrayOutOfBounds = 14,
/// <summary>
/// The trap was the result of an allocation that was too large to succeed.
/// </summary>
AllocationTooLarge = 15,
/// <summary>
/// The trap was the result of an attempt to cast a reference to a type that it is not an instance of.
/// </summary>
CastFailure = 16,
/// <summary>
/// The trap was the result of a component calling another component that would have violated the reentrance rules.
/// </summary>
CannotEnterComponent = 17,
/// <summary>
/// The trap was the result of an async-lifted export failing to return a valid async result.
/// </summary>
/// <remarks>
/// An async-lifted export failed to produce a result by calling `task.return` before returning `STATUS_DONE`
/// and/or after all host tasks completed.
/// </remarks>
NoAsyncResult = 18,
/// <summary>
/// The trap was the result of suspending to a tag for which there is no active handler.
/// </summary>
UnhandledTag = 19,
/// <summary>
/// The trap was the result of an attempt to resume a continuation twice.
/// </summary>
ContinuationAlreadyConsumed = 20,
/// <summary>
/// The trap was the result of a Pulley opcode executed at runtime when the opcode was disabled at compile time.
/// </summary>
DisabledOpCode = 21,
/// <summary>
/// The trap was the result of an async event loop deadlock.
/// </summary>
/// <remarks>
/// The async event loop cannot make further progress given that all host tasks have completed
/// and any/all host-owned stream/future handles have been dropped.
/// </remarks>
AsyncDeadlock = 22,
/// <summary>
/// The trap was the result of a component instance trying to call an import or intrinsic when not allowed.
/// </summary>
/// <remarks>
/// When the component-model feature is enabled this trap represents a scenario where a component instance
/// tried to call an import or intrinsic when it wasn't allowed to, e.g. from a post-return function.
/// </remarks>
CannotLeaveComponent = 23,
/// <summary>
/// The trap was the result of a synchronous task attempting to make a potentially blocking call prior to returning.
/// </summary>
CannotBlockSyncTask = 24,
/// <summary>
/// The trap was the result of a component trying to lift a char with an invalid bit pattern.
/// </summary>
InvalidChar = 25,
/// <summary>
/// Debug assertion generated for a fused adapter regarding the expected completion of a string encoding operation.
/// </summary>
DebugAssertStringEncodingFinished = 26,
/// <summary>
/// Debug assertion generated for a fused adapter regarding a string encoding operation.
/// </summary>
DebugAssertEqualCodeUnits = 27,
/// <summary>
/// Debug assertion generated for a fused adapter regarding the alignment of a pointer.
/// </summary>
DebugAssertPointerAligned = 28,
/// <summary>
/// Debug assertion generated for a fused adapter regarding the upper bits of a 64-bit value.
/// </summary>
DebugAssertUpperBitsUnset = 29,
/// <summary>
/// The trap was the result of a component trying to lift or lower a string past the end of its memory.
/// </summary>
StringOutOfBounds = 30,
/// <summary>
/// The trap was the result of a component trying to lift or lower a list past the end of its memory.
/// </summary>
ListOutOfBounds = 31,
/// <summary>
/// The trap was the result of a component using an invalid discriminant when lowering a variant value.
/// </summary>
InvalidDiscriminant = 32,
/// <summary>
/// The trap was the result of a component passing an unaligned pointer when lifting or lowering a value.
/// </summary>
UnalignedPointer = 33
#else
/// <summary>
/// The trap was the result of executing a function that was `canon lift`'d, then `canonlower`'d, then called.
/// The trap was the result of executing a function that was `canon lift`'d, then `canonlower`'d, then called.
/// </summary>
/// <remarks>
/// When the component model feature is enabled this trap represents a function that was `canon lift`'d,
Expand Down Expand Up @@ -84,6 +188,7 @@ public enum TrapCode
/// The trap was the result of a Pulley opcode executed at runtime when the opcode was disabled at compile time.
/// </summary>
DisabledOpCode = 20
#endif
}

/// <summary>
Expand Down
59 changes: 59 additions & 0 deletions src/Value.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,27 @@ private static class Native
/// <see cref="Store"/>.
/// </para>
/// </remarks>
#if WASMTIME_DEV
[StructLayout(LayoutKind.Explicit, Size = 32)]
internal struct Value
{
static Value()
{
// Ensure the struct size matches the expected wasmtime_val_t size.
System.Diagnostics.Debug.Assert(Marshal.SizeOf(typeof(Value)) == 32,
$"Value struct size mismatch: expected 32, got {Marshal.SizeOf(typeof(Value))}");
}
#else
[StructLayout(LayoutKind.Sequential)]
internal struct Value
{
static Value()
{
// Ensure the struct size matches the expected wasmtime_val_t size.
System.Diagnostics.Debug.Assert(Marshal.SizeOf(typeof(Value)) == 24,
$"Value struct size mismatch: expected 24, got {Marshal.SizeOf(typeof(Value))}");
}
#endif
public void Release(Store store)
{
Native.wasmtime_val_unroot(store.Context.handle, this);
Expand Down Expand Up @@ -490,9 +508,16 @@ public static class Native
}

public static readonly Native.Finalizer Finalizer = (p) => GCHandle.FromIntPtr(p).Free();
#if WASMTIME_DEV
[FieldOffset(0)]
private ValueKind kind;

[FieldOffset(8)]
private ValueUnion of;
#else
private ValueKind kind;
private ValueUnion of;
#endif
}

[StructLayout(LayoutKind.Explicit)]
Expand Down Expand Up @@ -523,9 +548,40 @@ internal unsafe struct ValueUnion
public V128 v128;
}

#if WASMTIME_DEV
[StructLayout(LayoutKind.Sequential)]
internal struct AnyRef
{
static AnyRef() => System.Diagnostics.Debug.Assert(Marshal.SizeOf(typeof(AnyRef)) == 24);

public ulong store;

private uint __private1;

private uint __private2;

private IntPtr __private3;
}

[StructLayout(LayoutKind.Sequential)]
internal struct ExternRef
{
static ExternRef() => System.Diagnostics.Debug.Assert(Marshal.SizeOf(typeof(ExternRef)) == 24);

public ulong store;

private uint __private1;

private uint __private2;

private IntPtr __private3;
}
#else
[StructLayout(LayoutKind.Sequential)]
internal struct AnyRef
{
static AnyRef() => System.Diagnostics.Debug.Assert(Marshal.SizeOf(typeof(AnyRef)) == 16);

public ulong store;

private uint __private1;
Expand All @@ -536,10 +592,13 @@ internal struct AnyRef
[StructLayout(LayoutKind.Sequential)]
internal struct ExternRef
{
static ExternRef() => System.Diagnostics.Debug.Assert(Marshal.SizeOf(typeof(ExternRef)) == 16);

public ulong store;

private uint __private1;

private uint __private2;
}
#endif
}
Loading