Example #1
0
        /// <summary>
        /// Instantiates the tables in the given WebAssembly file.
        /// </summary>
        /// <param name="File">The file whose tables are to be instantiated.</param>
        private void InstantiateTables(WasmFile File)
        {
            // Create module-defined tables.
            var allTableSections = File.GetSections <TableSection>();

            for (int i = 0; i < allTableSections.Count; i++)
            {
                foreach (var tableSpec in allTableSections[i].Tables)
                {
                    definedTables.Add(new FunctionTable(tableSpec.Limits));
                }
            }

            // Initialize tables by applying the segments defined by element sections.
            var allElementSections = File.GetSections <ElementSection>();

            for (int i = 0; i < allElementSections.Count; i++)
            {
                foreach (var segment in allElementSections[i].Segments)
                {
                    var table      = Tables[(int)segment.TableIndex];
                    var evalOffset = Evaluate <int>(segment.Offset);
                    for (int j = 0; j < segment.Elements.Count; j++)
                    {
                        table[(uint)(evalOffset + j)] = definedFuncs[(int)segment.Elements[j]];
                    }
                }
            }
        }
Example #2
0
        private void InstantiateMemories(WasmFile File)
        {
            // Create module-defined memories.
            var allMemorySections = File.GetSections <MemorySection>();

            for (int i = 0; i < allMemorySections.Count; i++)
            {
                var memorySection = allMemorySections[i];
                foreach (var memorySpec in memorySection.Memories)
                {
                    definedMemories.Add(new LinearMemory(memorySpec.Limits));
                }
            }

            // Initialize memories by applying the segments defined by data sections.
            var allDataSections = File.GetSections <DataSection>();

            for (int i = 0; i < allDataSections.Count; i++)
            {
                var dataSection = allDataSections[i];
                foreach (var segment in dataSection.Segments)
                {
                    var memoryView = Memories[(int)segment.MemoryIndex].Int8;
                    var evalOffset = Evaluate <int>(segment.Offset);
                    for (int j = 0; j < segment.Data.Length; j++)
                    {
                        memoryView[(uint)(evalOffset + j)] = (sbyte)segment.Data[j];
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Instantiates all function definitions from the given WebAssembly file.
        /// </summary>
        /// <param name="File">A WebAssembly file.</param>
        /// <param name="FunctionTypes">The list of all function types declared by the WebAssembly file.</param>
        private void InstantiateFunctionDefs(WasmFile File, List <FunctionType> FunctionTypes)
        {
            var funcSignatures = new List <FunctionType>();
            var funcBodies     = new List <FunctionBody>();

            var allFuncSections = File.GetSections <FunctionSection>();

            for (int i = 0; i < allFuncSections.Count; i++)
            {
                foreach (var funcSpec in allFuncSections[i].FunctionTypes)
                {
                    funcSignatures.Add(FunctionTypes[(int)funcSpec]);
                }
            }

            var allCodeSections = File.GetSections <CodeSection>();

            for (int i = 0; i < allCodeSections.Count; i++)
            {
                funcBodies.AddRange(allCodeSections[i].Bodies);
            }

            if (funcSignatures.Count != funcBodies.Count)
            {
                throw new WasmException(
                          "Function declaration/definition count mismatch: module declares " +
                          funcSignatures.Count + " functions and defines " + funcBodies.Count + ".");
            }

            for (int i = 0; i < funcSignatures.Count; i++)
            {
                DefineFunction(funcSignatures[i], funcBodies[i]);
            }
        }
Example #4
0
        /// <summary>
        /// Exports values specified by the given WebAssembly file.
        /// </summary>
        /// <param name="File">The file that specifies which values are to be exported and how.</param>
        private void RegisterExports(WasmFile File)
        {
            var allExportSections = File.GetSections <ExportSection>();

            for (int i = 0; i < allExportSections.Count; i++)
            {
                foreach (var export in allExportSections[i].Exports)
                {
                    switch (export.Kind)
                    {
                    case ExternalKind.Memory:
                        expMemories[export.Name] = Memories[(int)export.Index];
                        break;

                    case ExternalKind.Global:
                        expGlobals[export.Name] = Globals[(int)export.Index];
                        break;

                    case ExternalKind.Function:
                        expFuncs[export.Name] = Functions[(int)export.Index];
                        break;

                    case ExternalKind.Table:
                        expTables[export.Name] = Tables[(int)export.Index];
                        break;

                    default:
                        throw new WasmException("Unknown export kind: " + export.Kind);
                    }
                }
            }
        }
Example #5
0
        private void InstantiateMemories(WasmFile file, uint maxMemorySize)
        {
            // Create module-defined memories.
            var allMemorySections = file.GetSections <MemorySection>();

            for (int i = 0; i < allMemorySections.Count; i++)
            {
                var memorySection = allMemorySections[i];
                foreach (var memorySpec in memorySection.Memories)
                {
                    if (maxMemorySize == 0)
                    {
                        definedMemories.Add(new LinearMemory(memorySpec.Limits));
                    }
                    else
                    {
                        definedMemories.Add(
                            new LinearMemory(
                                new ResizableLimits(
                                    memorySpec.Limits.Initial,
                                    memorySpec.Limits.HasMaximum
                                        ? Math.Min(memorySpec.Limits.Maximum.Value, maxMemorySize)
                                        : maxMemorySize)));
                    }
                }
            }

            // Initialize memories by applying the segments defined by data sections.
            var allDataSections = file.GetSections <DataSection>();

            for (int i = 0; i < allDataSections.Count; i++)
            {
                var dataSection = allDataSections[i];
                foreach (var segment in dataSection.Segments)
                {
                    var memoryView = Memories[(int)segment.MemoryIndex].Int8;
                    var evalOffset = Evaluate <int>(segment.Offset);
                    for (int j = 0; j < segment.Data.Length; j++)
                    {
                        memoryView[(uint)(evalOffset + j)] = (sbyte)segment.Data[j];
                    }
                }
            }
        }
Example #6
0
        /// <summary>
        /// Uses the given importer to resolve all imported values.
        /// </summary>
        /// <param name="Importer">The importer.</param>
        private void ResolveImports(
            WasmFile File,
            IImporter Importer,
            List <FunctionType> FunctionTypes)
        {
            var allImportSections = File.GetSections <ImportSection>();

            for (int i = 0; i < allImportSections.Count; i++)
            {
                var importSection = allImportSections[i];
                foreach (var import in importSection.Imports)
                {
                    if (import is ImportedMemory)
                    {
                        var memory = Importer.ImportMemory((ImportedMemory)import);
                        if (memory == null)
                        {
                            ThrowCannotResolveImport(import, "linear memory");
                        }
                        definedMemories.Add(memory);
                    }
                    else if (import is ImportedGlobal)
                    {
                        var globalVar = Importer.ImportGlobal((ImportedGlobal)import);
                        if (globalVar == null)
                        {
                            ThrowCannotResolveImport(import, "global variable");
                        }
                        definedGlobals.Add(globalVar);
                    }
                    else if (import is ImportedFunction)
                    {
                        var funcImport = (ImportedFunction)import;
                        var funcDef    = Importer.ImportFunction(funcImport, FunctionTypes[(int)funcImport.TypeIndex]);
                        if (funcDef == null)
                        {
                            ThrowCannotResolveImport(import, "function");
                        }
                        definedFuncs.Add(funcDef);
                    }
                    else if (import is ImportedTable)
                    {
                        var table = Importer.ImportTable((ImportedTable)import);
                        if (table == null)
                        {
                            ThrowCannotResolveImport(import, "table");
                        }
                        definedTables.Add(table);
                    }
                    else
                    {
                        throw new WasmException("Unknown import type: " + import.ToString());
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// Gets a list of all function types declared by the given WebAssembly file.
        /// </summary>
        /// <param name="File">The WebAssembly file to examine.</param>
        /// <returns>The list of function types.</returns>
        private static List <FunctionType> GetFunctionTypes(WasmFile File)
        {
            var allFuncTypes    = new List <FunctionType>();
            var allTypeSections = File.GetSections <TypeSection>();

            for (int i = 0; i < allTypeSections.Count; i++)
            {
                allFuncTypes.AddRange(allTypeSections[i].FunctionTypes);
            }
            return(allFuncTypes);
        }
Example #8
0
        /// <summary>
        /// Rewrites function type references in the given WebAssembly file
        /// by replacing keys from the rewrite map with their corresponding
        /// values.
        /// </summary>
        /// <param name="File">The WebAssembly file to rewrite.</param>
        /// <param name="RewriteMap">A mapping of original type indices to new type indices.</param>
        public static void RewriteFunctionTypeReferences(
            this WasmFile File,
            IReadOnlyDictionary <uint, uint> RewriteMap)
        {
            // Type references occur only in the import and function sections.
            var importSections = File.GetSections <ImportSection>();

            for (int i = 0; i < importSections.Count; i++)
            {
                var importSec = importSections[i];
                for (int j = 0; j < importSec.Imports.Count; j++)
                {
                    var  importDecl = importSec.Imports[j] as ImportedFunction;
                    uint newIndex;
                    if (importDecl != null && RewriteMap.TryGetValue(importDecl.TypeIndex, out newIndex))
                    {
                        importDecl.TypeIndex = newIndex;
                    }
                }
            }

            var funcSections = File.GetSections <FunctionSection>();

            for (int i = 0; i < funcSections.Count; i++)
            {
                var funcSec = funcSections[i];
                for (int j = 0; j < funcSec.FunctionTypes.Count; j++)
                {
                    uint newIndex;
                    if (RewriteMap.TryGetValue(funcSec.FunctionTypes[j], out newIndex))
                    {
                        funcSec.FunctionTypes[j] = newIndex;
                    }
                }
            }
        }
Example #9
0
        /// <summary>
        /// Instantiates all function definitions from the given WebAssembly file.
        /// </summary>
        /// <param name="file">A WebAssembly file.</param>
        /// <param name="compiler">A compiler to use for instantiating function definitions.</param>
        /// <param name="functionTypes">The list of all function types declared by the WebAssembly file.</param>
        private void InstantiateFunctionDefs(WasmFile file, ModuleCompiler compiler, List <FunctionType> functionTypes)
        {
            var funcSignatures = new List <FunctionType>();
            var funcBodies     = new List <FunctionBody>();

            var allFuncSections = file.GetSections <FunctionSection>();

            for (int i = 0; i < allFuncSections.Count; i++)
            {
                foreach (var funcSpec in allFuncSections[i].FunctionTypes)
                {
                    funcSignatures.Add(functionTypes[(int)funcSpec]);
                }
            }

            var allCodeSections = file.GetSections <CodeSection>();

            for (int i = 0; i < allCodeSections.Count; i++)
            {
                funcBodies.AddRange(allCodeSections[i].Bodies);
            }

            if (funcSignatures.Count != funcBodies.Count)
            {
                throw new WasmException(
                          "Function declaration/definition count mismatch: module declares " +
                          funcSignatures.Count + " functions and defines " + funcBodies.Count + ".");
            }

            compiler.Initialize(this, definedFuncs.Count, funcSignatures);
            for (int i = 0; i < funcSignatures.Count; i++)
            {
                DefineFunction(compiler.Compile(i, funcBodies[i]));
            }
            compiler.Finish();
        }
Example #10
0
        private void InstantiateGlobals(WasmFile File)
        {
            // Create module-defined globals.
            var allGlobalSections = File.GetSections <GlobalSection>();

            for (int i = 0; i < allGlobalSections.Count; i++)
            {
                var globalSection = allGlobalSections[i];
                foreach (var globalSpec in globalSection.GlobalVariables)
                {
                    definedGlobals.Add(
                        Variable.Create <object>(
                            globalSpec.Type.ContentType,
                            globalSpec.Type.IsMutable,
                            Evaluate <object>(globalSpec.InitialValue)));
                }
            }
        }