/// <summary> /// Writes a <see cref="Module"/> to an in-memory stream with no expectation of success. /// </summary> /// <param name="module">The module to write.</param> public static void WriteToBinaryNoOutput(this Module module) { using (var memory = new MemoryStream()) { module.WriteToBinary(memory); } }
public void Module_CustomSectionRoundTrip() { var content = BitConverter.DoubleToInt64Bits(Math.PI); var toWrite = new Module(); toWrite.CustomSections.Add(new CustomSection { Content = BitConverter.GetBytes(content), Name = "Test", }); Module toRead; using (var memory = new MemoryStream()) { toWrite.WriteToBinary(memory); memory.Position = 0; toRead = Module.ReadFromBinary(memory); } Assert.IsNotNull(toRead); Assert.AreNotSame(toWrite, toRead); Assert.IsNotNull(toRead.CustomSections); Assert.AreEqual(1, toRead.CustomSections.Count); var custom = toRead.CustomSections[0]; Assert.IsNotNull(custom); Assert.AreEqual("Test", custom.Name); Assert.IsNotNull(custom.Content); Assert.AreEqual(8, custom.Content.Count); Assert.AreEqual(content, BitConverter.ToInt64(custom.Content.ToArray(), 0)); }
public void Module_TypeRoundTrip() { var source = new Module { Types = new Type[] { new Type { Parameters = new[] { ValueType.Int32, ValueType.Float32 }, Returns = new[] { ValueType.Int64 } } } };; Module destination; using (var stream = new MemoryStream()) { source.WriteToBinary(stream); stream.Position = 0; destination = Module.ReadFromBinary(stream); } Assert.IsNotNull(destination.Types); Assert.AreNotSame(source.Types, destination.Types); Assert.AreEqual(1, destination.Types.Count); Assert.IsTrue(source.Types[0].Equals(destination.Types[0])); }
/// <summary> /// Writes a <see cref="Module"/> to an in-memory stream with no expectation of success. /// </summary> /// <param name="module">The module to write.</param> public static void WriteToBinaryNoOutput(this Module module) { Assert.IsNotNull(module); using var memory = new MemoryStream(); module.WriteToBinary(memory); }
public void Compile_MinimalExportedFunction() { var module = new Module(); module.Types.Add(new Type { }); module.Functions.Add(new Function { }); module.Exports.Add(new Export { Name = nameof(HelloWorldExports.Start) }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new End(), }, }); Instance <dynamic> compiled; using (var memory = new MemoryStream()) { module.WriteToBinary(memory); memory.Position = 0; compiled = Compile.FromBinary <dynamic>(memory)(); } compiled.Exports.Start(); }
public void Compile_MinimalInternalFunction() { var module = new Module(); module.Types.Add(new Type { }); module.Functions.Add(new Function { }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new End(), }, }); Instance <dynamic> compiled; using (var memory = new MemoryStream()) { module.WriteToBinary(memory); memory.Position = 0; compiled = Compile.FromBinary <dynamic>(memory)(); } }
public static Module BinaryRoundTrip(this Module module) { using (var memory = new MemoryStream()) { module.WriteToBinary(memory); memory.Position = 0; var result = Module.ReadFromBinary(memory); return(result); } }
public void Compile_RuntimeImport() { var module = new Module(); module.Types.Add(new Type { Returns = new[] { ValueType.Float64 }, Parameters = new[] { ValueType.Float64, ValueType.Float64, } }); module.Imports.Add(new Import.Function { Module = "Math", Field = "Pow", }); module.Functions.Add(new Function { }); module.Exports.Add(new Export { Name = "Test", Index = 1, }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new GetLocal(0), new GetLocal(1), new Call(0), new End() }, }); Instance <CompilerTestBase2 <double> > compiled; using (var memory = new MemoryStream()) { module.WriteToBinary(memory); Assert.AreNotEqual(0, memory.Length); memory.Position = 0; var maker = Compile.FromBinary <CompilerTestBase2 <double> >(memory, new RuntimeImport[] { new FunctionImport("Math", "Pow", typeof(Math).GetTypeInfo().GetMethod("Pow")) }); Assert.IsNotNull(maker); compiled = maker(); } Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; Assert.AreEqual(Math.Pow(2, 3), instance.Test(2, 3)); }
public void Compiler_ReadGlobalSectionWhenGlobalImport() { // Set up a module with a global import and a global var module = new Module(); module.Imports.Add(new WebAssembly.Import.Global("mod", "field")); module.Globals.Add(new Global { ContentType = WebAssemblyValueType.Int32, IsMutable = false, InitializerExpression = new Instruction[] { new Int32Constant(1), new End() }.ToList() }); module.Types.Add(new WebAssemblyType { Returns = new[] { WebAssemblyValueType.Int32, }, }); module.Functions.Add(new Function { Type = 0 }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new GlobalGet(0), new GlobalGet(1), new Int32Add(), new End(), }, }); module.Exports.Add(new Export { Kind = ExternalKind.Function, Index = 0, Name = "fn", }); using var memoryStream = new MemoryStream(); module.WriteToBinary(memoryStream); memoryStream.Seek(0L, SeekOrigin.Begin); var compilationResult = Compile.FromBinary <dynamic>(memoryStream); var result = compilationResult.Invoke(new Dictionary <string, IDictionary <string, RuntimeImport> > { { "mod", new Dictionary <string, RuntimeImport> { { "field", new GlobalImport(() => 2) } } }, }).Exports.fn(); Assert.AreEqual(3, result); }
public void Compile_Empty() { var module = new Module(); using (var memory = new MemoryStream()) { module.WriteToBinary(memory); memory.Position = 0; var result = Compile.FromBinary <object>(memory)(); Assert.IsNotNull(result); } }
public static Module BinaryRoundTrip(this Module module) { Assert.IsNotNull(module); using var memory = new MemoryStream(); module.WriteToBinary(memory); Assert.AreNotEqual(0, memory.Position); memory.Position = 0; var result = Module.ReadFromBinary(memory); Assert.IsNotNull(result); return(result); }
public static TExport CreateInstance <TExport>(string name, ValueType? @return, IList <ValueType> parameters, params Instruction[] code) where TExport : class { Assert.IsNotNull(name); Assert.IsNotNull(parameters); Assert.IsNotNull(code); var module = new Module(); module.Types.Add(new Type { Returns = @return.HasValue == false ? new ValueType[0] : new[] { @return.GetValueOrDefault() }, Parameters = parameters, }); module.Functions.Add(new Function { }); module.Exports.Add(new Export { Name = name }); module.Codes.Add(new FunctionBody { Code = code }); Instance <TExport> compiled; using (var memory = new MemoryStream()) { module.WriteToBinary(memory); Assert.AreNotEqual(0, memory.Length); memory.Position = 0; var maker = Compile.FromBinary <TExport>(memory); Assert.IsNotNull(maker); compiled = maker(); } Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); return(compiled.Exports); }
public void Compile_HelloWorld_Static() { var module = new Module(); module.Types.Add(new Type { Returns = new[] { ValueType.Int32, } }); module.Functions.Add(new Function { }); module.Exports.Add(new Export { Name = nameof(HelloWorldExports.Start) }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new Int32Constant { Value = 3 }, new End(), }, }); Instance <HelloWorldExports> compiled; using (var memory = new MemoryStream()) { module.WriteToBinary(memory); memory.Position = 0; compiled = Compile.FromBinary <HelloWorldExports>(memory)(); } var exports = compiled.Exports; Assert.AreEqual(3, exports.Start()); }
public void Module_FunctionBodyRoundTrip() { var source = new Module { Codes = new[] { new FunctionBody { Locals = new[] { new Local { Count = 2, Type = ValueType.Float64 } }, Code = new Instruction[] { new Instructions.End() } } } }; Module destination; using (var stream = new MemoryStream()) { source.WriteToBinary(stream); stream.Position = 0; destination = Module.ReadFromBinary(stream); } Assert.IsNotNull(destination.Codes); Assert.AreNotSame(source.Codes, destination.Codes); TestUtility.AreEqual(source.Codes[0], destination.Codes[0]); }
public void Module_ImportRoundTrip() { var source = new Module { Imports = new Import[] { new Import.Function { Module = "A", Field = "1", TypeIndex = 2, }, new Import.Table { Module = "B", Field = "2", Definition = new Table { ElementType = ElementType.AnyFunction, ResizableLimits = new ResizableLimits(1, 2), }, }, new Import.Memory { Module = "C", Field = "3", Type = new Memory(4, 5), }, new Import.Global { Module = "D", Field = "4", }, } }; Module destination; using (var stream = new MemoryStream()) { source.WriteToBinary(stream); stream.Position = 0; destination = Module.ReadFromBinary(stream); } Assert.IsNotNull(destination); Assert.AreNotSame(source, destination); Assert.IsNotNull(destination.Imports); var imports = destination.Imports; Assert.AreNotSame(source.Imports, imports); Assert.AreEqual(4, imports.Count); Assert.IsInstanceOfType(imports[0], typeof(Import.Function)); { var function = (Import.Function)imports[0]; Assert.AreEqual("A", function.Module); Assert.AreEqual("1", function.Field); Assert.AreEqual(2u, function.TypeIndex); } Assert.IsInstanceOfType(imports[1], typeof(Import.Table)); { var table = (Import.Table)imports[1]; Assert.AreEqual("B", table.Module); Assert.AreEqual("2", table.Field); Assert.IsNotNull(table.Definition); Assert.AreEqual(ElementType.AnyFunction, table.Definition.ElementType); Assert.IsNotNull(table.Definition.ResizableLimits); Assert.AreEqual(1u, table.Definition.ResizableLimits.Minimum); Assert.AreEqual(2u, table.Definition.ResizableLimits.Maximum.GetValueOrDefault()); } Assert.IsInstanceOfType(imports[2], typeof(Import.Memory)); { var memory = (Import.Memory)imports[2]; Assert.AreEqual("C", memory.Module); Assert.AreEqual("3", memory.Field); Assert.IsNotNull(memory.Type); Assert.IsNotNull(memory.Type.ResizableLimits); Assert.AreEqual(4u, memory.Type.ResizableLimits.Minimum); Assert.AreEqual(5u, memory.Type.ResizableLimits.Maximum.GetValueOrDefault()); } Assert.IsInstanceOfType(imports[3], typeof(Import.Global)); { var global = (Import.Global)imports[3]; Assert.AreEqual("D", global.Module); Assert.AreEqual("4", global.Field); } }