GetMaximumInterpreterStackDepth() public method

Returns the maximum stack depth (in terms of number of call frames) allowed in a single invocation of interpreter.
Returns the maximum stack depth (in terms of number of call frames) allowed in a single invocation of interpreter. If the set depth would be exceeded, the interpreter will throw an EvaluatorException in the script. Defaults to Integer.MAX_VALUE. The setting only has effect for interpreted functions (those compiled with optimization level set to -1). As the interpreter doesn't use the Java stack but rather manages its own stack in the heap memory, a runaway recursion in interpreted code would eventually consume all available memory and cause OutOfMemoryError instead of a StackOverflowError limited to only a single thread. This setting helps prevent such situations.
public GetMaximumInterpreterStackDepth ( ) : int
return int
Example #1
0
		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);
		}