Skip to content

Commit

Permalink
Added TableKind for tables (#262)
Browse files Browse the repository at this point in the history
* Replaced `ValueKind` with `TableKind` in `Table`. This properly represents the range of type a `Table` may contain.

* Added `Obsolete` annotation to Table constructor that accepts `ValueKind` to steer people towards the new constructor.

* Fixed all uses of Obsolete constructor in tests

* Update table example.

---------

Co-authored-by: Peter Huene <peter@huene.dev>
  • Loading branch information
martindevans and peterhuene authored Jul 5, 2023
1 parent 3d4a3e3 commit cf0ef9d
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 16 deletions.
2 changes: 1 addition & 1 deletion examples/table/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using var linker = new Linker(engine);
using var store = new Store(engine);

var table = new Table(store, ValueKind.FuncRef, null, 4);
var table = new Table(store, TableKind.FuncRef, null, 4);

table.SetElement(0, Function.FromCallback(store, (int a, int b) => a + b));
table.SetElement(1, Function.FromCallback(store, (int a, int b) => a - b));
Expand Down
36 changes: 33 additions & 3 deletions src/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@

namespace Wasmtime
{
/// <summary>
/// Represents the possible kinds of WebAssembly values stored in a table
/// </summary>
public enum TableKind
{
/// <summary>
/// The value is a function reference.
/// </summary>
FuncRef = ValueKind.FuncRef,

/// <summary>
/// The value is an external reference.
/// </summary>
ExternRef = ValueKind.ExternRef,
}

/// <summary>
/// Represents a WebAssembly table.
/// </summary>
Expand All @@ -17,14 +33,28 @@ public class Table : IExternal
/// <param name="initialValue">The initial value for elements in the table.</param>
/// <param name="initial">The number of initial elements in the table.</param>
/// <param name="maximum">The maximum number of elements in the table.</param>
[Obsolete("Replace ValueKind parameter with TableKind")]
public Table(Store store, ValueKind kind, object? initialValue, uint initial, uint maximum = uint.MaxValue)
: this(store, (TableKind)kind, initialValue, initial, maximum)
{
}

/// <summary>
/// Creates a new WebAssembly table.
/// </summary>
/// <param name="store">The store to create the table in.</param>
/// <param name="kind">The value kind for the elements in the table.</param>
/// <param name="initialValue">The initial value for elements in the table.</param>
/// <param name="initial">The number of initial elements in the table.</param>
/// <param name="maximum">The maximum number of elements in the table.</param>
public Table(Store store, TableKind kind, object? initialValue, uint initial, uint maximum = uint.MaxValue)
{
if (store is null)
{
throw new ArgumentNullException(nameof(store));
}

if (kind != ValueKind.ExternRef && kind != ValueKind.FuncRef)
if (kind != TableKind.ExternRef && kind != TableKind.FuncRef)
{
throw new WasmtimeException($"Table elements must be externref or funcref.");
}
Expand Down Expand Up @@ -63,7 +93,7 @@ public Table(Store store, ValueKind kind, object? initialValue, uint initial, ui
/// Gets the value kind of the table.
/// </summary>
/// <value></value>
public ValueKind Kind { get; private set; }
public TableKind Kind { get; private set; }

/// <summary>
/// The minimum table element size.
Expand Down Expand Up @@ -154,7 +184,7 @@ internal Table(Store store, ExternTable table)
using var type = new TypeHandle(Native.wasmtime_table_type(store.Context.handle, this.table));
GC.KeepAlive(store);

this.Kind = ValueType.ToKind(Native.wasm_tabletype_element(type.DangerousGetHandle()));
this.Kind = (TableKind)ValueType.ToKind(Native.wasm_tabletype_element(type.DangerousGetHandle()));

unsafe
{
Expand Down
10 changes: 10 additions & 0 deletions src/Value.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public static bool IsAssignableFrom(this ValueKind kind, Type type)

internal static class ValueType
{
public static IntPtr FromKind(TableKind kind)
{
return FromKind((ValueKind)kind);
}

public static IntPtr FromKind(ValueKind kind)
{
switch (kind)
Expand Down Expand Up @@ -251,6 +256,11 @@ public ValueBox ToValueBox()
}
}

public static Value FromObject(object? o, TableKind kind)
{
return FromObject(o, (ValueKind)kind);
}

public static Value FromObject(object? o, ValueKind kind)
{
var value = new Value();
Expand Down
2 changes: 1 addition & 1 deletion tests/StoreTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void ItLimitsTableElements()
{
Store.SetLimits(tableElements: 5);

var table = new Table(Store, ValueKind.ExternRef, null, 0);
var table = new Table(Store, TableKind.ExternRef, null, 0);
table.GetSize().Should().Be(0);

table.Grow(5, null);
Expand Down
6 changes: 3 additions & 3 deletions tests/TableExportsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,19 @@ public void ItCreatesExternsForTheTables()

var table1 = instance.GetTable("table1");
table1.Should().NotBeNull();
table1.Kind.Should().Be(ValueKind.FuncRef);
table1.Kind.Should().Be(TableKind.FuncRef);
table1.Minimum.Should().Be(1);
table1.Maximum.Should().Be(10);

var table2 = instance.GetTable("table2");
table2.Should().NotBeNull();
table2.Kind.Should().Be(ValueKind.FuncRef);
table2.Kind.Should().Be(TableKind.FuncRef);
table2.Minimum.Should().Be(10);
table2.Maximum.Should().Be(uint.MaxValue);

var table3 = instance.GetTable("table3");
table3.Should().NotBeNull();
table3.Kind.Should().Be(ValueKind.FuncRef);
table3.Kind.Should().Be(TableKind.FuncRef);
table3.Minimum.Should().Be(100);
table3.Maximum.Should().Be(1000);
}
Expand Down
16 changes: 8 additions & 8 deletions tests/TableImportBindingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public void ItFailsToInstantiateWithMissingImport()
[Fact]
public void ItFailsToInstantiateWithTableTypeMismatch()
{
var funcs = new Table(Store, ValueKind.ExternRef, null, 10);
var externs = new Table(Store, ValueKind.ExternRef, null, 10);
var funcs = new Table(Store, TableKind.ExternRef, null, 10);
var externs = new Table(Store, TableKind.ExternRef, null, 10);

Linker.Define("", "funcs", funcs);
Linker.Define("", "externs", externs);
Expand All @@ -55,8 +55,8 @@ public void ItFailsToInstantiateWithTableTypeMismatch()
[Fact]
public void ItFailsToInstantiateWithTableLimitsMismatch()
{
var funcs = new Table(Store, ValueKind.FuncRef, null, 10);
var externs = new Table(Store, ValueKind.ExternRef, null, 1);
var funcs = new Table(Store, TableKind.FuncRef, null, 10);
var externs = new Table(Store, TableKind.ExternRef, null, 1);

Linker.Define("", "funcs", funcs);
Linker.Define("", "externs", externs);
Expand All @@ -72,8 +72,8 @@ public void ItFailsToInstantiateWithTableLimitsMismatch()
[Fact]
public void ItBindsTheTableCorrectly()
{
var funcs = new Table(Store, ValueKind.FuncRef, null, 10);
var externs = new Table(Store, ValueKind.ExternRef, null, 10);
var funcs = new Table(Store, TableKind.FuncRef, null, 10);
var externs = new Table(Store, TableKind.ExternRef, null, 10);

Linker.Define("", "funcs", funcs);
Linker.Define("", "externs", externs);
Expand Down Expand Up @@ -120,8 +120,8 @@ public void ItBindsTheTableCorrectly()
[Fact]
public void ItGrowsATable()
{
var funcs = new Table(Store, ValueKind.FuncRef, null, 10, 20);
var externs = new Table(Store, ValueKind.ExternRef, null, 10, 20);
var funcs = new Table(Store, TableKind.FuncRef, null, 10, 20);
var externs = new Table(Store, TableKind.ExternRef, null, 10, 20);

Linker.Define("", "funcs", funcs);
Linker.Define("", "externs", externs);
Expand Down

0 comments on commit cf0ef9d

Please sign in to comment.