/// <summary> /// Instantiates the given WebAssembly file. An importer is used to /// resolve module imports and an interpreter is used to interpret /// instructions. /// </summary> /// <param name="File">The file to instantiate.</param> /// <param name="Importer">Resolves module imports.</param> /// <param name="Interpreter">Interprets instructions.</param> /// <returns>A module instance.</returns> public static ModuleInstance Instantiate( WasmFile File, IImporter Importer, InstructionInterpreter Interpreter) { var instance = new ModuleInstance(Interpreter); // Extract the function types. var allFuncTypes = GetFunctionTypes(File); // Resolve all imports. instance.ResolveImports(File, Importer, allFuncTypes); // Instantiate global variables. instance.InstantiateGlobals(File); // Instantiate memories. instance.InstantiateMemories(File); // Instantiate function definitions. instance.InstantiateFunctionDefs(File, allFuncTypes); // Instantiate function tables. instance.InstantiateTables(File); // Export values. instance.RegisterExports(File); return(instance); }
private ModuleInstance(InstructionInterpreter Interpreter) { this.Interpreter = Interpreter; this.definedMemories = new List <LinearMemory>(); this.definedGlobals = new List <Variable>(); this.definedFuncs = new List <FunctionDefinition>(); this.definedTables = new List <FunctionTable>(); this.expMemories = new Dictionary <string, LinearMemory>(); this.expGlobals = new Dictionary <string, Variable>(); this.expFuncs = new Dictionary <string, FunctionDefinition>(); this.expTables = new Dictionary <string, FunctionTable>(); }
private ModuleInstance(InstructionInterpreter interpreter, ExecutionPolicy policy) { this.Interpreter = interpreter; this.Policy = policy; this.definedTypes = new List <FunctionType>(); this.definedMemories = new List <LinearMemory>(); this.definedGlobals = new List <Variable>(); this.definedFuncs = new List <FunctionDefinition>(); this.definedTables = new List <FunctionTable>(); this.expMemories = new Dictionary <string, LinearMemory>(); this.expGlobals = new Dictionary <string, Variable>(); this.expFuncs = new Dictionary <string, FunctionDefinition>(); this.expTables = new Dictionary <string, FunctionTable>(); }
/// <summary> /// Instantiates the given WebAssembly file. /// </summary> /// <param name="file">The file to instantiate.</param> /// <param name="importer">The importer to use to resolve module imports.</param> /// <param name="interpreter"> /// Interprets instructions. A <c>null</c> interpreter indicates that the default interpreter should be used. /// </param> /// <param name="policy"> /// The execution policy to adhere to for this module. /// A <c>null</c> execution policy indicates that the default policy should be used. /// </param> /// <param name="compiler"> /// Creates a new instance of a module compiler to use. /// </param> /// <returns>A module instance.</returns> public static ModuleInstance Instantiate( WasmFile file, IImporter importer, InstructionInterpreter interpreter = null, ExecutionPolicy policy = null, Func <ModuleCompiler> compiler = null) { if (interpreter == null) { interpreter = DefaultInstructionInterpreter.Default; } if (policy == null) { policy = ExecutionPolicy.Create(); } if (compiler == null) { compiler = () => new InterpreterCompiler(); } var instance = new ModuleInstance(interpreter, policy); // Extract the function types. var allFuncTypes = GetFunctionTypes(file); instance.definedTypes.AddRange(allFuncTypes); // Resolve all imports. instance.ResolveImports(file, importer, allFuncTypes); // Instantiate global variables. instance.InstantiateGlobals(file); // Instantiate memories. instance.InstantiateMemories(file, policy.MaxMemorySize); // Instantiate function definitions. instance.InstantiateFunctionDefs(file, compiler(), allFuncTypes); // Instantiate function tables. instance.InstantiateTables(file); // Export values. instance.RegisterExports(file); return(instance); }
public static int Main(string[] args) { // Read command-line arguments. InterpreterArguments parsedArgs; if (!InterpreterArguments.TryRead(args, out parsedArgs)) { return(PrintUsage()); } IImporter importer; if (!parsedArgs.TryGetImporter(out importer)) { Console.Error.WriteLine("error: there is no importer named '" + parsedArgs.ImporterName + "'"); return(1); } // Read and instantiate the module. var wasmFile = WasmFile.ReadBinary(parsedArgs.WasmFilePath); InstructionInterpreter interp = DefaultInstructionInterpreter.Default; if (parsedArgs.TraceExecution) { interp = new TracingInstructionInterpreter(interp, Console.Error); } var module = ModuleInstance.Instantiate(wasmFile, importer, interp); // Figure out which function to run. FunctionDefinition funcToRun = null; if (parsedArgs.FunctionToRun != null) { if (!module.ExportedFunctions.TryGetValue(parsedArgs.FunctionToRun, out funcToRun)) { Console.Error.WriteLine( "error: module does not export a function named '" + parsedArgs.FunctionToRun + "'"); return(1); } } else { var startSec = wasmFile.GetFirstSectionOrNull <StartSection>(); if (startSec == null) { Console.Error.WriteLine( "error: module does not define a 'start' section " + " and '--run exported_func_name' was not specified."); return(1); } else { IReadOnlyList <FunctionDefinition> funcs = module.Functions; funcToRun = funcs[(int)startSec.StartFunctionIndex]; } } // Run that function. int exitCode = 0; try { IReadOnlyList <object> output = funcToRun.Invoke(parsedArgs.FunctionArgs); if (output.Count > 0) { for (int i = 0; i < output.Count; i++) { if (i > 0) { Console.Write(" "); } Console.Write(output[i]); } Console.WriteLine(); } } catch (WasmException ex) { Console.Error.WriteLine("error: " + ex.Message); exitCode = 1; } return(exitCode); }
/// <summary> /// Creates a tracing instruction interpreter from the given inner interpreter /// and a trace writer. /// </summary> /// <param name="interpreter">The inner interpreter that is used to run instructions.</param> /// <param name="traceWriter">The text writer to which execution traces are written.</param> public TracingInstructionInterpreter( InstructionInterpreter interpreter, TextWriter traceWriter) { this.Interpreter = interpreter; this.TraceWriter = traceWriter; }
/// <summary> /// Creates a tracing instruction interpreter from the given inner interpreter /// and a trace writer. /// </summary> /// <param name="Interpreter">The inner interpreter that is used to run instructions.</param> /// <param name="TraceWriter">The text writer to which execution traces are written.</param> public TracingInstructionInterpreter( InstructionInterpreter Interpreter, TextWriter TraceWriter) { this.Interpreter = Interpreter; this.TraceWriter = TraceWriter; }