public void Compile_HelloWorld_Dynamic() { var module = new Module(); module.Types.Add(new WebAssemblyType { Returns = new[] { WebAssemblyValueType.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 = 8 }, new End(), }, }); var compiled = module.ToInstance <dynamic>(); var exports = compiled.Exports; Assert.AreEqual(8, exports.Start()); }
public void Compile_MinimalExportedMutableGlobal() { var module = new Module(); module.Globals.Add(new Global { ContentType = WebAssemblyValueType.Int32, IsMutable = true, InitializerExpression = new Instruction[] { new Int32Constant(3), new End() } }); module.Exports.Add(new Export { Name = "Test", Kind = ExternalKind.Global, }); var compiled = module.ToInstance <ExportedMutableGlobal>(); Assert.AreEqual(3, compiled.Exports.Test); Assert.AreNotEqual(4, compiled.Exports.Test); compiled.Exports.Test = 7; Assert.AreEqual(7, compiled.Exports.Test); Assert.AreNotEqual(4, compiled.Exports.Test); Assert.AreNotEqual(3, compiled.Exports.Test); }
public void Compile_MinimalExportedImmutableGlobal() { var module = new Module(); module.Globals.Add(new Global { ContentType = ValueType.Int32, IsMutable = false, InitializerExpression = new Instruction[] { new Int32Constant(5), new End() } }); module.Exports.Add(new Export { Name = "Test", Kind = ExternalKind.Global, }); var compiled = module.ToInstance <ExportedReadonlyGlobal>(); Assert.AreEqual(5, compiled.Exports.Test); Assert.AreNotEqual(6, compiled.Exports.Test); }
public void Compile_GlobalImmutableImportExport() { var module = new Module(); module.Imports.Add(new Import.Global { Module = "Imported", Field = "Global", ContentType = ValueType.Int32, }); module.Exports.Add(new Export { Name = "Test", Kind = ExternalKind.Global, }); var compiled = module.ToInstance <CompilerTestBaseExportedImmutableGlobal <int> >( new RuntimeImport[] { new GlobalImport("Imported", "Global", typeof(GlobalImportTests).GetTypeInfo().GetProperty(nameof(ImportedImmutableGlobalReturns3))) }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; Assert.AreEqual(ImportedImmutableGlobalReturns3, instance.Test); }
public void Compile_MinimalExportedImmutableGlobal() { var module = new Module(); module.Globals.Add(new Global { ContentType = WebAssemblyValueType.Int32, IsMutable = false, InitializerExpression = new Instruction[] { new Int32Constant(5), new End() } }); module.Exports.Add(new Export { Name = "Test", Kind = ExternalKind.Global, }); var compiled = module.ToInstance <ExportedReadonlyGlobal>(); Assert.AreEqual(5, compiled.Exports.Test); var native = compiled.Exports.GetType().GetProperty("Test").GetCustomAttribute <NativeExportAttribute>(); Assert.IsNotNull(native); Assert.AreEqual(ExternalKind.Global, native.Kind); Assert.AreEqual("Test", native.Name); }
public void Compiler_Memory() { var module = new Module(); module.Memories.Add(new Memory(1, 1)); module.Exports.Add(new Export { Name = "Memory", Kind = ExternalKind.Memory, }); var compiled = module.ToInstance <dynamic>(); Runtime.UnmanagedMemory linearMemory; using (compiled) { Assert.IsNotNull(compiled); var exports = compiled.Exports; Assert.IsNotNull(exports); linearMemory = exports.Memory; Assert.IsNotNull(linearMemory); Assert.AreNotEqual(IntPtr.Zero, linearMemory.Start); for (var i = 0; i < Memory.PageSize; i += 8) { Assert.AreEqual(0, Marshal.ReadInt64(linearMemory.Start + 8)); } } Assert.AreEqual(IntPtr.Zero, linearMemory.Start); }
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(), }, }); var compiled = module.ToInstance <dynamic>(); compiled.Exports.Start(); }
public void Compile_GlobalImmutableImportExport() { var module = new Module(); module.Imports.Add(new Import.Global { Module = "Imported", Field = "Global", ContentType = WebAssemblyValueType.Int32, }); module.Exports.Add(new Export { Name = "Test", Kind = ExternalKind.Global, }); var compiled = module.ToInstance <CompilerTestBaseExportedImmutableGlobal <int> >( new ImportDictionary { { "Imported", "Global", new GlobalImport(() => ImportedImmutableGlobalReturns3) }, }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; Assert.AreEqual(ImportedImmutableGlobalReturns3, instance.Test); }
public void Compiler_DataMemoryMinimumTooSmall() { var module = new Module(); module.Memories.Add(new Memory(0, 1)); module.Exports.Add(new Export { Name = "Memory", Kind = ExternalKind.Memory, }); module.Data.Add(new Data { InitializerExpression = new Instruction[] { new Int32Constant(0), new End(), }, RawData = new byte[] { 2 }, }); //module.ToInstance<dynamic>(); var x = Assert.ThrowsException <MemoryAccessOutOfRangeException>(() => module.ToInstance <dynamic>()); Assert.AreEqual(1u, x.Offset); Assert.AreEqual(1u, x.Length); }
public void Compiler_MemoryImportExport() { var module = new Module(); module.Memories.Add(new Memory(0, 1)); module.Imports.Add(new Import.Memory { Field = "Memory", Module = "Memory", Type = new Memory(0, 1) }); module.Exports.Add(new Export { Name = "Memory", Kind = ExternalKind.Memory, }); var memory = new Runtime.UnmanagedMemory(0, 1); var roundMemory = module.ToInstance <dynamic>(new ImportDictionary { { "Memory", "Memory", new MemoryImport(() => memory) }, }).Exports.Memory as UnmanagedMemory; Assert.IsNotNull(roundMemory); Assert.AreSame(memory, roundMemory); }
public static TExport CreateInstance <TExport>(string name, WebAssemblyValueType? @return, params Instruction[] code) where TExport : class { var module = new Module(); module.Types.Add(new WebAssemblyType { Returns = @return.HasValue == false ? new WebAssemblyValueType[0] : new[] { @return.GetValueOrDefault() }, }); module.Functions.Add(new Function { }); module.Exports.Add(new Export { Name = name }); module.Codes.Add(new FunctionBody { Code = code }); var compiled = module.ToInstance <TExport>(); return(compiled.Exports); }
public void Compile_Streaming() { 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(), }, }); var compiled = module.ToInstance <HelloWorldExports>(); var exports = compiled.Exports; Assert.AreEqual(3, exports.Start()); }
public void Compile_CallsParentConstructor() { var module = new Module(); var compiled = module.ToInstance <HelloWorldExportsWithConstructor>(); var exports = compiled.Exports; Assert.AreEqual(5, exports.SetByConstructor); }
public void Compile_FunctionImportDelegateNoReturn() { var module = new Module(); module.Types.Add(new WebAssemblyType { Parameters = new[] { WebAssemblyValueType.Float64, } }); module.Imports.Add(new Import.Function { Module = "Do", Field = "Nothing", }); module.Functions.Add(new Function { }); module.Exports.Add(new Export { Name = "Test", Index = 1, }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new LocalGet(0), new Call(0), new End() }, }); var calls = 0; void doNothing(double ignored) => calls++; var compiled = module.ToInstance <CompilerTestBaseVoid <double> >( new ImportDictionary { { "Do", "Nothing", new FunctionImport(new Action <double>(doNothing)) }, }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; lock (typeof(NothingDoer)) { var start = calls; instance.Test(2); Assert.AreEqual(start + 1, calls); } }
public void Compiler_DataOverlappedSegments() { var module = new Module(); module.Memories.Add(new Memory(1, 1)); module.Exports.Add(new Export { Name = "Memory", Kind = ExternalKind.Memory, }); module.Data.Add(new Data { InitializerExpression = new Instruction[] { new Int32Constant(0), new End(), }, RawData = new byte[] { 1, 2 }, }); module.Data.Add(new Data { InitializerExpression = new Instruction[] { new Int32Constant(1), new End(), }, RawData = new byte[] { 3, 4 }, }); var compiled = module.ToInstance <dynamic>(); UnmanagedMemory linearMemory; using (compiled) { Assert.IsNotNull(compiled); var exports = compiled.Exports; Assert.IsNotNull(exports); linearMemory = exports.Memory; Assert.IsNotNull(linearMemory); Assert.AreNotEqual(IntPtr.Zero, linearMemory.Start); Assert.AreEqual(0x040301, Marshal.ReadInt64(linearMemory.Start)); } Assert.AreEqual(IntPtr.Zero, linearMemory.Start); }
public void Compile_RuntimeImportNoReturn() { var module = new Module(); module.Types.Add(new Type { Parameters = new[] { ValueType.Float64, } }); module.Imports.Add(new Import.Function { Module = "Do", Field = "Nothing", }); 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 Call(0), new End() }, }); var compiled = module.ToInstance <CompilerTestBaseVoid <double> >( new RuntimeImport[] { new FunctionImport("Do", "Nothing", typeof(NothingDoer).GetTypeInfo().GetMethod(nameof(NothingDoer.DoNothing))) }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; lock (typeof(NothingDoer)) { var start = NothingDoer.Calls; instance.Test(2); Assert.AreEqual(start + 1, NothingDoer.Calls); } }
public void Compiler_CustomSection() { var module = new Module(); module.CustomSections.Add(new CustomSection { Content = BitConverter.GetBytes(Math.PI), Name = "Test", }); var compiled = module.ToInstance <dynamic>(); Assert.IsNotNull(compiled); using (compiled) { } }
public void Compile_FunctionImport() { var module = new Module(); module.Types.Add(new WebAssemblyType { Returns = new[] { WebAssemblyValueType.Float64 }, Parameters = new[] { WebAssemblyValueType.Float64, WebAssemblyValueType.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 LocalGet(0), new LocalGet(1), new Call(0), new End() }, }); var compiled = module.ToInstance <CompilerTestBase2 <double> >( new ImportDictionary { { "Math", "Pow", new FunctionImport(new Func <double, double, double>(Math.Pow)) }, }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; Assert.AreEqual(Math.Pow(2, 3), instance.Test(2, 3)); }
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() }, }); var compiled = module.ToInstance <CompilerTestBase2 <double> >( new RuntimeImport[] { new FunctionImport("Math", "Pow", typeof(Math).GetTypeInfo().GetMethod("Pow")) }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; Assert.AreEqual(Math.Pow(2, 3), instance.Test(2, 3)); }
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(), }, }); var compiled = module.ToInstance <dynamic>(); }
public void Compiler_MemoryImportExport() { var module = new Module(); module.Memories.Add(new Memory(0, 1)); module.Imports.Add(new Import.Memory { Field = "Memory", Module = "Memory", Type = new Memory(0, 1) }); module.Exports.Add(new Export { Name = "Memory", Kind = ExternalKind.Memory, }); var roundMemory = module.ToInstance <dynamic>(new[] { new MemoryImport("Memory", "Memory", typeof(CompilerTests).GetMethod(nameof(GetMemoryFor_Compiler_MemoryImportExport))) }).Exports.Memory as Runtime.UnmanagedMemory; Assert.IsNotNull(roundMemory); Assert.AreSame(memory, roundMemory); }
public void Compile_GlobalMutableImportExport() { var module = new Module(); module.Imports.Add(new Import.Global { Module = "Imported", Field = "Global", ContentType = WebAssemblyValueType.Int32, IsMutable = true, }); module.Exports.Add(new Export { Name = "Test", Kind = ExternalKind.Global, }); var compiled = module.ToInstance <CompilerTestBaseExportedMutableGlobal <int> >( new ImportDictionary { { "Imported", "Global", new GlobalImport(() => MutableGlobal, value => MutableGlobal = value) }, }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; Assert.AreEqual(0, instance.Test); const int passedThroughImport = 5; MutableGlobal = passedThroughImport; Assert.AreEqual(passedThroughImport, instance.Test); const int passedThroughExport = 7; instance.Test = passedThroughExport; Assert.AreEqual(passedThroughExport, MutableGlobal); }
public void Compiler_GithubIssue4_Locals() { var module = new Module(); module.Types.Add(new Type { Returns = new[] { ValueType.Int32, } }); module.Functions.Add(new Function { }); module.Exports.Add(new Export { Name = "Test", }); module.Codes.Add(new FunctionBody { Locals = new[] { new Local { Count = 1, Type = ValueType.Int32, } }, Code = new Instruction[] { new GetLocal(0), new End(), } }); var compiled = module.ToInstance <dynamic>(); Assert.AreEqual(0, (int)compiled.Exports.Test()); }
public void Compile_GlobalMutableImportExport() { var module = new Module(); module.Imports.Add(new Import.Global { Module = "Imported", Field = "Global", ContentType = ValueType.Int32, IsMutable = true, }); module.Exports.Add(new Export { Name = "Test", Kind = ExternalKind.Global, }); var compiled = module.ToInstance <CompilerTestBaseExportedMutableGlobal <int> >( new RuntimeImport[] { new GlobalImport("Imported", "Global", typeof(GlobalImportTests).GetTypeInfo().GetProperty(nameof(MutableGlobal))) }); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); var instance = compiled.Exports; Assert.AreEqual(0, instance.Test); const int passedThroughImport = 5; MutableGlobal = passedThroughImport; Assert.AreEqual(passedThroughImport, instance.Test); const int passedThroughExport = 7; instance.Test = passedThroughExport; Assert.AreEqual(passedThroughExport, MutableGlobal); }
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 }); var compiled = module.ToInstance <TExport>(); Assert.IsNotNull(compiled); Assert.IsNotNull(compiled.Exports); return(compiled.Exports); }
public void Compiler_StartSection() { var module = new Module(); module.Memories.Add(new Memory(1, 1)); module.Types.Add(new Type { }); module.Types.Add(new Type { Returns = new[] { ValueType.Int32, } }); module.Functions.Add(new Function { }); module.Functions.Add(new Function { Type = 1, }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new Int32Constant(1), new Int32Constant(2), new Int32Store(), new End(), }, }); module.Codes.Add(new FunctionBody { Code = new Instruction[] { new Int32Constant(1), new Int32Load(), new End(), }, }); module.Start = 0; module.Exports.Add(new Export { Index = 1, Name = "Test", }); var compiled = module.ToInstance <dynamic>(); Assert.IsNotNull(compiled); using (compiled) { Assert.AreEqual <int>(2, compiled.Exports.Test()); } }
public void Compile_Empty() { var module = new Module(); module.ToInstance <object>(); }