HasFeature() public method

Controls certain aspects of script semantics.
Controls certain aspects of script semantics. Should be overwritten to alter default behavior.

The default implementation calls ContextFactory.HasFeature(Context, int) that allows to customize Context behavior without introducing Context subclasses. ContextFactory documentation gives an example of hasFeature implementation.

public HasFeature ( int featureIndex ) : bool
featureIndex int feature index to check
return bool
Ejemplo n.º 1
0
		internal static Ref CreateSpecial(Context cx, object @object, string name)
		{
			Scriptable target = ScriptRuntime.ToObjectOrNull(cx, @object);
			if (target == null)
			{
				throw ScriptRuntime.UndefReadError(@object, name);
			}
			int type;
			if (name.Equals("__proto__"))
			{
				type = SPECIAL_PROTO;
			}
			else
			{
				if (name.Equals("__parent__"))
				{
					type = SPECIAL_PARENT;
				}
				else
				{
					throw new ArgumentException(name);
				}
			}
			if (!cx.HasFeature(Context.FEATURE_PARENT_PROTO_PROPERTIES))
			{
				// Clear special after checking for valid name!
				type = SPECIAL_NONE;
			}
			return new Rhino.SpecialRef(target, type, name);
		}
Ejemplo n.º 2
0
		public virtual void InitFromContext(Context cx)
		{
			SetErrorReporter(cx.GetErrorReporter());
			languageVersion = cx.GetLanguageVersion();
			generateDebugInfo = (!cx.IsGeneratingDebugChanged() || cx.IsGeneratingDebug());
			reservedKeywordAsIdentifier = cx.HasFeature(Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER);
			allowMemberExprAsFunctionName = cx.HasFeature(Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME);
			strictMode = cx.HasFeature(Context.FEATURE_STRICT_MODE);
			warningAsError = cx.HasFeature(Context.FEATURE_WARNING_AS_ERROR);
			xmlAvailable = cx.HasFeature(Context.FEATURE_E4X);
			optimizationLevel = cx.GetOptimizationLevel();
			generatingSource = cx.IsGeneratingSource();
			activationNames = cx.activationNames;
			// Observer code generation in compiled code :
			generateObserverCount = cx.generateObserverCount;
		}
Ejemplo n.º 3
0
		public static Scriptable WrapException(Exception t, Scriptable scope, Context cx)
		{
			RhinoException re;
			string errorName;
			string errorMsg;
			Exception javaException = null;
			if (t is EcmaError)
			{
				EcmaError ee = (EcmaError)t;
				re = ee;
				errorName = ee.GetName();
				errorMsg = ee.GetErrorMessage();
			}
			else
			{
				if (t is WrappedException)
				{
					WrappedException we = (WrappedException)t;
					re = we;
					javaException = we.GetWrappedException();
					errorName = "JavaException";
					errorMsg = javaException.GetType().FullName + ": " + javaException.Message;
				}
				else
				{
					if (t is EvaluatorException)
					{
						// Pure evaluator exception, nor WrappedException instance
						EvaluatorException ee = (EvaluatorException)t;
						re = ee;
						errorName = "InternalError";
						errorMsg = ee.Message;
					}
					else
					{
						if (cx.HasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS))
						{
							// With FEATURE_ENHANCED_JAVA_ACCESS, scripts can catch
							// all exception types
							re = new WrappedException(t);
							errorName = "JavaException";
							errorMsg = t.ToString();
						}
						else
						{
							// Script can catch only instances of JavaScriptException,
							// EcmaError and EvaluatorException
							throw Kit.CodeBug();
						}
					}
				}
			}
			string sourceUri = re.SourceName();
			if (sourceUri == null)
			{
				sourceUri = string.Empty;
			}
			int line = re.LineNumber();
			object[] args;
			if (line > 0)
			{
				args = new object[] { errorMsg, sourceUri, Sharpen.Extensions.ValueOf(line) };
			}
			else
			{
				args = new object[] { errorMsg, sourceUri };
			}
			Scriptable errorObject = cx.NewObject(scope, errorName, args);
			ScriptableObject.PutProperty(errorObject, "name", errorName);
			// set exception in Error objects to enable non-ECMA "stack" property
			if (errorObject is NativeError)
			{
				((NativeError)errorObject).SetStackProvider(re);
			}
			if (javaException != null && IsVisible(cx, javaException))
			{
				object wrap = cx.GetWrapFactory().Wrap(cx, scope, javaException, null);
				ScriptableObject.DefineProperty(errorObject, "javaException", wrap, ScriptableObject.PERMANENT | ScriptableObject.READONLY);
			}
			if (IsVisible(cx, re))
			{
				object wrap = cx.GetWrapFactory().Wrap(cx, scope, re, null);
				ScriptableObject.DefineProperty(errorObject, "rhinoException", wrap, ScriptableObject.PERMANENT | ScriptableObject.READONLY);
			}
			return errorObject;
		}
Ejemplo n.º 4
0
		public static object DoTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, object[] args)
		{
			if (scope == null)
			{
				throw new ArgumentException();
			}
			if (cx.topCallScope != null)
			{
				throw new InvalidOperationException();
			}
			object result;
			cx.topCallScope = ScriptableObject.GetTopLevelScope(scope);
			cx.useDynamicScope = cx.HasFeature(Context.FEATURE_DYNAMIC_SCOPE);
			ContextFactory f = cx.GetFactory();
			try
			{
				result = f.DoTopCall(callable, cx, scope, thisObj, args);
			}
			finally
			{
				cx.topCallScope = null;
				// Cleanup cached references
				cx.cachedXMLLib = null;
				if (cx.currentActivationCall != null)
				{
					// Function should always call exitActivationFunction
					// if it creates activation record
					throw new InvalidOperationException();
				}
			}
			return result;
		}
Ejemplo n.º 5
0
		/// <summary>The eval function property of the global object.</summary>
		/// <remarks>
		/// The eval function property of the global object.
		/// See ECMA 15.1.2.1
		/// </remarks>
		public static object EvalSpecial(Context cx, Scriptable scope, object thisArg, object[] args, string filename, int lineNumber)
		{
			if (args.Length < 1)
			{
				return Undefined.instance;
			}
			object x = args[0];
			if (!(x is CharSequence))
			{
				if (cx.HasFeature(Context.FEATURE_STRICT_MODE) || cx.HasFeature(Context.FEATURE_STRICT_EVAL))
				{
					throw Context.ReportRuntimeError0("msg.eval.nonstring.strict");
				}
				string message = ScriptRuntime.GetMessage0("msg.eval.nonstring");
				Context.ReportWarning(message);
				return x;
			}
			if (filename == null)
			{
				int[] linep = new int[1];
				filename = Context.GetSourcePositionFromStack(linep);
				if (filename != null)
				{
					lineNumber = linep[0];
				}
				else
				{
					filename = string.Empty;
				}
			}
			string sourceName = ScriptRuntime.MakeUrlForGeneratedScript(true, filename, lineNumber);
			ErrorReporter reporter;
			reporter = DefaultErrorReporter.ForEval(cx.GetErrorReporter());
			Evaluator evaluator = Context.CreateInterpreter();
			if (evaluator == null)
			{
				throw new JavaScriptException("Interpreter not present", filename, lineNumber);
			}
			// Compile with explicit interpreter instance to force interpreter
			// mode.
			Script script = cx.CompileString(x.ToString(), evaluator, reporter, sourceName, 1, null);
			evaluator.SetEvalScriptFlag(script);
			Callable c = (Callable)script;
			return c.Call(cx, scope, (Scriptable)thisArg, ScriptRuntime.emptyArgs);
		}
Ejemplo n.º 6
0
		public static object SetName(Scriptable bound, object value, Context cx, Scriptable scope, string id)
		{
			if (bound != null)
			{
				// TODO: we used to special-case XMLObject here, but putProperty
				// seems to work for E4X and it's better to optimize  the common case
				ScriptableObject.PutProperty(bound, id, value);
			}
			else
			{
				// "newname = 7;", where 'newname' has not yet
				// been defined, creates a new property in the
				// top scope unless strict mode is specified.
				if (cx.HasFeature(Context.FEATURE_STRICT_MODE) || cx.HasFeature(Context.FEATURE_STRICT_VARS))
				{
					Context.ReportWarning(ScriptRuntime.GetMessage1("msg.assn.create.strict", id));
				}
				// Find the top scope by walking up the scope chain.
				bound = ScriptableObject.GetTopLevelScope(scope);
				if (cx.useDynamicScope)
				{
					bound = CheckDynamicScope(cx.topCallScope, bound);
				}
				bound.Put(id, bound, value);
			}
			return value;
		}
