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