internal static object Interpret (InterpretedFunction ifun, Context cx, IScriptable scope, IScriptable thisObj, object [] args)
        {
            using (Helpers.StackOverflowVerifier sov = new Helpers.StackOverflowVerifier (128)) {
                if (!ScriptRuntime.hasTopCall (cx))
                    Context.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;
                    }
                }

                CallFrame frame = new CallFrame ();
                initFrame (cx, scope, thisObj, args, null, 0, args.Length, ifun, null, frame);

                return InterpretLoop (cx, frame, (object)null);
            }
        }
        static void initFrame (Context cx, IScriptable callerScope, IScriptable thisObj, object [] args, double [] argsDbl, int argShift, int argCount, InterpretedFunction fnOrScript, CallFrame parentFrame, CallFrame frame)
        {
            InterpreterData idata = fnOrScript.idata;

            bool useActivation = idata.itsNeedsActivation;
            DebugFrame debuggerFrame = null;
            if (cx.m_Debugger != null) {
                debuggerFrame = cx.m_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;
            }

            IScriptable scope;
            if (idata.itsFunctionType != 0) {
                if (!idata.useDynamicScope) {
                    scope = fnOrScript.ParentScope;
                }
                else {
                    scope = callerScope;
                }

                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)
                    Context.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);
                    }
                }
            }

            IScriptable [] scriptRegExps = null;
            if (idata.itsRegExpLiterals != null) {
                // Wrapped regexps for functions are stored in
                // InterpretedFunction
                // but for script which should not contain references to scope
                // the regexps re-wrapped during each script execution
                if (idata.itsFunctionType != 0) {
                    scriptRegExps = fnOrScript.functionRegExps;
                }
                else {
                    scriptRegExps = fnOrScript.createRegExpWraps (cx, scope);
                }
            }

            // Initialize args, vars, locals and stack

            int emptyStackTop = idata.itsMaxVars + idata.itsMaxLocals - 1;
            int maxFrameArray = idata.itsMaxFrameArray;
            if (maxFrameArray != emptyStackTop + idata.itsMaxStack + 1)
                Context.CodeBug ();

            object [] stack;
            double [] sDbl;
            bool stackReuse;
            if (frame.stack != null && maxFrameArray <= frame.stack.Length) {
                // Reuse stacks from old frame
                stackReuse = true;
                stack = frame.stack;
                sDbl = frame.sDbl;
            }
            else {
                stackReuse = false;
                stack = new object [maxFrameArray];
                sDbl = new double [maxFrameArray];
            }

            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.MaximumInterpreterStackDepth)
                throw ScriptRuntime.TypeErrorById ("msg.stackoverflow");
            frame.frozen = false;

            frame.fnOrScript = fnOrScript;
            frame.idata = idata;

            frame.stack = stack;
            frame.sDbl = sDbl;
            frame.varSource = frame;
            frame.localShift = idata.itsMaxVars;
            frame.emptyStackTop = emptyStackTop;

            frame.debuggerFrame = debuggerFrame;
            frame.useActivation = useActivation;

            frame.thisObj = thisObj;
            frame.scriptRegExps = scriptRegExps;

            // Initialize initial values of variables that change during
            // interpretation.
            frame.result = Undefined.Value;
            frame.pc = 0;
            frame.pcPrevBranch = 0;
            frame.pcSourceLineStart = idata.firstLinePC;
            frame.scope = scope;

            frame.savedStackTop = emptyStackTop;
            frame.savedCallOp = 0;

            Array.Copy (args, argShift, stack, 0, definedArgs);
            if (argsDbl != null) {
                Array.Copy (argsDbl, argShift, sDbl, 0, definedArgs);
            }
            for (int i = definedArgs; i != idata.itsMaxVars; ++i) {
                stack [i] = Undefined.Value;
            }
            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 != stack.Length; ++i) {
                    stack [i] = null;
                }
            }

            EnterFrame (cx, frame, args);
        }
 static void initFunction (Context cx, IScriptable 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 InterpretedFunction(InterpretedFunction parent, int index)
 {
     this.idata = parent.idata.itsNestedFunctions [index];
     this.securityController = parent.securityController;
     this.securityDomain = parent.securityDomain;
 }
 /// <summary> Create script from compiled bytecode.</summary>
 internal static InterpretedFunction createScript(InterpreterData idata, object staticSecurityDomain)
 {
     InterpretedFunction f;
     f = new InterpretedFunction (idata, staticSecurityDomain);
     return f;
 }
 /// <summary> Create function embedded in script or another function.</summary>
 internal static InterpretedFunction createFunction(Context cx, IScriptable scope, InterpretedFunction parent, int index)
 {
     InterpretedFunction f = new InterpretedFunction (parent, index);
     f.initInterpretedFunction (cx, scope);
     return f;
 }
 /// <summary> Create function compiled from Function(...) constructor.</summary>
 internal static InterpretedFunction createFunction(Context cx, IScriptable scope, InterpreterData idata, object staticSecurityDomain)
 {
     InterpretedFunction f;
     f = new InterpretedFunction (idata, staticSecurityDomain);
     f.initInterpretedFunction (cx, scope);
     return f;
 }