Ejemplo n.º 7
0
		public static object GetObjectProp(Scriptable obj, string property, Context cx)
		{
			object result = ScriptableObject.GetProperty(obj, property);
			if (result == ScriptableConstants.NOT_FOUND)
			{
				if (cx.HasFeature(Context.FEATURE_STRICT_MODE))
				{
					Context.ReportWarning(ScriptRuntime.GetMessage1("msg.ref.undefined.prop", property));
				}
				result = Undefined.instance;
			}
			return result;
		}
Ejemplo n.º 8
0
		public static ScriptableObject InitStandardObjects(Context cx, ScriptableObject scope, bool @sealed)
		{
			if (scope == null)
			{
				scope = new NativeObject();
			}
			scope.AssociateValue(LIBRARY_SCOPE_KEY, scope);
			(new ClassCache()).Associate(scope);
			BaseFunction.Init(scope, @sealed);
			NativeObject.Init(scope, @sealed);
			Scriptable objectProto = ScriptableObject.GetObjectPrototype(scope);
			// Function.prototype.__proto__ should be Object.prototype
			Scriptable functionProto = ScriptableObject.GetClassPrototype(scope, "Function");
			functionProto.SetPrototype(objectProto);
			// Set the prototype of the object passed in if need be
			if (scope.GetPrototype() == null)
			{
				scope.SetPrototype(objectProto);
			}
			// must precede NativeGlobal since it's needed therein
			NativeError.Init(scope, @sealed);
			NativeGlobal.Init(cx, scope, @sealed);
			NativeArray.Init(scope, @sealed);
			if (cx.GetOptimizationLevel() > 0)
			{
				// When optimizing, attempt to fulfill all requests for new Array(N)
				// with a higher threshold before switching to a sparse
				// representation
				NativeArray.SetMaximumInitialCapacity(200000);
			}
			NativeString.Init(scope, @sealed);
			NativeBoolean.Init(scope, @sealed);
			NativeNumber.Init(scope, @sealed);
			NativeDate.Init(scope, @sealed);
			NativeMath.Init(scope, @sealed);
			NativeJSON.Init(scope, @sealed);
			NativeWith.Init(scope, @sealed);
			NativeCall.Init(scope, @sealed);
			NativeScript.Init(scope, @sealed);
			NativeIterator.Init(scope, @sealed);
			// Also initializes NativeGenerator
			bool withXml = cx.HasFeature(Context.FEATURE_E4X) && cx.GetE4xImplementationFactory() != null;
			// define lazy-loaded properties using their class name
			new LazilyLoadedCtor(scope, "RegExp", "org.mozilla.javascript.regexp.NativeRegExp", @sealed, true);
			new LazilyLoadedCtor(scope, "Packages", "org.mozilla.javascript.NativeJavaTopPackage", @sealed, true);
			new LazilyLoadedCtor(scope, "getClass", "org.mozilla.javascript.NativeJavaTopPackage", @sealed, true);
			new LazilyLoadedCtor(scope, "JavaAdapter", "org.mozilla.javascript.JavaAdapter", @sealed, true);
			new LazilyLoadedCtor(scope, "JavaImporter", "org.mozilla.javascript.ImporterTopLevel", @sealed, true);
			new LazilyLoadedCtor(scope, "Continuation", "org.mozilla.javascript.NativeContinuation", @sealed, true);
			foreach (string packageName in GetTopPackageNames())
			{
				new LazilyLoadedCtor(scope, packageName, "org.mozilla.javascript.NativeJavaTopPackage", @sealed, true);
			}
			if (withXml)
			{
				string xmlImpl = cx.GetE4xImplementationFactory().GetImplementationClassName();
				new LazilyLoadedCtor(scope, "XML", xmlImpl, @sealed, true);
				new LazilyLoadedCtor(scope, "XMLList", xmlImpl, @sealed, true);
				new LazilyLoadedCtor(scope, "Namespace", xmlImpl, @sealed, true);
				new LazilyLoadedCtor(scope, "QName", xmlImpl, @sealed, true);
			}
			if (scope is TopLevel)
			{
				((TopLevel)scope).CacheBuiltins();
			}
			return scope;
		}
