/// <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);
     }
 }
Пример #2
0
        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));
        }
Пример #3
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);
        }
Пример #5
0
        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();
        }
Пример #6
0
        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);
            }
        }
Пример #8
0
        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));
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
            }
        }
Пример #11
0
        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);
        }
Пример #12
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
            });

            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);
        }
Пример #13
0
        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());
        }
Пример #14
0
        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]);
        }
Пример #15
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);
            }
        }