Example #1
0
        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());
        }
Example #2
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #15
0
        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);
        }
Example #25
0
        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>();
        }