Ejemplo n.º 9
0
		public override object ExecIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, object[] args)
		{
			if (!f.HasTag(DATE_TAG))
			{
				return base.ExecIdCall(f, cx, scope, thisObj, args);
			}
			int id = f.MethodId();
			switch (id)
			{
				case ConstructorId_now:
				{
					return ScriptRuntime.WrapNumber(Now());
				}

				case ConstructorId_parse:
				{
					string dataStr = ScriptRuntime.ToString(args, 0);
					return ScriptRuntime.WrapNumber(Date_parseString(dataStr));
				}

				case ConstructorId_UTC:
				{
					return ScriptRuntime.WrapNumber(JsStaticFunction_UTC(args));
				}

				case Id_constructor:
				{
					// if called as a function, just return a string
					// representing the current time.
					if (thisObj != null)
					{
						return Date_format(Now(), Id_toString);
					}
					return JsConstructor(args);
				}

				case Id_toJSON:
				{
					if (thisObj is Rhino.NativeDate)
					{
						return ((Rhino.NativeDate)thisObj).ToISOString();
					}
					string toISOString = "toISOString";
					Scriptable o = ScriptRuntime.ToObject(cx, scope, thisObj);
					object tv = ScriptRuntime.ToPrimitive(o, ScriptRuntime.NumberClass);
					if (tv is Number)
					{
						double d = System.Convert.ToDouble(((Number)tv));
						if (d != d || System.Double.IsInfinity(d))
						{
							return null;
						}
					}
					object toISO = o.Get(toISOString, o);
					if (toISO == ScriptableConstants.NOT_FOUND)
					{
						throw ScriptRuntime.TypeError2("msg.function.not.found.in", toISOString, ScriptRuntime.ToString(o));
					}
					if (!(toISO is Callable))
					{
						throw ScriptRuntime.TypeError3("msg.isnt.function.in", toISOString, ScriptRuntime.ToString(o), ScriptRuntime.ToString(toISO));
					}
					object result = ((Callable)toISO).Call(cx, scope, o, ScriptRuntime.emptyArgs);
					if (!ScriptRuntime.IsPrimitive(result))
					{
						throw ScriptRuntime.TypeError1("msg.toisostring.must.return.primitive", ScriptRuntime.ToString(result));
					}
					return result;
				}
			}
			// The rest of Date.prototype methods require thisObj to be Date
			if (!(thisObj is Rhino.NativeDate))
			{
				throw IncompatibleCallError(f);
			}
			Rhino.NativeDate realThis = (Rhino.NativeDate)thisObj;
			double t = realThis.date;
			switch (id)
			{
				case Id_toString:
				case Id_toTimeString:
				case Id_toDateString:
				{
					if (t == t)
					{
						return Date_format(t, id);
					}
					return js_NaN_date_str;
				}

				case Id_toLocaleString:
				case Id_toLocaleTimeString:
				case Id_toLocaleDateString:
				{
					if (t == t)
					{
						return ToLocale_helper(t, id);
					}
					return js_NaN_date_str;
				}

				case Id_toUTCString:
				{
					if (t == t)
					{
						return Js_toUTCString(t);
					}
					return js_NaN_date_str;
				}

				case Id_toSource:
				{
					return "(new Date(" + ScriptRuntime.ToString(t) + "))";
				}

				case Id_valueOf:
				case Id_getTime:
				{
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getYear:
				case Id_getFullYear:
				case Id_getUTCFullYear:
				{
					if (t == t)
					{
						if (id != Id_getUTCFullYear)
						{
							t = LocalTime(t);
						}
						t = YearFromTime(t);
						if (id == Id_getYear)
						{
							if (cx.HasFeature(Context.FEATURE_NON_ECMA_GET_YEAR))
							{
								if (1900 <= t && t < 2000)
								{
									t -= 1900;
								}
							}
							else
							{
								t -= 1900;
							}
						}
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getMonth:
				case Id_getUTCMonth:
				{
					if (t == t)
					{
						if (id == Id_getMonth)
						{
							t = LocalTime(t);
						}
						t = MonthFromTime(t);
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getDate:
				case Id_getUTCDate:
				{
					if (t == t)
					{
						if (id == Id_getDate)
						{
							t = LocalTime(t);
						}
						t = DateFromTime(t);
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getDay:
				case Id_getUTCDay:
				{
					if (t == t)
					{
						if (id == Id_getDay)
						{
							t = LocalTime(t);
						}
						t = WeekDay(t);
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getHours:
				case Id_getUTCHours:
				{
					if (t == t)
					{
						if (id == Id_getHours)
						{
							t = LocalTime(t);
						}
						t = HourFromTime(t);
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getMinutes:
				case Id_getUTCMinutes:
				{
					if (t == t)
					{
						if (id == Id_getMinutes)
						{
							t = LocalTime(t);
						}
						t = MinFromTime(t);
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getSeconds:
				case Id_getUTCSeconds:
				{
					if (t == t)
					{
						if (id == Id_getSeconds)
						{
							t = LocalTime(t);
						}
						t = SecFromTime(t);
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getMilliseconds:
				case Id_getUTCMilliseconds:
				{
					if (t == t)
					{
						if (id == Id_getMilliseconds)
						{
							t = LocalTime(t);
						}
						t = MsFromTime(t);
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_getTimezoneOffset:
				{
					if (t == t)
					{
						t = (t - LocalTime(t)) / msPerMinute;
					}
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_setTime:
				{
					t = TimeClip(ScriptRuntime.ToNumber(args, 0));
					realThis.date = t;
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_setMilliseconds:
				case Id_setUTCMilliseconds:
				case Id_setSeconds:
				case Id_setUTCSeconds:
				case Id_setMinutes:
				case Id_setUTCMinutes:
				case Id_setHours:
				case Id_setUTCHours:
				{
					t = MakeTime(t, args, id);
					realThis.date = t;
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_setDate:
				case Id_setUTCDate:
				case Id_setMonth:
				case Id_setUTCMonth:
				case Id_setFullYear:
				case Id_setUTCFullYear:
				{
					t = MakeDate(t, args, id);
					realThis.date = t;
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_setYear:
				{
					double year = ScriptRuntime.ToNumber(args, 0);
					if (year != year || System.Double.IsInfinity(year))
					{
						t = ScriptRuntime.NaN;
					}
					else
					{
						if (t != t)
						{
							t = 0;
						}
						else
						{
							t = LocalTime(t);
						}
						if (year >= 0 && year <= 99)
						{
							year += 1900;
						}
						double day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
						t = MakeDate(day, TimeWithinDay(t));
						t = InternalUTC(t);
						t = TimeClip(t);
					}
					realThis.date = t;
					return ScriptRuntime.WrapNumber(t);
				}

				case Id_toISOString:
				{
					return realThis.ToISOString();
				}

				default:
				{
					throw new ArgumentException(id.ToString());
				}
			}
		}
Ejemplo n.º 10
0
		private static object InterpretLoop(Context cx, Interpreter.CallFrame frame, object throwable)
		{
			// throwable holds exception object to rethrow or catch
			// It is also used for continuation restart in which case
			// it holds ContinuationJump
			object DBL_MRK = UniqueTag.DOUBLE_MARK;
			object undefined = Undefined.instance;
			bool instructionCounting = (cx.instructionThreshold != 0);
			// arbitrary number to add to instructionCount when calling
			// other functions
			int INVOCATION_COST = 100;
			// arbitrary exception cost for instruction counting
			int EXCEPTION_COST = 100;
			string stringReg = null;
			int indexReg = -1;
			if (cx.lastInterpreterFrame != null)
			{
				// save the top frame from the previous interpretLoop
				// invocation on the stack
				if (cx.previousInterpreterInvocations == null)
				{
					cx.previousInterpreterInvocations = new ObjArray();
				}
				cx.previousInterpreterInvocations.Push(cx.lastInterpreterFrame);
			}
			// When restarting continuation throwable is not null and to jump
			// to the code that rewind continuation state indexReg should be set
			// to -1.
			// With the normal call throwable == null and indexReg == -1 allows to
			// catch bugs with using indeReg to access array elements before
			// initializing indexReg.
			Interpreter.GeneratorState generatorState = null;
			if (throwable != null)
			{
				if (throwable is Interpreter.GeneratorState)
				{
					generatorState = (Interpreter.GeneratorState)throwable;
					// reestablish this call frame
					EnterFrame(cx, frame, ScriptRuntime.emptyArgs, true);
					throwable = null;
				}
				else
				{
					if (!(throwable is Interpreter.ContinuationJump))
					{
						// It should be continuation
						Kit.CodeBug();
					}
				}
			}
			object interpreterResult = null;
			double interpreterResultDbl = 0.0;
			for (; ; )
			{
				try
				{
					if (throwable != null)
					{
						// Need to return both 'frame' and 'throwable' from
						// 'processThrowable', so just added a 'throwable'
						// member in 'frame'.
						frame = ProcessThrowable(cx, throwable, frame, indexReg, instructionCounting);
						throwable = frame.throwable;
						frame.throwable = null;
					}
					else
					{
						if (generatorState == null && frame.frozen)
						{
							Kit.CodeBug();
						}
					}
					// Use local variables for constant values in frame
					// for faster access
					object[] stack = frame.stack;
					double[] sDbl = frame.sDbl;
					object[] vars = frame.varSource.stack;
					double[] varDbls = frame.varSource.sDbl;
					int[] varAttributes = frame.varSource.stackAttributes;
					byte[] iCode = frame.idata.itsICode;
					string[] strings = frame.idata.itsStringTable;
					// Use local for stackTop as well. Since execption handlers
					// can only exist at statement level where stack is empty,
					// it is necessary to save/restore stackTop only across
					// function calls and normal returns.
					int stackTop = frame.savedStackTop;
					// Store new frame in cx which is used for error reporting etc.
					cx.lastInterpreterFrame = frame;
					for (; ; )
					{
						// Exception handler assumes that PC is already incremented
						// pass the instruction start when it searches the
						// exception handler
						int op = iCode[frame.pc++];
						switch (op)
						{
							case Icode_GENERATOR:
							{
								// Back indent to ease implementation reading
								if (!frame.frozen)
								{
									// First time encountering this opcode: create new generator
									// object and return
									frame.pc--;
									// we want to come back here when we resume
									Interpreter.CallFrame generatorFrame = CaptureFrameForGenerator(frame);
									generatorFrame.frozen = true;
									NativeGenerator generator = new NativeGenerator(frame.scope, generatorFrame.fnOrScript, generatorFrame);
									frame.result = generator;
									goto Loop_break;
								}
								goto case Token.YIELD;
							}

							case Token.YIELD:
							{
								// We are now resuming execution. Fall through to YIELD case.
								// fall through...
								if (!frame.frozen)
								{
									return FreezeGenerator(cx, frame, stackTop, generatorState);
								}
								else
								{
									object obj = ThawGenerator(frame, stackTop, generatorState, op);
									if (obj != ScriptableConstants.NOT_FOUND)
									{
										throwable = obj;
										goto withoutExceptions_break;
									}
									goto Loop_continue;
								}
								goto case Icode_GENERATOR_END;
							}

							case Icode_GENERATOR_END:
							{
								// throw StopIteration
								frame.frozen = true;
								int sourceLine = GetIndex(iCode, frame.pc);
								generatorState.returnedException = new JavaScriptException(NativeIterator.GetStopIterationObject(frame.scope), frame.idata.itsSourceFile, sourceLine);
								goto Loop_break;
							}

							case Token.THROW:
							{
								object value = stack[stackTop];
								if (value == DBL_MRK)
								{
									value = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								int sourceLine = GetIndex(iCode, frame.pc);
								throwable = new JavaScriptException(value, frame.idata.itsSourceFile, sourceLine);
								goto withoutExceptions_break;
							}

							case Token.RETHROW:
							{
								indexReg += frame.localShift;
								throwable = stack[indexReg];
								goto withoutExceptions_break;
							}

							case Token.GE:
							case Token.LE:
							case Token.GT:
							case Token.LT:
							{
								stackTop = DoCompare(frame, op, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Token.IN:
							case Token.INSTANCEOF:
							{
								stackTop = DoInOrInstanceof(cx, op, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Token.EQ:
							case Token.NE:
							{
								--stackTop;
								bool valBln = DoEquals(stack, sDbl, stackTop);
								valBln ^= (op == Token.NE);
								stack[stackTop] = ScriptRuntime.WrapBoolean(valBln);
								goto Loop_continue;
							}

							case Token.SHEQ:
							case Token.SHNE:
							{
								--stackTop;
								bool valBln = DoShallowEquals(stack, sDbl, stackTop);
								valBln ^= (op == Token.SHNE);
								stack[stackTop] = ScriptRuntime.WrapBoolean(valBln);
								goto Loop_continue;
							}

							case Token.IFNE:
							{
								if (Stack_boolean(frame, stackTop--))
								{
									frame.pc += 2;
									goto Loop_continue;
								}
								goto jumplessRun_break;
							}

							case Token.IFEQ:
							{
								if (!Stack_boolean(frame, stackTop--))
								{
									frame.pc += 2;
									goto Loop_continue;
								}
								goto jumplessRun_break;
							}

							case Icode_IFEQ_POP:
							{
								if (!Stack_boolean(frame, stackTop--))
								{
									frame.pc += 2;
									goto Loop_continue;
								}
								stack[stackTop--] = null;
								goto jumplessRun_break;
							}

							case Token.GOTO:
							{
								goto jumplessRun_break;
							}

							case Icode_GOSUB:
							{
								++stackTop;
								stack[stackTop] = DBL_MRK;
								sDbl[stackTop] = frame.pc + 2;
								goto jumplessRun_break;
							}

							case Icode_STARTSUB:
							{
								if (stackTop == frame.emptyStackTop + 1)
								{
									// Call from Icode_GOSUB: store return PC address in the local
									indexReg += frame.localShift;
									stack[indexReg] = stack[stackTop];
									sDbl[indexReg] = sDbl[stackTop];
									--stackTop;
								}
								else
								{
									// Call from exception handler: exception object is already stored
									// in the local
									if (stackTop != frame.emptyStackTop)
									{
										Kit.CodeBug();
									}
								}
								goto Loop_continue;
							}

							case Icode_RETSUB:
							{
								// indexReg: local to store return address
								if (instructionCounting)
								{
									AddInstructionCount(cx, frame, 0);
								}
								indexReg += frame.localShift;
								object value = stack[indexReg];
								if (value != DBL_MRK)
								{
									// Invocation from exception handler, restore object to rethrow
									throwable = value;
									goto withoutExceptions_break;
								}
								// Normal return from GOSUB
								frame.pc = (int)sDbl[indexReg];
								if (instructionCounting)
								{
									frame.pcPrevBranch = frame.pc;
								}
								goto Loop_continue;
							}

							case Icode_POP:
							{
								stack[stackTop] = null;
								stackTop--;
								goto Loop_continue;
							}

							case Icode_POP_RESULT:
							{
								frame.result = stack[stackTop];
								frame.resultDbl = sDbl[stackTop];
								stack[stackTop] = null;
								--stackTop;
								goto Loop_continue;
							}

							case Icode_DUP:
							{
								stack[stackTop + 1] = stack[stackTop];
								sDbl[stackTop + 1] = sDbl[stackTop];
								stackTop++;
								goto Loop_continue;
							}

							case Icode_DUP2:
							{
								stack[stackTop + 1] = stack[stackTop - 1];
								sDbl[stackTop + 1] = sDbl[stackTop - 1];
								stack[stackTop + 2] = stack[stackTop];
								sDbl[stackTop + 2] = sDbl[stackTop];
								stackTop += 2;
								goto Loop_continue;
							}

							case Icode_SWAP:
							{
								object o = stack[stackTop];
								stack[stackTop] = stack[stackTop - 1];
								stack[stackTop - 1] = o;
								double d = sDbl[stackTop];
								sDbl[stackTop] = sDbl[stackTop - 1];
								sDbl[stackTop - 1] = d;
								goto Loop_continue;
							}

							case Token.RETURN:
							{
								frame.result = stack[stackTop];
								frame.resultDbl = sDbl[stackTop];
								--stackTop;
								goto Loop_break;
							}

							case Token.RETURN_RESULT:
							{
								goto Loop_break;
							}

							case Icode_RETUNDEF:
							{
								frame.result = undefined;
								goto Loop_break;
							}

							case Token.BITNOT:
							{
								int rIntValue = Stack_int32(frame, stackTop);
								stack[stackTop] = DBL_MRK;
								sDbl[stackTop] = ~rIntValue;
								goto Loop_continue;
							}

							case Token.BITAND:
							case Token.BITOR:
							case Token.BITXOR:
							case Token.LSH:
							case Token.RSH:
							{
								stackTop = DoBitOp(frame, op, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Token.URSH:
							{
								double lDbl = Stack_double(frame, stackTop - 1);
								int rIntValue = Stack_int32(frame, stackTop) & unchecked((int)(0x1F));
								stack[--stackTop] = DBL_MRK;
								sDbl[stackTop] = (long)(((ulong)ScriptRuntime.ToUint32(lDbl)) >> rIntValue);
								goto Loop_continue;
							}

							case Token.NEG:
							case Token.POS:
							{
								double rDbl = Stack_double(frame, stackTop);
								stack[stackTop] = DBL_MRK;
								if (op == Token.NEG)
								{
									rDbl = -rDbl;
								}
								sDbl[stackTop] = rDbl;
								goto Loop_continue;
							}

							case Token.ADD:
							{
								--stackTop;
								DoAdd(stack, sDbl, stackTop, cx);
								goto Loop_continue;
							}

							case Token.SUB:
							case Token.MUL:
							case Token.DIV:
							case Token.MOD:
							{
								stackTop = DoArithmetic(frame, op, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Token.NOT:
							{
								stack[stackTop] = ScriptRuntime.WrapBoolean(!Stack_boolean(frame, stackTop));
								goto Loop_continue;
							}

							case Token.BINDNAME:
							{
								stack[++stackTop] = ScriptRuntime.Bind(cx, frame.scope, stringReg);
								goto Loop_continue;
							}

							case Token.STRICT_SETNAME:
							case Token.SETNAME:
							{
								object rhs = stack[stackTop];
								if (rhs == DBL_MRK)
								{
									rhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								Scriptable lhs = (Scriptable)stack[stackTop];
								stack[stackTop] = op == Token.SETNAME ? ScriptRuntime.SetName(lhs, rhs, cx, frame.scope, stringReg) : ScriptRuntime.StrictSetName(lhs, rhs, cx, frame.scope, stringReg);
								goto Loop_continue;
							}

							case Icode_SETCONST:
							{
								object rhs = stack[stackTop];
								if (rhs == DBL_MRK)
								{
									rhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								Scriptable lhs = (Scriptable)stack[stackTop];
								stack[stackTop] = ScriptRuntime.SetConst(lhs, rhs, cx, stringReg);
								goto Loop_continue;
							}

							case Token.DELPROP:
							case Icode_DELNAME:
							{
								stackTop = DoDelName(cx, op, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Token.GETPROPNOWARN:
							{
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.GetObjectPropNoWarn(lhs, stringReg, cx);
								goto Loop_continue;
							}

							case Token.GETPROP:
							{
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.GetObjectProp(lhs, stringReg, cx, frame.scope);
								goto Loop_continue;
							}

							case Token.SETPROP:
							{
								object rhs = stack[stackTop];
								if (rhs == DBL_MRK)
								{
									rhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.SetObjectProp(lhs, stringReg, rhs, cx);
								goto Loop_continue;
							}

							case Icode_PROP_INC_DEC:
							{
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.PropIncrDecr(lhs, stringReg, cx, iCode[frame.pc]);
								++frame.pc;
								goto Loop_continue;
							}

							case Token.GETELEM:
							{
								stackTop = DoGetElem(cx, frame, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Token.SETELEM:
							{
								stackTop = DoSetElem(cx, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Icode_ELEM_INC_DEC:
							{
								stackTop = DoElemIncDec(cx, frame, iCode, stack, sDbl, stackTop);
								goto Loop_continue;
							}

							case Token.GET_REF:
							{
								Ref @ref = (Ref)stack[stackTop];
								stack[stackTop] = ScriptRuntime.RefGet(@ref, cx);
								goto Loop_continue;
							}

							case Token.SET_REF:
							{
								object value = stack[stackTop];
								if (value == DBL_MRK)
								{
									value = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								Ref @ref = (Ref)stack[stackTop];
								stack[stackTop] = ScriptRuntime.RefSet(@ref, value, cx);
								goto Loop_continue;
							}

							case Token.DEL_REF:
							{
								Ref @ref = (Ref)stack[stackTop];
								stack[stackTop] = ScriptRuntime.RefDel(@ref, cx);
								goto Loop_continue;
							}

							case Icode_REF_INC_DEC:
							{
								Ref @ref = (Ref)stack[stackTop];
								stack[stackTop] = ScriptRuntime.RefIncrDecr(@ref, cx, iCode[frame.pc]);
								++frame.pc;
								goto Loop_continue;
							}

							case Token.LOCAL_LOAD:
							{
								++stackTop;
								indexReg += frame.localShift;
								stack[stackTop] = stack[indexReg];
								sDbl[stackTop] = sDbl[indexReg];
								goto Loop_continue;
							}

							case Icode_LOCAL_CLEAR:
							{
								indexReg += frame.localShift;
								stack[indexReg] = null;
								goto Loop_continue;
							}

							case Icode_NAME_AND_THIS:
							{
								// stringReg: name
								++stackTop;
								stack[stackTop] = ScriptRuntime.GetNameFunctionAndThis(stringReg, cx, frame.scope);
								++stackTop;
								stack[stackTop] = ScriptRuntime.LastStoredScriptable(cx);
								goto Loop_continue;
							}

							case Icode_PROP_AND_THIS:
							{
								object obj = stack[stackTop];
								if (obj == DBL_MRK)
								{
									obj = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								// stringReg: property
								stack[stackTop] = ScriptRuntime.GetPropFunctionAndThis(obj, stringReg, cx, frame.scope);
								++stackTop;
								stack[stackTop] = ScriptRuntime.LastStoredScriptable(cx);
								goto Loop_continue;
							}

							case Icode_ELEM_AND_THIS:
							{
								object obj = stack[stackTop - 1];
								if (obj == DBL_MRK)
								{
									obj = ScriptRuntime.WrapNumber(sDbl[stackTop - 1]);
								}
								object id = stack[stackTop];
								if (id == DBL_MRK)
								{
									id = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop - 1] = ScriptRuntime.GetElemFunctionAndThis(obj, id, cx);
								stack[stackTop] = ScriptRuntime.LastStoredScriptable(cx);
								goto Loop_continue;
							}

							case Icode_VALUE_AND_THIS:
							{
								object value = stack[stackTop];
								if (value == DBL_MRK)
								{
									value = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.GetValueFunctionAndThis(value, cx);
								++stackTop;
								stack[stackTop] = ScriptRuntime.LastStoredScriptable(cx);
								goto Loop_continue;
							}

							case Icode_CALLSPECIAL:
							{
								if (instructionCounting)
								{
									cx.instructionCount += INVOCATION_COST;
								}
								stackTop = DoCallSpecial(cx, frame, stack, sDbl, stackTop, iCode, indexReg);
								goto Loop_continue;
							}

							case Token.CALL:
							case Icode_TAIL_CALL:
							case Token.REF_CALL:
							{
								if (instructionCounting)
								{
									cx.instructionCount += INVOCATION_COST;
								}
								// stack change: function thisObj arg0 .. argN -> result
								// indexReg: number of arguments
								stackTop -= 1 + indexReg;
								// CALL generation ensures that fun and funThisObj
								// are already Scriptable and Callable objects respectively
								Callable fun = (Callable)stack[stackTop];
								Scriptable funThisObj = (Scriptable)stack[stackTop + 1];
								if (op == Token.REF_CALL)
								{
									object[] outArgs = GetArgsArray(stack, sDbl, stackTop + 2, indexReg);
									stack[stackTop] = ScriptRuntime.CallRef(fun, funThisObj, outArgs, cx);
									goto Loop_continue;
								}
								Scriptable calleeScope = frame.scope;
								if (frame.useActivation)
								{
									calleeScope = ScriptableObject.GetTopLevelScope(frame.scope);
								}
								if (fun is InterpretedFunction)
								{
									InterpretedFunction ifun = (InterpretedFunction)fun;
									if (frame.fnOrScript.securityDomain == ifun.securityDomain)
									{
										Interpreter.CallFrame callParentFrame = frame;
										Interpreter.CallFrame calleeFrame = new Interpreter.CallFrame();
										if (op == Icode_TAIL_CALL)
										{
											// In principle tail call can re-use the current
											// frame and its stack arrays but it is hard to
											// do properly. Any exceptions that can legally
											// happen during frame re-initialization including
											// StackOverflowException during innocent looking
											// System.arraycopy may leave the current frame
											// data corrupted leading to undefined behaviour
											// in the catch code bellow that unwinds JS stack
											// on exceptions. Then there is issue about frame release
											// end exceptions there.
											// To avoid frame allocation a released frame
											// can be cached for re-use which would also benefit
											// non-tail calls but it is not clear that this caching
											// would gain in performance due to potentially
											// bad interaction with GC.
											callParentFrame = frame.parentFrame;
											// Release the current frame. See Bug #344501 to see why
											// it is being done here.
											ExitFrame(cx, frame, null);
										}
										InitFrame(cx, calleeScope, funThisObj, stack, sDbl, stackTop + 2, indexReg, ifun, callParentFrame, calleeFrame);
										if (op != Icode_TAIL_CALL)
										{
											frame.savedStackTop = stackTop;
											frame.savedCallOp = op;
										}
										frame = calleeFrame;
										goto StateLoop_continue;
									}
								}
								if (fun is NativeContinuation)
								{
									// Jump to the captured continuation
									Interpreter.ContinuationJump cjump;
									cjump = new Interpreter.ContinuationJump((NativeContinuation)fun, frame);
									// continuation result is the first argument if any
									// of continuation call
									if (indexReg == 0)
									{
										cjump.result = undefined;
									}
									else
									{
										cjump.result = stack[stackTop + 2];
										cjump.resultDbl = sDbl[stackTop + 2];
									}
									// Start the real unwind job
									throwable = cjump;
									goto withoutExceptions_break;
								}
								if (fun is IdFunctionObject)
								{
									IdFunctionObject ifun = (IdFunctionObject)fun;
									if (NativeContinuation.IsContinuationConstructor(ifun))
									{
										frame.stack[stackTop] = CaptureContinuation(cx, frame.parentFrame, false);
										goto Loop_continue;
									}
									// Bug 405654 -- make best effort to keep Function.apply and
									// Function.call within this interpreter loop invocation
									if (BaseFunction.IsApplyOrCall(ifun))
									{
										Callable applyCallable = ScriptRuntime.GetCallable(funThisObj);
										if (applyCallable is InterpretedFunction)
										{
											InterpretedFunction iApplyCallable = (InterpretedFunction)applyCallable;
											if (frame.fnOrScript.securityDomain == iApplyCallable.securityDomain)
											{
												frame = InitFrameForApplyOrCall(cx, frame, indexReg, stack, sDbl, stackTop, op, calleeScope, ifun, iApplyCallable);
												goto StateLoop_continue;
											}
										}
									}
								}
								// Bug 447697 -- make best effort to keep __noSuchMethod__ within this
								// interpreter loop invocation
								if (fun is ScriptRuntime.NoSuchMethodShim)
								{
									// get the shim and the actual method
									ScriptRuntime.NoSuchMethodShim noSuchMethodShim = (ScriptRuntime.NoSuchMethodShim)fun;
									Callable noSuchMethodMethod = noSuchMethodShim.noSuchMethodMethod;
									// if the method is in fact an InterpretedFunction
									if (noSuchMethodMethod is InterpretedFunction)
									{
										InterpretedFunction ifun = (InterpretedFunction)noSuchMethodMethod;
										if (frame.fnOrScript.securityDomain == ifun.securityDomain)
										{
											frame = InitFrameForNoSuchMethod(cx, frame, indexReg, stack, sDbl, stackTop, op, funThisObj, calleeScope, noSuchMethodShim, ifun);
											goto StateLoop_continue;
										}
									}
								}
								cx.lastInterpreterFrame = frame;
								frame.savedCallOp = op;
								frame.savedStackTop = stackTop;
								stack[stackTop] = fun.Call(cx, calleeScope, funThisObj, GetArgsArray(stack, sDbl, stackTop + 2, indexReg));
								goto Loop_continue;
							}

							case Token.NEW:
							{
								if (instructionCounting)
								{
									cx.instructionCount += INVOCATION_COST;
								}
								// stack change: function arg0 .. argN -> newResult
								// indexReg: number of arguments
								stackTop -= indexReg;
								object lhs = stack[stackTop];
								if (lhs is InterpretedFunction)
								{
									InterpretedFunction f = (InterpretedFunction)lhs;
									if (frame.fnOrScript.securityDomain == f.securityDomain)
									{
										Scriptable newInstance = f.CreateObject(cx, frame.scope);
										Interpreter.CallFrame calleeFrame = new Interpreter.CallFrame();
										InitFrame(cx, frame.scope, newInstance, stack, sDbl, stackTop + 1, indexReg, f, frame, calleeFrame);
										stack[stackTop] = newInstance;
										frame.savedStackTop = stackTop;
										frame.savedCallOp = op;
										frame = calleeFrame;
										goto StateLoop_continue;
									}
								}
								if (!(lhs is Function))
								{
									if (lhs == DBL_MRK)
									{
										lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
									}
									throw ScriptRuntime.NotFunctionError(lhs);
								}
								Function fun = (Function)lhs;
								if (fun is IdFunctionObject)
								{
									IdFunctionObject ifun = (IdFunctionObject)fun;
									if (NativeContinuation.IsContinuationConstructor(ifun))
									{
										frame.stack[stackTop] = CaptureContinuation(cx, frame.parentFrame, false);
										goto Loop_continue;
									}
								}
								object[] outArgs = GetArgsArray(stack, sDbl, stackTop + 1, indexReg);
								stack[stackTop] = fun.Construct(cx, frame.scope, outArgs);
								goto Loop_continue;
							}

							case Token.TYPEOF:
							{
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.Typeof(lhs);
								goto Loop_continue;
							}

							case Icode_TYPEOFNAME:
							{
								stack[++stackTop] = ScriptRuntime.TypeofName(frame.scope, stringReg);
								goto Loop_continue;
							}

							case Token.STRING:
							{
								stack[++stackTop] = stringReg;
								goto Loop_continue;
							}

							case Icode_SHORTNUMBER:
							{
								++stackTop;
								stack[stackTop] = DBL_MRK;
								sDbl[stackTop] = GetShort(iCode, frame.pc);
								frame.pc += 2;
								goto Loop_continue;
							}

							case Icode_INTNUMBER:
							{
								++stackTop;
								stack[stackTop] = DBL_MRK;
								sDbl[stackTop] = GetInt(iCode, frame.pc);
								frame.pc += 4;
								goto Loop_continue;
							}

							case Token.NUMBER:
							{
								++stackTop;
								stack[stackTop] = DBL_MRK;
								sDbl[stackTop] = frame.idata.itsDoubleTable[indexReg];
								goto Loop_continue;
							}

							case Token.NAME:
							{
								stack[++stackTop] = ScriptRuntime.Name(cx, frame.scope, stringReg);
								goto Loop_continue;
							}

							case Icode_NAME_INC_DEC:
							{
								stack[++stackTop] = ScriptRuntime.NameIncrDecr(frame.scope, stringReg, cx, iCode[frame.pc]);
								++frame.pc;
								goto Loop_continue;
							}

							case Icode_SETCONSTVAR1:
							{
								indexReg = iCode[frame.pc++];
								goto case Token.SETCONSTVAR;
							}

							case Token.SETCONSTVAR:
							{
								// fallthrough
								stackTop = DoSetConstVar(frame, stack, sDbl, stackTop, vars, varDbls, varAttributes, indexReg);
								goto Loop_continue;
							}

							case Icode_SETVAR1:
							{
								indexReg = iCode[frame.pc++];
								goto case Token.SETVAR;
							}

							case Token.SETVAR:
							{
								// fallthrough
								stackTop = DoSetVar(frame, stack, sDbl, stackTop, vars, varDbls, varAttributes, indexReg);
								goto Loop_continue;
							}

							case Icode_GETVAR1:
							{
								indexReg = iCode[frame.pc++];
								goto case Token.GETVAR;
							}

							case Token.GETVAR:
							{
								// fallthrough
								stackTop = DoGetVar(frame, stack, sDbl, stackTop, vars, varDbls, indexReg);
								goto Loop_continue;
							}

							case Icode_VAR_INC_DEC:
							{
								stackTop = DoVarIncDec(cx, frame, stack, sDbl, stackTop, vars, varDbls, indexReg);
								goto Loop_continue;
							}

							case Icode_ZERO:
							{
								++stackTop;
								stack[stackTop] = DBL_MRK;
								sDbl[stackTop] = 0;
								goto Loop_continue;
							}

							case Icode_ONE:
							{
								++stackTop;
								stack[stackTop] = DBL_MRK;
								sDbl[stackTop] = 1;
								goto Loop_continue;
							}

							case Token.NULL:
							{
								stack[++stackTop] = null;
								goto Loop_continue;
							}

							case Token.THIS:
							{
								stack[++stackTop] = frame.thisObj;
								goto Loop_continue;
							}

							case Token.THISFN:
							{
								stack[++stackTop] = frame.fnOrScript;
								goto Loop_continue;
							}

							case Token.FALSE:
							{
								stack[++stackTop] = false;
								goto Loop_continue;
							}

							case Token.TRUE:
							{
								stack[++stackTop] = true;
								goto Loop_continue;
							}

							case Icode_UNDEF:
							{
								stack[++stackTop] = undefined;
								goto Loop_continue;
							}

							case Token.ENTERWITH:
							{
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								frame.scope = ScriptRuntime.EnterWith(lhs, cx, frame.scope);
								goto Loop_continue;
							}

							case Token.LEAVEWITH:
							{
								frame.scope = ScriptRuntime.LeaveWith(frame.scope);
								goto Loop_continue;
							}

							case Token.CATCH_SCOPE:
							{
								// stack top: exception object
								// stringReg: name of exception variable
								// indexReg: local for exception scope
								--stackTop;
								indexReg += frame.localShift;
								bool afterFirstScope = (frame.idata.itsICode[frame.pc] != 0);
								Exception caughtException = (Exception)stack[stackTop + 1];
								Scriptable lastCatchScope;
								if (!afterFirstScope)
								{
									lastCatchScope = null;
								}
								else
								{
									lastCatchScope = (Scriptable)stack[indexReg];
								}
								stack[indexReg] = ScriptRuntime.NewCatchScope(caughtException, lastCatchScope, stringReg, cx, frame.scope);
								++frame.pc;
								goto Loop_continue;
							}

							case Token.ENUM_INIT_KEYS:
							case Token.ENUM_INIT_VALUES:
							case Token.ENUM_INIT_ARRAY:
							{
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								indexReg += frame.localShift;
								int enumType = op == Token.ENUM_INIT_KEYS ? ScriptRuntime.ENUMERATE_KEYS : op == Token.ENUM_INIT_VALUES ? ScriptRuntime.ENUMERATE_VALUES : ScriptRuntime.ENUMERATE_ARRAY;
								stack[indexReg] = ScriptRuntime.EnumInit(lhs, cx, enumType);
								goto Loop_continue;
							}

							case Token.ENUM_NEXT:
							case Token.ENUM_ID:
							{
								indexReg += frame.localShift;
								object val = stack[indexReg];
								++stackTop;
								stack[stackTop] = (op == Token.ENUM_NEXT) ? (object)ScriptRuntime.EnumNext(val) : (object)ScriptRuntime.EnumId(val, cx);
								goto Loop_continue;
							}

							case Token.REF_SPECIAL:
							{
								//stringReg: name of special property
								object obj = stack[stackTop];
								if (obj == DBL_MRK)
								{
									obj = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.SpecialRef(obj, stringReg, cx);
								goto Loop_continue;
							}

							case Token.REF_MEMBER:
							{
								//indexReg: flags
								stackTop = DoRefMember(cx, stack, sDbl, stackTop, indexReg);
								goto Loop_continue;
							}

							case Token.REF_NS_MEMBER:
							{
								//indexReg: flags
								stackTop = DoRefNsMember(cx, stack, sDbl, stackTop, indexReg);
								goto Loop_continue;
							}

							case Token.REF_NAME:
							{
								//indexReg: flags
								object name = stack[stackTop];
								if (name == DBL_MRK)
								{
									name = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.NameRef(name, cx, frame.scope, indexReg);
								goto Loop_continue;
							}

							case Token.REF_NS_NAME:
							{
								//indexReg: flags
								stackTop = DoRefNsName(cx, frame, stack, sDbl, stackTop, indexReg);
								goto Loop_continue;
							}

							case Icode_SCOPE_LOAD:
							{
								indexReg += frame.localShift;
								frame.scope = (Scriptable)stack[indexReg];
								goto Loop_continue;
							}

							case Icode_SCOPE_SAVE:
							{
								indexReg += frame.localShift;
								stack[indexReg] = frame.scope;
								goto Loop_continue;
							}

							case Icode_CLOSURE_EXPR:
							{
								stack[++stackTop] = InterpretedFunction.CreateFunction(cx, frame.scope, frame.fnOrScript, indexReg);
								goto Loop_continue;
							}

							case Icode_CLOSURE_STMT:
							{
								InitFunction(cx, frame.scope, frame.fnOrScript, indexReg);
								goto Loop_continue;
							}

							case Token.REGEXP:
							{
								object re = frame.idata.itsRegExpLiterals[indexReg];
								stack[++stackTop] = ScriptRuntime.WrapRegExp(cx, frame.scope, re);
								goto Loop_continue;
							}

							case Icode_LITERAL_NEW:
							{
								// indexReg: number of values in the literal
								++stackTop;
								stack[stackTop] = new int[indexReg];
								++stackTop;
								stack[stackTop] = new object[indexReg];
								sDbl[stackTop] = 0;
								goto Loop_continue;
							}

							case Icode_LITERAL_SET:
							{
								object value = stack[stackTop];
								if (value == DBL_MRK)
								{
									value = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								int i = (int)sDbl[stackTop];
								((object[])stack[stackTop])[i] = value;
								sDbl[stackTop] = i + 1;
								goto Loop_continue;
							}

							case Icode_LITERAL_GETTER:
							{
								object value = stack[stackTop];
								--stackTop;
								int i = (int)sDbl[stackTop];
								((object[])stack[stackTop])[i] = value;
								((int[])stack[stackTop - 1])[i] = -1;
								sDbl[stackTop] = i + 1;
								goto Loop_continue;
							}

							case Icode_LITERAL_SETTER:
							{
								object value = stack[stackTop];
								--stackTop;
								int i = (int)sDbl[stackTop];
								((object[])stack[stackTop])[i] = value;
								((int[])stack[stackTop - 1])[i] = +1;
								sDbl[stackTop] = i + 1;
								goto Loop_continue;
							}

							case Token.ARRAYLIT:
							case Icode_SPARE_ARRAYLIT:
							case Token.OBJECTLIT:
							{
								object[] data = (object[])stack[stackTop];
								--stackTop;
								int[] getterSetters = (int[])stack[stackTop];
								object val;
								if (op == Token.OBJECTLIT)
								{
									object[] ids = (object[])frame.idata.literalIds[indexReg];
									val = ScriptRuntime.NewObjectLiteral(ids, data, getterSetters, cx, frame.scope);
								}
								else
								{
									int[] skipIndexces = null;
									if (op == Icode_SPARE_ARRAYLIT)
									{
										skipIndexces = (int[])frame.idata.literalIds[indexReg];
									}
									val = ScriptRuntime.NewArrayLiteral(data, skipIndexces, cx, frame.scope);
								}
								stack[stackTop] = val;
								goto Loop_continue;
							}

							case Icode_ENTERDQ:
							{
								object lhs = stack[stackTop];
								if (lhs == DBL_MRK)
								{
									lhs = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								--stackTop;
								frame.scope = ScriptRuntime.EnterDotQuery(lhs, frame.scope);
								goto Loop_continue;
							}

							case Icode_LEAVEDQ:
							{
								bool valBln = Stack_boolean(frame, stackTop);
								object x = ScriptRuntime.UpdateDotQuery(valBln, frame.scope);
								if (x != null)
								{
									stack[stackTop] = x;
									frame.scope = ScriptRuntime.LeaveDotQuery(frame.scope);
									frame.pc += 2;
									goto Loop_continue;
								}
								// reset stack and PC to code after ENTERDQ
								--stackTop;
								goto jumplessRun_break;
							}

							case Token.DEFAULTNAMESPACE:
							{
								object value = stack[stackTop];
								if (value == DBL_MRK)
								{
									value = ScriptRuntime.WrapNumber(sDbl[stackTop]);
								}
								stack[stackTop] = ScriptRuntime.SetDefaultNamespace(value, cx);
								goto Loop_continue;
							}

							case Token.ESCXMLATTR:
							{
								object value = stack[stackTop];
								if (value != DBL_MRK)
								{
									stack[stackTop] = ScriptRuntime.EscapeAttributeValue(value, cx);
								}
								goto Loop_continue;
							}

							case Token.ESCXMLTEXT:
							{
								object value = stack[stackTop];
								if (value != DBL_MRK)
								{
									stack[stackTop] = ScriptRuntime.EscapeTextValue(value, cx);
								}
								goto Loop_continue;
							}

							case Icode_DEBUGGER:
							{
								if (frame.debuggerFrame != null)
								{
									frame.debuggerFrame.OnDebuggerStatement(cx);
								}
								goto Loop_continue;
							}

							case Icode_LINE:
							{
								frame.pcSourceLineStart = frame.pc;
								if (frame.debuggerFrame != null)
								{
									int line = GetIndex(iCode, frame.pc);
									frame.debuggerFrame.OnLineChange(cx, line);
								}
								frame.pc += 2;
								goto Loop_continue;
							}

							case Icode_REG_IND_C0:
							{
								indexReg = 0;
								goto Loop_continue;
							}

							case Icode_REG_IND_C1:
							{
								indexReg = 1;
								goto Loop_continue;
							}

							case Icode_REG_IND_C2:
							{
								indexReg = 2;
								goto Loop_continue;
							}

							case Icode_REG_IND_C3:
							{
								indexReg = 3;
								goto Loop_continue;
							}

							case Icode_REG_IND_C4:
							{
								indexReg = 4;
								goto Loop_continue;
							}

							case Icode_REG_IND_C5:
							{
								indexReg = 5;
								goto Loop_continue;
							}

							case Icode_REG_IND1:
							{
								indexReg = unchecked((int)(0xFF)) & iCode[frame.pc];
								++frame.pc;
								goto Loop_continue;
							}

							case Icode_REG_IND2:
							{
								indexReg = GetIndex(iCode, frame.pc);
								frame.pc += 2;
								goto Loop_continue;
							}

							case Icode_REG_IND4:
							{
								indexReg = GetInt(iCode, frame.pc);
								frame.pc += 4;
								goto Loop_continue;
							}

							case Icode_REG_STR_C0:
							{
								stringReg = strings[0];
								goto Loop_continue;
							}

							case Icode_REG_STR_C1:
							{
								stringReg = strings[1];
								goto Loop_continue;
							}

							case Icode_REG_STR_C2:
							{
								stringReg = strings[2];
								goto Loop_continue;
							}

							case Icode_REG_STR_C3:
							{
								stringReg = strings[3];
								goto Loop_continue;
							}

							case Icode_REG_STR1:
							{
								stringReg = strings[unchecked((int)(0xFF)) & iCode[frame.pc]];
								++frame.pc;
								goto Loop_continue;
							}

							case Icode_REG_STR2:
							{
								stringReg = strings[GetIndex(iCode, frame.pc)];
								frame.pc += 2;
								goto Loop_continue;
							}

							case Icode_REG_STR4:
							{
								stringReg = strings[GetInt(iCode, frame.pc)];
								frame.pc += 4;
								goto Loop_continue;
							}

							default:
							{
								DumpICode(frame.idata);
								throw new Exception("Unknown icode : " + op + " @ pc : " + (frame.pc - 1));
							}
						}
jumplessRun_break: ;
						// end of interpreter switch
						// end of jumplessRun label block
						// This should be reachable only for jump implementation
						// when pc points to encoded target offset
						if (instructionCounting)
						{
							AddInstructionCount(cx, frame, 2);
						}
						int offset = GetShort(iCode, frame.pc);
						if (offset != 0)
						{
							// -1 accounts for pc pointing to jump opcode + 1
							frame.pc += offset - 1;
						}
						else
						{
							frame.pc = frame.idata.longJumps.GetExistingInt(frame.pc);
						}
						if (instructionCounting)
						{
							frame.pcPrevBranch = frame.pc;
						}
						goto Loop_continue;
Loop_continue: ;
					}
Loop_break: ;
					// end of Loop: for
					ExitFrame(cx, frame, null);
					interpreterResult = frame.result;
					interpreterResultDbl = frame.resultDbl;
					if (frame.parentFrame != null)
					{
						frame = frame.parentFrame;
						if (frame.frozen)
						{
							frame = frame.CloneFrozen();
						}
						SetCallResult(frame, interpreterResult, interpreterResultDbl);
						interpreterResult = null;
						// Help GC
						goto StateLoop_continue;
					}
					goto StateLoop_break;
				}
				catch (Exception ex)
				{
					// end of interpreter withoutExceptions: try
					if (throwable != null)
					{
						// This is serious bug and it is better to track it ASAP
						Sharpen.Runtime.PrintStackTrace(ex, System.Console.Error);
						throw new InvalidOperationException();
					}
					throwable = ex;
				}
withoutExceptions_break: ;
				// This should be reachable only after above catch or from
				// finally when it needs to propagate exception or from
				// explicit throw
				if (throwable == null)
				{
					Kit.CodeBug();
				}
				// Exception type
				int EX_CATCH_STATE = 2;
				// Can execute JS catch
				int EX_FINALLY_STATE = 1;
				// Can execute JS finally
				int EX_NO_JS_STATE = 0;
				// Terminate JS execution
				int exState;
				Interpreter.ContinuationJump cjump_1 = null;
				if (generatorState != null && generatorState.operation == NativeGenerator.GENERATOR_CLOSE && throwable == generatorState.value)
				{
					exState = EX_FINALLY_STATE;
				}
				else
				{
					if (throwable is JavaScriptException)
					{
						exState = EX_CATCH_STATE;
					}
					else
					{
						if (throwable is EcmaError)
						{
							// an offical ECMA error object,
							exState = EX_CATCH_STATE;
						}
						else
						{
							if (throwable is EvaluatorException)
							{
								exState = EX_CATCH_STATE;
							}
							else
							{
								if (throwable is ContinuationPending)
								{
									exState = EX_NO_JS_STATE;
								}
								else
								{
									if (throwable is Exception)
									{
										exState = cx.HasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) ? EX_CATCH_STATE : EX_FINALLY_STATE;
									}
									else
									{
										if (throwable is Exception)
										{
											exState = cx.HasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) ? EX_CATCH_STATE : EX_NO_JS_STATE;
										}
										else
										{
											if (throwable is Interpreter.ContinuationJump)
											{
												// It must be ContinuationJump
												exState = EX_FINALLY_STATE;
												cjump_1 = (Interpreter.ContinuationJump)throwable;
											}
											else
											{
												exState = cx.HasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) ? EX_CATCH_STATE : EX_FINALLY_STATE;
											}
										}
									}
								}
							}
						}
					}
				}
				if (instructionCounting)
				{
					try
					{
						AddInstructionCount(cx, frame, EXCEPTION_COST);
					}
					catch (Exception ex)
					{
						throwable = ex;
						exState = EX_FINALLY_STATE;
					}
					catch (Exception ex)
					{
						// Error from instruction counting
						//     => unconditionally terminate JS
						throwable = ex;
						cjump_1 = null;
						exState = EX_NO_JS_STATE;
					}
				}
				if (frame.debuggerFrame != null && throwable is Exception)
				{
					// Call debugger only for RuntimeException
					Exception rex = (Exception)throwable;
					try
					{
						frame.debuggerFrame.OnExceptionThrown(cx, rex);
					}
					catch (Exception ex)
					{
						// Any exception from debugger
						//     => unconditionally terminate JS
						throwable = ex;
						cjump_1 = null;
						exState = EX_NO_JS_STATE;
					}
				}
				for (; ; )
				{
					if (exState != EX_NO_JS_STATE)
					{
						bool onlyFinally = (exState != EX_CATCH_STATE);
						indexReg = GetExceptionHandler(frame, onlyFinally);
						if (indexReg >= 0)
						{
							// We caught an exception, restart the loop
							// with exception pending the processing at the loop
							// start
							goto StateLoop_continue;
						}
					}
					// No allowed exception handlers in this frame, unwind
					// to parent and try to look there
					ExitFrame(cx, frame, throwable);
					frame = frame.parentFrame;
					if (frame == null)
					{
						break;
					}
					if (cjump_1 != null && cjump_1.branchFrame == frame)
					{
						// Continuation branch point was hit,
						// restart the state loop to reenter continuation
						indexReg = -1;
						goto StateLoop_continue;
					}
				}
				// No more frames, rethrow the exception or deal with continuation
				if (cjump_1 != null)
				{
					if (cjump_1.branchFrame != null)
					{
						// The above loop should locate the top frame
						Kit.CodeBug();
					}
					if (cjump_1.capturedFrame != null)
					{
						// Restarting detached continuation
						indexReg = -1;
						goto StateLoop_continue;
					}
					// Return continuation result to the caller
					interpreterResult = cjump_1.result;
					interpreterResultDbl = cjump_1.resultDbl;
					throwable = null;
				}
				goto StateLoop_break;
StateLoop_continue: ;
			}
StateLoop_break: ;
			// end of StateLoop: for(;;)
			// Do cleanups/restorations before the final return or throw
			if (cx.previousInterpreterInvocations != null && cx.previousInterpreterInvocations.Size() != 0)
			{
				cx.lastInterpreterFrame = cx.previousInterpreterInvocations.Pop();
			}
			else
			{
				// It was the last interpreter frame on the stack
				cx.lastInterpreterFrame = null;
				// Force GC of the value cx.previousInterpreterInvocations
				cx.previousInterpreterInvocations = null;
			}
			if (throwable != null)
			{
				if (throwable is Exception)
				{
					throw (Exception)throwable;
				}
				else
				{
					// Must be instance of Error or code bug
					throw (Exception)throwable;
				}
			}
			return (interpreterResult != DBL_MRK) ? interpreterResult : ScriptRuntime.WrapNumber(interpreterResultDbl);
		}
Ejemplo n.º 11
0
		/// <summary>
		/// Find the index of the correct function to call given the set of methods
		/// or constructors and the arguments.
		/// </summary>
		/// <remarks>
		/// Find the index of the correct function to call given the set of methods
		/// or constructors and the arguments.
		/// If no function can be found to call, return -1.
		/// </remarks>
		internal static int FindFunction(Context cx, MemberBox[] methodsOrCtors, object[] args)
		{
			if (methodsOrCtors.Length == 0)
			{
				return -1;
			}
			else
			{
				if (methodsOrCtors.Length == 1)
				{
					MemberBox member = methodsOrCtors[0];
					Type[] argTypes = member.argTypes;
					int alength = argTypes.Length;
					if (member.vararg)
					{
						alength--;
						if (alength > args.Length)
						{
							return -1;
						}
					}
					else
					{
						if (alength != args.Length)
						{
							return -1;
						}
					}
					for (int j = 0; j != alength; ++j)
					{
						if (!NativeJavaObject.CanConvert(args[j], argTypes[j]))
						{
							return -1;
						}
					}
					return 0;
				}
			}
			int firstBestFit = -1;
			int[] extraBestFits = null;
			int extraBestFitsCount = 0;
			for (int i = 0; i < methodsOrCtors.Length; i++)
			{
				MemberBox member = methodsOrCtors[i];
				Type[] argTypes = member.argTypes;
				int alength = argTypes.Length;
				if (member.vararg)
				{
					alength--;
					if (alength > args.Length)
					{
						goto search_continue;
					}
				}
				else
				{
					if (alength != args.Length)
					{
						goto search_continue;
					}
				}
				for (int j = 0; j < alength; j++)
				{
					if (!NativeJavaObject.CanConvert(args[j], argTypes[j]))
					{
						goto search_continue;
					}
				}
				if (firstBestFit < 0)
				{
					firstBestFit = i;
				}
				else
				{
					// Compare with all currently fit methods.
					// The loop starts from -1 denoting firstBestFit and proceed
					// until extraBestFitsCount to avoid extraBestFits allocation
					// in the most common case of no ambiguity
					int betterCount = 0;
					// number of times member was prefered over
					// best fits
					int worseCount = 0;
					// number of times best fits were prefered
					// over member
					for (int j_1 = -1; j_1 != extraBestFitsCount; ++j_1)
					{
						int bestFitIndex;
						if (j_1 == -1)
						{
							bestFitIndex = firstBestFit;
						}
						else
						{
							bestFitIndex = extraBestFits[j_1];
						}
						MemberBox bestFit = methodsOrCtors[bestFitIndex];
						if (cx.HasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) && (bestFit.Member().Attributes & Modifier.PUBLIC) != (member.Member().Attributes & Modifier.PUBLIC))
						{
							// When FEATURE_ENHANCED_JAVA_ACCESS gives us access
							// to non-public members, continue to prefer public
							// methods in overloading
							if ((bestFit.Member().Attributes & Modifier.PUBLIC) == 0)
							{
								++betterCount;
							}
							else
							{
								++worseCount;
							}
						}
						else
						{
							int preference = PreferSignature(args, argTypes, member.vararg, bestFit.argTypes, bestFit.vararg);
							if (preference == PREFERENCE_AMBIGUOUS)
							{
								break;
							}
							else
							{
								if (preference == PREFERENCE_FIRST_ARG)
								{
									++betterCount;
								}
								else
								{
									if (preference == PREFERENCE_SECOND_ARG)
									{
										++worseCount;
									}
									else
									{
										if (preference != PREFERENCE_EQUAL)
										{
											Kit.CodeBug();
										}
										// This should not happen in theory
										// but on some JVMs, Class.getMethods will return all
										// static methods of the class hierarchy, even if
										// a derived class's parameters match exactly.
										// We want to call the derived class's method.
										if (bestFit.IsStatic() && bestFit.GetDeclaringClass().IsAssignableFrom(member.GetDeclaringClass()))
										{
											// On some JVMs, Class.getMethods will return all
											// static methods of the class hierarchy, even if
											// a derived class's parameters match exactly.
											// We want to call the derived class's method.
											if (j_1 == -1)
											{
												firstBestFit = i;
											}
											else
											{
												extraBestFits[j_1] = i;
											}
										}
										goto search_continue;
									}
								}
							}
						}
					}
					if (betterCount == 1 + extraBestFitsCount)
					{
						// member was prefered over all best fits
						firstBestFit = i;
						extraBestFitsCount = 0;
					}
					else
					{
						if (worseCount == 1 + extraBestFitsCount)
						{
						}
						else
						{
							// all best fits were prefered over member, ignore it
							// some ambiguity was present, add member to best fit set
							if (extraBestFits == null)
							{
								// Allocate maximum possible array
								extraBestFits = new int[methodsOrCtors.Length - 1];
							}
							extraBestFits[extraBestFitsCount] = i;
							++extraBestFitsCount;
						}
					}
				}
search_continue: ;
			}
search_break: ;
			if (firstBestFit < 0)
			{
				// Nothing was found
				return -1;
			}
			else
			{
				if (extraBestFitsCount == 0)
				{
					// single best fit
					return firstBestFit;
				}
			}
			// report remaining ambiguity
			StringBuilder buf = new StringBuilder();
			for (int j_2 = -1; j_2 != extraBestFitsCount; ++j_2)
			{
				int bestFitIndex;
				if (j_2 == -1)
				{
					bestFitIndex = firstBestFit;
				}
				else
				{
					bestFitIndex = extraBestFits[j_2];
				}
				buf.Append("\n    ");
				buf.Append(methodsOrCtors[bestFitIndex].ToJavaDeclaration());
			}
			MemberBox firstFitMember = methodsOrCtors[firstBestFit];
			string memberName = firstFitMember.GetName();
			string memberClass = firstFitMember.GetDeclaringClass().FullName;
			if (methodsOrCtors[0].IsCtor())
			{
				throw Context.ReportRuntimeError3("msg.constructor.ambiguous", memberName, ScriptSignature(args), buf.ToString());
			}
			else
			{
				throw Context.ReportRuntimeError4("msg.method.ambiguous", memberClass, memberName, ScriptSignature(args), buf.ToString());
			}
		}
Ejemplo n.º 12
0
		private static void ReportWarning(Context cx, string messageId, string arg)
		{
			if (cx.HasFeature(Context.FEATURE_STRICT_MODE))
			{
				string msg = ScriptRuntime.GetMessage1(messageId, arg);
				Context.ReportWarning(msg);
			}
		}