Пример #1
0
        private InterpreterContext InterpretBodyImpl(uint callStackDepth, List <Variable> locals)
        {
            var context     = new InterpreterContext(Module, ReturnTypes, locals, Module.Policy, callStackDepth + 1);
            var interpreter = Module.Interpreter;

            foreach (var instruction in body.BodyInstructions)
            {
                interpreter.Interpret(instruction, context);
                if (context.BreakRequested)
                {
                    // Functions can use a break to return. This acts exactly like
                    // a regular return.
                    OperatorImpls.Return(context);
                    break;
                }
            }
            context.Return();
            return(context);
        }
Пример #2
0
        /// <summary>
        /// Invokes this function with the given argument list.
        /// </summary>
        /// <param name="Arguments">The list of arguments for this function's parameters.</param>
        /// <returns>The list of return values.</returns>
        public override IReadOnlyList <object> Invoke(IReadOnlyList <object> Arguments)
        {
            var locals = new List <Variable>();

            // Check argument types and create parameter variables.
            if (Signature.ParameterTypes.Count != Arguments.Count)
            {
                throw new WasmException(
                          "Function arity mismatch: function has " + Signature.ParameterTypes.Count +
                          " parameters and is given " + Arguments.Count + " arguments.");
            }

            // Turn each argument into a variable.
            for (int i = 0; i < Signature.ParameterTypes.Count; i++)
            {
                locals.Add(Variable.Create <object>(Signature.ParameterTypes[i], true, Arguments[i]));
            }

            // Turn each local into a variable.
            foreach (var localEntry in body.Locals)
            {
                for (int i = 0; i < localEntry.LocalCount; i++)
                {
                    locals.Add(Variable.CreateDefault(localEntry.LocalType, true));
                }
            }

            // Interpret the function body.
            var context     = new InterpreterContext(Module, locals);
            var interpreter = Module.Interpreter;

            foreach (var instruction in body.BodyInstructions)
            {
                interpreter.Interpret(instruction, context);
            }
            context.Return();

            // Check return types.
            var retVals = context.ReturnValues;

            if (retVals.Count != Signature.ReturnTypes.Count)
            {
                throw new WasmException(
                          "Return value arity mismatch: function expects " + Signature.ReturnTypes.Count +
                          " return values but is given " + retVals.Count + " return values.");
            }

            for (int i = 0; i < retVals.Count; i++)
            {
                if (!Variable.IsInstanceOf <object>(retVals[i], Signature.ReturnTypes[i]))
                {
                    throw new WasmException(
                              "Return type mismatch: function has return type '" +
                              ((object)Signature.ReturnTypes[i]).ToString() +
                              " but is given a return value of type '" +
                              retVals[i].GetType().Name + "'.");
                }
            }

            return(retVals);
        }