/// <summary>Create function compiled from Function(...) constructor.</summary> /// <remarks>Create function compiled from Function(...) constructor.</remarks> internal static Rhino.InterpretedFunction CreateFunction(Context cx, Scriptable scope, InterpreterData idata, object staticSecurityDomain) { Rhino.InterpretedFunction f; f = new Rhino.InterpretedFunction(idata, staticSecurityDomain); f.InitScriptFunction(cx, scope); return f; }
internal static object Interpret(InterpretedFunction ifun, Context cx, Scriptable scope, Scriptable thisObj, object[] args) { if (!ScriptRuntime.HasTopCall(cx)) { Kit.CodeBug(); } if (cx.interpreterSecurityDomain != ifun.securityDomain) { object savedDomain = cx.interpreterSecurityDomain; cx.interpreterSecurityDomain = ifun.securityDomain; try { return ifun.securityController.CallWithDomain(ifun.securityDomain, cx, ifun, scope, thisObj, args); } finally { cx.interpreterSecurityDomain = savedDomain; } } Interpreter.CallFrame frame = new Interpreter.CallFrame(); InitFrame(cx, scope, thisObj, args, null, 0, args.Length, ifun, null, frame); frame.isContinuationsTopFrame = cx.isContinuationsTopCall; cx.isContinuationsTopCall = false; return InterpretLoop(cx, frame, null); }
private static void InitFunction(Context cx, Scriptable scope, InterpretedFunction parent, int index) { InterpretedFunction fn; fn = InterpretedFunction.CreateFunction(cx, scope, parent, index); ScriptRuntime.InitFunction(cx, scope, fn, fn.idata.itsFunctionType, parent.idata.evalScriptFlag); }
private static void InitFrame(Context cx, Scriptable callerScope, Scriptable thisObj, object[] args, double[] argsDbl, int argShift, int argCount, InterpretedFunction fnOrScript, Interpreter.CallFrame parentFrame, Interpreter.CallFrame frame) { InterpreterData idata = fnOrScript.idata; bool useActivation = idata.itsNeedsActivation; DebugFrame debuggerFrame = null; if (cx.debugger != null) { debuggerFrame = cx.debugger.GetFrame(cx, idata); if (debuggerFrame != null) { useActivation = true; } } if (useActivation) { // Copy args to new array to pass to enterActivationFunction // or debuggerFrame.onEnter if (argsDbl != null) { args = GetArgsArray(args, argsDbl, argShift, argCount); } argShift = 0; argsDbl = null; } Scriptable scope; if (idata.itsFunctionType != 0) { scope = fnOrScript.GetParentScope(); if (useActivation) { scope = ScriptRuntime.CreateFunctionActivation(fnOrScript, scope, args); } } else { scope = callerScope; ScriptRuntime.InitScript(fnOrScript, thisObj, cx, scope, fnOrScript.idata.evalScriptFlag); } if (idata.itsNestedFunctions != null) { if (idata.itsFunctionType != 0 && !idata.itsNeedsActivation) { Kit.CodeBug(); } for (int i = 0; i < idata.itsNestedFunctions.Length; i++) { InterpreterData fdata = idata.itsNestedFunctions[i]; if (fdata.itsFunctionType == FunctionNode.FUNCTION_STATEMENT) { InitFunction(cx, scope, fnOrScript, i); } } } // Initialize args, vars, locals and stack int emptyStackTop = idata.itsMaxVars + idata.itsMaxLocals - 1; int maxFrameArray = idata.itsMaxFrameArray; if (maxFrameArray != emptyStackTop + idata.itsMaxStack + 1) { Kit.CodeBug(); } object[] stack; int[] stackAttributes; double[] sDbl; bool stackReuse; if (frame.stack != null && maxFrameArray <= frame.stack.Length) { // Reuse stacks from old frame stackReuse = true; stack = frame.stack; stackAttributes = frame.stackAttributes; sDbl = frame.sDbl; } else { stackReuse = false; stack = new object[maxFrameArray]; stackAttributes = new int[maxFrameArray]; sDbl = new double[maxFrameArray]; } int varCount = idata.GetParamAndVarCount(); for (int i_1 = 0; i_1 < varCount; i_1++) { if (idata.GetParamOrVarConst(i_1)) { stackAttributes[i_1] = ScriptableObject.CONST; } } int definedArgs = idata.argCount; if (definedArgs > argCount) { definedArgs = argCount; } // Fill the frame structure frame.parentFrame = parentFrame; frame.frameIndex = (parentFrame == null) ? 0 : parentFrame.frameIndex + 1; if (frame.frameIndex > cx.GetMaximumInterpreterStackDepth()) { throw Context.ReportRuntimeError("Exceeded maximum stack depth"); } frame.frozen = false; frame.fnOrScript = fnOrScript; frame.idata = idata; frame.stack = stack; frame.stackAttributes = stackAttributes; frame.sDbl = sDbl; frame.varSource = frame; frame.localShift = idata.itsMaxVars; frame.emptyStackTop = emptyStackTop; frame.debuggerFrame = debuggerFrame; frame.useActivation = useActivation; frame.thisObj = thisObj; // Initialize initial values of variables that change during // interpretation. frame.result = Undefined.instance; frame.pc = 0; frame.pcPrevBranch = 0; frame.pcSourceLineStart = idata.firstLinePC; frame.scope = scope; frame.savedStackTop = emptyStackTop; frame.savedCallOp = 0; System.Array.Copy(args, argShift, stack, 0, definedArgs); if (argsDbl != null) { System.Array.Copy(argsDbl, argShift, sDbl, 0, definedArgs); } for (int i_2 = definedArgs; i_2 != idata.itsMaxVars; ++i_2) { stack[i_2] = Undefined.instance; } if (stackReuse) { // Clean the stack part and space beyond stack if any // of the old array to allow to GC objects there for (int i = emptyStackTop + 1; i_2 != stack.Length; ++i_2) { stack[i_2] = null; } } EnterFrame(cx, frame, args, false); }
private static Interpreter.CallFrame InitFrameForApplyOrCall(Context cx, Interpreter.CallFrame frame, int indexReg, object[] stack, double[] sDbl, int stackTop, int op, Scriptable calleeScope, IdFunctionObject ifun, InterpretedFunction iApplyCallable) { Scriptable applyThis; if (indexReg != 0) { object obj = stack[stackTop + 2]; if (obj == UniqueTag.DOUBLE_MARK) { obj = ScriptRuntime.WrapNumber(sDbl[stackTop + 2]); } applyThis = ScriptRuntime.ToObjectOrNull(cx, obj); } else { applyThis = null; } if (applyThis == null) { // This covers the case of args[0] == (null|undefined) as well. applyThis = ScriptRuntime.GetTopCallScope(cx); } if (op == Icode_TAIL_CALL) { ExitFrame(cx, frame, null); frame = frame.parentFrame; } else { frame.savedStackTop = stackTop; frame.savedCallOp = op; } Interpreter.CallFrame calleeFrame = new Interpreter.CallFrame(); if (BaseFunction.IsApply(ifun)) { object[] callArgs = indexReg < 2 ? ScriptRuntime.emptyArgs : ScriptRuntime.GetApplyArguments(cx, stack[stackTop + 3]); InitFrame(cx, calleeScope, applyThis, callArgs, null, 0, callArgs.Length, iApplyCallable, frame, calleeFrame); } else { // Shift args left for (int i = 1; i < indexReg; ++i) { stack[stackTop + 1 + i] = stack[stackTop + 2 + i]; sDbl[stackTop + 1 + i] = sDbl[stackTop + 2 + i]; } int argCount = indexReg < 2 ? 0 : indexReg - 1; InitFrame(cx, calleeScope, applyThis, stack, sDbl, stackTop + 2, argCount, iApplyCallable, frame, calleeFrame); } frame = calleeFrame; return frame; }
/// <summary>Call __noSuchMethod__.</summary> /// <remarks>Call __noSuchMethod__.</remarks> private static Interpreter.CallFrame InitFrameForNoSuchMethod(Context cx, Interpreter.CallFrame frame, int indexReg, object[] stack, double[] sDbl, int stackTop, int op, Scriptable funThisObj, Scriptable calleeScope, ScriptRuntime.NoSuchMethodShim noSuchMethodShim, InterpretedFunction ifun) { // create an args array from the stack object[] argsArray = null; // exactly like getArgsArray except that the first argument // is the method name from the shim int shift = stackTop + 2; object[] elements = new object[indexReg]; for (int i = 0; i < indexReg; ++i, ++shift) { object val = stack[shift]; if (val == UniqueTag.DOUBLE_MARK) { val = ScriptRuntime.WrapNumber(sDbl[shift]); } elements[i] = val; } argsArray = new object[2]; argsArray[0] = noSuchMethodShim.methodName; argsArray[1] = cx.NewArray(calleeScope, elements); // exactly the same as if it's a regular InterpretedFunction Interpreter.CallFrame callParentFrame = frame; Interpreter.CallFrame calleeFrame = new Interpreter.CallFrame(); if (op == Icode_TAIL_CALL) { callParentFrame = frame.parentFrame; ExitFrame(cx, frame, null); } // init the frame with the underlying method with the // adjusted args array and shim's function InitFrame(cx, calleeScope, funThisObj, argsArray, null, 0, 2, ifun, callParentFrame, calleeFrame); if (op != Icode_TAIL_CALL) { frame.savedStackTop = stackTop; frame.savedCallOp = op; } return calleeFrame; }
/// <summary>Create function embedded in script or another function.</summary> /// <remarks>Create function embedded in script or another function.</remarks> internal static Rhino.InterpretedFunction CreateFunction(Context cx, Scriptable scope, Rhino.InterpretedFunction parent, int index) { Rhino.InterpretedFunction f = new Rhino.InterpretedFunction(parent, index); f.InitScriptFunction(cx, scope); return f; }
/// <summary>Create script from compiled bytecode.</summary> /// <remarks>Create script from compiled bytecode.</remarks> internal static Rhino.InterpretedFunction CreateScript(InterpreterData idata, object staticSecurityDomain) { Rhino.InterpretedFunction f; f = new Rhino.InterpretedFunction(idata, staticSecurityDomain); return f; }