예제 #1
0
        /// <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);
        }
예제 #2
0
 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>();
 }
예제 #3
0
 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>();
 }
예제 #4
0
        /// <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);
        }
예제 #5
0
        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);
        }
예제 #6
0
 /// <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;
 }
예제 #7
0
 /// <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;
 }