예제 #1
0
 /// <summary>
 /// Creates a new interpreter context from the given module, return types
 /// and list of local variables.
 /// </summary>
 /// <param name="module">The owning module.</param>
 /// <param name="returnTypes">The list of expected return types.</param>
 /// <param name="locals">The list of local variables in this context.</param>
 public InterpreterContext(
     ModuleInstance module,
     IReadOnlyList <WasmValueType> returnTypes,
     IReadOnlyList <Variable> locals)
     : this(module, returnTypes, locals, ExecutionPolicy.Create())
 {
 }
예제 #2
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);
        }
예제 #3
0
 /// <summary>
 /// Creates a new interpreter context from the given module and list of
 /// local variables.
 /// </summary>
 /// <param name="module">The owning module.</param>
 /// <param name="locals">The list of local variables in this context.</param>
 public InterpreterContext(ModuleInstance module, IReadOnlyList <Variable> locals)
 {
     this.Module       = module;
     this.Locals       = locals;
     this.valStack     = new Stack <object>();
     this.ReturnValues = null;
     this.BreakDepth   = -1;
 }
예제 #4
0
 /// <summary>
 /// Creates a WebAssembly function definition from the given signature,
 /// function body and declaring module.
 /// </summary>
 /// <param name="Signature">The function's signature.</param>
 /// <param name="Body">The function's body.</param>
 /// <param name="Module">The declaring module.</param>
 public WasmFunctionDefinition(
     FunctionType Signature,
     FunctionBody Body,
     ModuleInstance Module)
 {
     this.Signature = Signature;
     this.body      = Body;
     this.Module    = Module;
 }
 /// <summary>
 /// Creates a WebAssembly function definition from the given signature,
 /// function body and declaring module.
 /// </summary>
 /// <param name="signature">The function's signature.</param>
 /// <param name="body">The function's body.</param>
 /// <param name="module">The declaring module.</param>
 public WasmFunctionDefinition(
     FunctionType signature,
     FunctionBody body,
     ModuleInstance module)
 {
     this.Signature = signature;
     this.body      = body;
     this.Module    = module;
 }
예제 #6
0
 /// <summary>
 /// Creates a new interpreter context from the given module, return types
 /// and list of local variables.
 /// </summary>
 /// <param name="module">The owning module.</param>
 /// <param name="returnTypes">The list of expected return types.</param>
 /// <param name="locals">The list of local variables in this context.</param>
 /// <param name="policy">The execution policy to use.</param>
 /// <param name="callStackDepth">
 /// The current depth of the call stack.
 /// </param>
 public InterpreterContext(
     ModuleInstance module,
     IReadOnlyList <WasmValueType> returnTypes,
     IReadOnlyList <Variable> locals,
     ExecutionPolicy policy,
     uint callStackDepth = 0)
 {
     this.Module         = module;
     this.ReturnTypes    = returnTypes;
     this.Locals         = locals;
     this.Policy         = policy;
     this.valStack       = new Stack <object>();
     this.ReturnValues   = null;
     this.BreakDepth     = -1;
     this.CallStackDepth = callStackDepth;
 }
예제 #7
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);
        }
예제 #8
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);
        }
예제 #9
0
 /// <summary>
 /// Creates a new interpreter context from the given module.
 /// </summary>
 /// <param name="module">The owning module.</param>
 public InterpreterContext(ModuleInstance module)
     : this(module, new Variable[0])
 {
 }
예제 #10
0
 /// <summary>
 /// Creates an importer for a module's exports.
 /// </summary>
 /// <param name="module">A module whose exports are imported by the resulting importer.</param>
 public ModuleExportsImporter(ModuleInstance module)
 {
     this.Module = module;
 }
예제 #11
0
 /// <summary>
 /// Creates a new interpreter context from the given module and
 /// expected return types.
 /// </summary>
 /// <param name="module">The owning module.</param>
 /// <param name="returnTypes">The list of expected return types.</param>
 public InterpreterContext(ModuleInstance module, IReadOnlyList <WasmValueType> returnTypes)
     : this(module, returnTypes, new Variable[0])
 {
 }
예제 #12
0
 /// <inheritdoc/>
 public override void Initialize(ModuleInstance module, int offset, IReadOnlyList <FunctionType> types)
 {
     this.module = module;
     this.types  = types;
 }
예제 #13
0
 /// <summary>
 /// Declares all functions in a module.
 /// </summary>
 /// <param name="module">The module to declare functions for.</param>
 /// <param name="offset">The index of the first function to define.</param>
 /// <param name="types">A list of function types, one for each function declaration.</param>
 public abstract void Initialize(ModuleInstance module, int offset, IReadOnlyList <FunctionType> types);