Skip to content
Open
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
38 changes: 20 additions & 18 deletions src/Linker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ namespace Wasmtime
/// </summary>
public partial class Linker : IDisposable
{
private const int StackallocThreshold = 256;

/// <summary>
/// Constructs a new linker from the given engine.
/// </summary>
Expand Down Expand Up @@ -304,9 +302,11 @@ public Function GetDefaultFunction(Store store, string name)
public Function? GetFunction(Store store, string module, string name)
{
if (store is null)
{
throw new ArgumentNullException(nameof(store));
}
if (module is null)
throw new ArgumentNullException(nameof(module));
if (name is null)
throw new ArgumentNullException(nameof(name));

var context = store.Context;
if (!TryGetExtern(context, module, name, out var ext) || ext.kind != ExternKind.Func)
Expand All @@ -329,9 +329,11 @@ public Function GetDefaultFunction(Store store, string name)
public Table? GetTable(Store store, string module, string name)
{
if (store is null)
{
throw new ArgumentNullException(nameof(store));
}
if (module is null)
throw new ArgumentNullException(nameof(module));
if (name is null)
throw new ArgumentNullException(nameof(name));

var context = store.Context;
if (!TryGetExtern(context, module, name, out var ext) || ext.kind != ExternKind.Table)
Expand All @@ -354,9 +356,11 @@ public Function GetDefaultFunction(Store store, string name)
public Memory? GetMemory(Store store, string module, string name)
{
if (store is null)
{
throw new ArgumentNullException(nameof(store));
}
if (module is null)
throw new ArgumentNullException(nameof(module));
if (name is null)
throw new ArgumentNullException(nameof(name));

var context = store.Context;
if (!TryGetExtern(context, module, name, out var ext) || ext.kind != ExternKind.Memory)
Expand All @@ -379,9 +383,11 @@ public Function GetDefaultFunction(Store store, string name)
public Global? GetGlobal(Store store, string module, string name)
{
if (store is null)
{
throw new ArgumentNullException(nameof(store));
}
if (module is null)
throw new ArgumentNullException(nameof(module));
if (name is null)
throw new ArgumentNullException(nameof(name));

var context = store.Context;
if (!TryGetExtern(context, module, name, out var ext) || ext.kind != ExternKind.Global)
Expand Down Expand Up @@ -412,19 +418,15 @@ public void Dispose()
public void DefineFunction(string module, string name, Function.UntypedCallbackDelegate callback, IReadOnlyList<ValueKind> parameterKinds, IReadOnlyList<ValueKind> resultKinds)
{
if (module is null)
{
throw new ArgumentNullException(nameof(module));
}

if (name is null)
{
throw new ArgumentNullException(nameof(name));
}

if (callback is null)
{
throw new ArgumentNullException(nameof(callback));
}
if (parameterKinds is null)
throw new ArgumentNullException(nameof(parameterKinds));
if (resultKinds is null)
throw new ArgumentNullException(nameof(resultKinds));

unsafe
{
Expand Down
57 changes: 57 additions & 0 deletions tests/ExternTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Diagnostics;
using Xunit;

namespace Wasmtime.Tests;

public class ExternTests
{
[Fact]
public void ExternFunc_StaticCheck()
{
// An assertion is made in the static constructor. Doing this forces the static constructor to run
Assert.Equal(default(ExternFunc), default);
}

[Fact]
public void ExternTable_StaticCheck()
{
// An assertion is made in the static constructor. Doing this forces the static constructor to run
Assert.Equal(default(ExternTable), default);
}

[Fact]
public void ExternMemory_StaticCheck()
{
// An assertion is made in the static constructor. Doing this forces the static constructor to run
Assert.Equal(default(ExternMemory), default);
}

[Fact]
public void ExternInstance_StaticCheck()
{
// An assertion is made in the static constructor. Doing this forces the static constructor to run
Assert.Equal(default(ExternInstance), default);
}

[Fact]
public void ExternGlobal_StaticCheck()
{
// An assertion is made in the static constructor. Doing this forces the static constructor to run
Assert.Equal(default(ExternGlobal), default);
}

[Fact]
public void ExternUnion_StaticCheck()
{
// An assertion is made in the static constructor. Doing this forces the static constructor to run
Assert.Equal(default(ExternUnion), default);
Assert.Equal(default(Extern), default);
}

[Fact]
public void Extern_StaticCheck()
{
// An assertion is made in the static constructor. Doing this forces the static constructor to run
Assert.Equal(default(Extern), default);
}
}
54 changes: 50 additions & 4 deletions tests/LinkerFunctionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,61 @@ public void ItReturnsNullForUndefinedFunctions()
}

[Fact]
public void ItBindsComplexFunction()
public void GetFunctionThrowsWithNullStore()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetFunction(null!, "module", "name"));
}

[Fact]
public void GetFunctionThrowsWithNullName()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetFunction(Store, "module", null!));
}

[Fact]
public void GetFunctionThrowsWithNullModule()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetFunction(Store, null!, "name"));
}

[Fact]
public void DefineFunctionThrowsWithNullModule()
{
Assert.Throws<ArgumentNullException>(() => Linker.DefineFunction(null!, "name", (c, p, r) => { }, [ ValueKind.Int32 ], []));
}

[Fact]
public void DefineFunctionThrowsWithNullName()
{
Assert.Throws<ArgumentNullException>(() => Linker.DefineFunction("", null!, (c, p, r) => { }, [ValueKind.Int32], []));
}

[Fact]
public void DefineFunctionThrowsWithNullCallback()
{
Assert.Throws<ArgumentNullException>(() => Linker.DefineFunction("", "name", null!, [ValueKind.Int32], []));
}

[Fact]
public void DefineFunctionThrowsWithNullParameters()
{
using var store = new Store(Fixture.Engine);
Assert.Throws<ArgumentNullException>(() => Linker.DefineFunction("", "name", (c, p, r) => { }, null!, []));
}

[Fact]
public void DefineFunctionThrowsWithNullResults()
{
Assert.Throws<ArgumentNullException>(() => Linker.DefineFunction("", "name", (c, p, r) => { }, [ValueKind.Int32], null!));
}

[Fact]
public void ItBindsComplexFunction()
{
Linker.DefineFunction("", "complex", (c, p, r) =>
{
p.Length.Should().Be(0);
r.Length.Should().Be(19);
for (int i = 0; i < r.Length; ++i)
for (var i = 0; i < r.Length; ++i)
{
r[i] = i + 1;
}
Expand All @@ -254,7 +300,7 @@ public void ItBindsComplexFunction()
Enumerable.Repeat(ValueKind.Int32, 19).ToArray()
);

var func = Linker.GetFunction(store, "", "complex");
var func = Linker.GetFunction(Store, "", "complex");
func.Should().NotBeNull();
}

Expand Down
160 changes: 160 additions & 0 deletions tests/LinkerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using System;
using Xunit;

namespace Wasmtime.Tests;

public sealed class LinkerFixture : ModuleFixture
{
protected override string ModuleFileName => "FunctionExports.wat";
}

public sealed class LinkerTests
: IClassFixture<LinkerFixture>, IDisposable
{
private Store Store { get; }
private Linker Linker { get; }

public LinkerTests(LinkerFixture fixture)
{
Fixture = fixture;
Linker = new Linker(Fixture.Engine);
Store = new Store(Fixture.Engine);
}

public LinkerFixture Fixture { get; }

public void Dispose()
{
Linker.Dispose();
Store.Dispose();
}

[Fact]
public void ItThrowsWithNullEngine()
{
Assert.Throws<ArgumentNullException>(() => new Linker(null!));
}

[Fact]
public void DefineThrowsWithNullStore()
{
Assert.Throws<ArgumentException>(() => Linker.Define("module", "name", Function.Null));
}

[Fact]
public void DefineThrowsWithNullModule()
{
Assert.Throws<ArgumentNullException>(() => Linker.Define(null!, "name", new Global(Store, ValueKind.Int32, 1, Mutability.Immutable)));
}

[Fact]
public void DefineThrowsWithNullName()
{
Assert.Throws<ArgumentNullException>(() => Linker.Define("module", null!, new Global(Store, ValueKind.Int32, 1, Mutability.Immutable)));
}

[Fact]
public void DefineModuleThrowsWithNullModule()
{
Assert.Throws<ArgumentNullException>(() => Linker.DefineModule(Store, null!));
}

[Fact]
public void DefineModuleThrowsWithNullStore()
{
Assert.Throws<ArgumentNullException>(() => Linker.DefineModule(null!, Fixture.Module));
}

[Fact]
public void DefineWasiTwiceThrows()
{
Linker.DefineWasi();
Assert.Throws<WasmtimeException>(() => Linker.DefineWasi());
}

[Fact]
public void GetDefaultFunctionThrowsWithNullStore()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetDefaultFunction(null!, "name"));
}

[Fact]
public void GetDefaultFunctionThrowsWithNullName()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetDefaultFunction(Store, null!));
}

[Fact]
public void GetTableThrowsWithNullStore()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetTable(null!, "module", "name"));
}

[Fact]
public void GetTableThrowsWithNullModule()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetTable(Store, null!, "name"));
}

[Fact]
public void GetTableThrowsWithNullName()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetTable(Store, "module", null!));
}

[Fact]
public void GetMemoryThrowsWithNullStore()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetMemory(null!, "module", "name"));
}

[Fact]
public void GetMemoryThrowsWithNullModule()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetMemory(Store, null!, "name"));
}

[Fact]
public void GetMemoryThrowsWithNullName()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetMemory(Store, "module", null!));
}

[Fact]
public void GetGlobalThrowsWithNullStore()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetGlobal(null!, "module", "name"));
}

[Fact]
public void GetGlobalThrowsWithNullModule()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetGlobal(Store, null!, "name"));
}

[Fact]
public void GetGlobalThrowsWithNullName()
{
Assert.Throws<ArgumentNullException>(() => Linker.GetGlobal(Store, "module", null!));
}

[Fact]
public void DefineInstanceThrowsWithNullStore()
{
var instance = new Instance(Store, Fixture.Module);
Assert.Throws<ArgumentNullException>(() => Linker.DefineInstance(null!, "name", instance));
}

[Fact]
public void DefineInstanceThrowsWithNullName()
{
var instance = new Instance(Store, Fixture.Module);
Assert.Throws<ArgumentNullException>(() => Linker.DefineInstance(Store, null!, instance));
}

[Fact]
public void DefineInstanceThrowsWithNullInstance()
{
Assert.Throws<ArgumentNullException>(() => Linker.DefineInstance(Store, "name", null!));
}
}