public static void Call(ref mdr.CallFrame callFrame, int argsCount, int resultIndex, bool hasThis, bool isDirectEvalCall) { var values = callFrame.Values; var calleeFrame = new mdr.CallFrame(); var sp = resultIndex; calleeFrame.Function = values[sp++].AsDFunction(); if (hasThis) { calleeFrame.This = values[sp++].AsDObject(); } else { if (isDirectEvalCall) { calleeFrame.CallerFunction = callFrame.Function; calleeFrame.CallerContext = GetContext(ref callFrame); calleeFrame.This = callFrame.This; } else { calleeFrame.This = mdr.Runtime.Instance.GlobalContext; } } ReadArguments(ref callFrame, sp, argsCount, ref calleeFrame); calleeFrame.Function.Call(ref calleeFrame); values[resultIndex] = calleeFrame.Return; }
public static void createEvent(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling document.createEvent"); //String eventClassString = callFrame.Arg0.ToString(); //DOMBinding.JSEvent evt = DOMBinding.JSEvent.createEvent(eventClassString, callFrame.This); //callFrame.Return.Set(evt); }
// TODO: Remove this; we need instead to generate a binding based upon the NamedConstructor WebIDL attribute. // See http://dev.w3.org/html5/spec/the-img-element.html#the-img-element for how our IDL should look. public static void Image(ref mdr.CallFrame callFrame) { Debug.WriteLine("++$> calling Image constructor"); var window = (ContentWindow)mjr.JSRuntime.Instance.GlobalContext; callFrame.Return.SetNullable(window.Document.CreateElement("img")); }
public static void ReadFromContext(ref mdr.CallFrame callFrame, int resultIndex, int valueIndex, int fieldId) { var pd = GetPropertyDescriptor(ref callFrame, valueIndex, fieldId); var context = GetContext(ref callFrame); pd.Get(context, ref callFrame.Values[resultIndex]); }
private void ctor(ref mdr.CallFrame callFrame) { if (IsConstrutor) { mdr.DObject newobject = new mdr.DObject(TargetPrototype); if (callFrame.PassedArgsCount > 0) { newobject.PrimitiveValue.Set(Operations.Convert.ToBoolean.Run(ref callFrame.Arg0)); } else { newobject.PrimitiveValue.Set(false); } //newobject.Class = "Boolean"; callFrame.This = (newobject); } else { if (callFrame.PassedArgsCount > 0) { callFrame.Return.Set(Operations.Convert.ToBoolean.Run(ref callFrame.Arg0)); } else { callFrame.Return.Set(false); } } }
// ECMA-262 section 15.5.4.19 void toLocaleUpperCase(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.toLocaleUpperCase()"); string thisString = callFrame.This.ToString(); callFrame.Return.Set(thisString.ToUpper()); }
// ECMA-262 section 15.5.4.10 void match(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.match()"); string S = callFrame.This.ToString(); mdr.DRegExp rx = callFrame.Arg0.AsDObject() as mdr.DRegExp; if (rx == null) { rx = new mdr.DRegExp(callFrame.Arg0.AsString()); } if (!rx.Global) { callFrame.Return.Set(rx.ExecImplementation(S)); return; } mdr.DArray result = new mdr.DArray(); int i = 0; foreach (Match match in (rx.Value).Matches(S)) { foreach (Group group in match.Groups) { //result.SetField(i++, new mdr.DString(group.Value.ToString())); result.SetField(i++, group.Value); } } callFrame.Return.Set(result); }
// ECMA-262 section 15.5.4.20 void trim(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.trim()"); string thisString = callFrame.This.ToString(); callFrame.Return.Set(thisString.Trim()); }
public static void clearInterval(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling window.clearInterval"); int timer_id = callFrame.Arg0.AsInt32(); HTMLRuntime.Instance.TimerQueue.ClearInterval(timer_id); }
internal static void EvalString(string inputString, ref mdr.DValue result, mdr.DFunction callerFunction = null, mdr.DObject callerContext = null, mdr.DObject thisArg = null) { var funcMetadata = JSParser.ParseScript(inputString).Expression.Metadata; var func = new mdr.DFunction(funcMetadata, null); var tempCallFrame = new mdr.CallFrame(); bool isDirectEval = callerContext != null; if (isDirectEval) { //function will behave as if it was the caller Debug.Assert(thisArg != null && callerFunction != null && callerContext != null, "Invalid situation! Direct eval call must have thisArg, callerFunction, callerContext set"); funcMetadata.Scope.IsProgram = false; funcMetadata.Scope.IsEvalFunction = true; funcMetadata.ParentFunction = (JSFunctionMetadata)callerFunction.Metadata; tempCallFrame.CallerContext = callerContext; tempCallFrame.This = thisArg; } else { //This will behave just like a program code tempCallFrame.CallerContext = mdr.Runtime.Instance.GlobalContext; tempCallFrame.This = (mdr.Runtime.Instance.GlobalContext); } //TODO: find a way to assign a name to this //funcMetadata.Name += "_eval"; //After we know the ParentFunction tempCallFrame.Function = func; tempCallFrame.Signature = mdr.DFunctionSignature.EmptySignature; func.Call(ref tempCallFrame); result.Set(ref tempCallFrame.Return); }
private static mdr.DArray CreateArgumentsObject(ref mdr.CallFrame callFrame) { var argsCount = callFrame.ExpectedArgsCount; if (callFrame.PassedArgsCount > callFrame.ExpectedArgsCount) { argsCount = callFrame.PassedArgsCount; } var arguments = new mdr.DArray(argsCount); switch (callFrame.PassedArgsCount) { case 0: break; case 1: arguments.Elements[0] = callFrame.Arg0; goto case 0; case 2: arguments.Elements[1] = callFrame.Arg1; goto case 1; case 3: arguments.Elements[2] = callFrame.Arg2; goto case 2; case 4: arguments.Elements[3] = callFrame.Arg3; goto case 3; default: Array.Copy(callFrame.Arguments, 0, arguments.Elements, 4, callFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount); goto case 4; } ///To comply with 10.6 item 6, we add a "length" property to prevent it affecting the actual array, ///TODO: in future version os Javscript, this is going change and Arguments is acutally an array arguments.DefineOwnProperty("length", callFrame.PassedArgsCount, mdr.PropertyDescriptor.Attributes.Data | mdr.PropertyDescriptor.Attributes.NotEnumerable); return(arguments); }
public int RunScriptProgram(JSFunctionMetadata prgMetadata) { try { //TODO: It should be checked later. This situation should not happen if (prgMetadata == null) { return(0); } var prgFunc = new mdr.DFunction(prgMetadata, null); mdr.CallFrame callFrame = new mdr.CallFrame(); callFrame.Function = prgFunc; callFrame.Signature = mdr.DFunctionSignature.EmptySignature; callFrame.This = (GlobalContext); prgFunc.Call(ref callFrame); return(0); } catch (mjr.JSException e) { WriteJSException(e); } catch (Exception e) { Diagnostics.WriteException(e); } return(1); }
public static void CreateArgumentsObject(ref mdr.CallFrame callFrame, int argumentsIndex) { var arguments = JSFunctionArguments.CreateArgumentsObject(ref callFrame, GetContext(ref callFrame)); callFrame.Values[argumentsIndex].Set(arguments); SetArguments(ref callFrame, arguments); }
public static void ReadProperty(ref mdr.CallFrame callFrame, int resultIndex, int fieldId) { var values = callFrame.Values; var container = values[resultIndex].AsDObject(); container.GetFieldByFieldId(fieldId, ref values[resultIndex]); }
public static void CreateFunction(ref mdr.CallFrame callFrame, int funcDefIndex, mdr.DObject context, ref Stack stack) { //Debug.WriteLine("calling Exec.CreateFunction"); var funcDef = ((JSFunctionMetadata)callFrame.Function.Metadata).SubFunctions[funcDefIndex]; var func = new mdr.DFunction(funcDef, context); stack.Items[stack.Sp++].Set(func);; }
public static void ReadIndexer(ref mdr.CallFrame callFrame, int resultIndex) { //TODO: make this dynamically adaptive var values = callFrame.Values; var container = values[resultIndex].AsDObject(); container.GetField(ref values[resultIndex + 1], ref values[resultIndex]); }
public static void CreateFunction(ref mdr.CallFrame callFrame, int resultIndex, int functionIndex) { var func = new mdr.DFunction( ((JSFunctionMetadata)callFrame.Function.Metadata).SubFunctions[functionIndex] , GetContext(ref callFrame)); callFrame.Values[resultIndex].Set(func); }
// ECMA-262 section 15.5.4.3 void valueOf(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.valueOf()"); if (!(callFrame.This is mdr.DString)) { throw new Exception("String.prototype.valueOf is not generic"); } callFrame.Return.Set(callFrame.This.ToString()); }
void FirstExecute(ref mdr.CallFrame callFrame) { ///We may have multiple function objects point to the same function ///therefore, this code might be executed multiple times, but once for each function object. Prepare(); Execute = NormalExecute; callFrame.Function.JittedCode = Execute; //To make sure from now on, it goes to the right function, also to prevent instanciating a new delegate object. NormalExecute(ref callFrame); }
// ECMA-262 section 15.6.4.3 private static void valueOf(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSBoolean.valueOf"); if (callFrame.This.ValueType != mdr.ValueTypes.Boolean) { throw new Exception("Boolean.prototype.valueOf is not generic"); } callFrame.Return.Set(callFrame.This.ToBoolean()); }
public PositionListener(mdr.DFunction handler, mdr.DFunction errorHandler, PositionListenerOptions options) { this._handler = handler; // TODO: Unused. /*this._errorHandler = errorHandler; this._options = options;*/ _callFrame = new mdr.CallFrame(); _callFrame.Function = _handler; }
public PositionListener(mdr.DFunction handler, mdr.DFunction errorHandler, PositionListenerOptions options) { this._handler = handler; // TODO: Unused. /*this._errorHandler = errorHandler; * this._options = options;*/ _callFrame = new mdr.CallFrame(); _callFrame.Function = _handler; }
public static void Execute(ref mdr.CallFrame callFrame, int fromIndex, int toIndex) { var ics = callFrame.Function.Metadata.InlineCache; var i = fromIndex; while (i <= toIndex) { Debug.WriteLine("Running {0}:{1}", i, ics[i].Method.Name); i = ics[i](ref callFrame, i); } }
public static void CreateArray(ref mdr.CallFrame callFrame, int resultIndex, int valuesCount) { var values = callFrame.Values; var array = new mdr.DArray(valuesCount); for (var i = valuesCount - 1; i >= 0; --i) { array.Elements[i] = values[resultIndex + i]; } values[resultIndex].Set(array); }
/// <summary> /// We use this function that may not be inlined and also enabled the common case to be inlined /// </summary> public static mdr.PropertyDescriptor GetPropertyDescriptor_Slow(ref mdr.CallFrame callFrame, int valueIndex, int fieldId) { var values = callFrame.Values; Debug.Assert(values[valueIndex].ValueType == mdr.ValueTypes.Undefined, "callFrame.Values[{0}].ValueType = {1} and is not undefined", valueIndex, values[valueIndex].ValueType); //first time visit var pd = GetContext(ref callFrame).GetPropertyDescriptorByFieldId(fieldId); values[valueIndex].Set(pd); return(pd); }
public static void New(ref mdr.CallFrame callFrame, int argsCount, int resultIndex) { var values = callFrame.Values; var calleeFrame = new mdr.CallFrame(); var sp = resultIndex; calleeFrame.Function = values[sp++].AsDFunction(); ReadArguments(ref callFrame, sp, argsCount, ref calleeFrame); calleeFrame.Function.Construct(ref calleeFrame); values[resultIndex].Set(calleeFrame.This); }
public bool HandleEvent(JSEvent e) { try { Debug.WriteLine("Listeners loop starts here"); var callFrame = new mdr.CallFrame(); callFrame.PassedArgsCount = 1; callFrame.Arg0.Set(e); callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 1); callFrame.This = e.CurrentTarget; mdr.DFunction handler; bool eventPropagationStopped = false; if (_listeners == null) { return(false); } Debug.WriteLine("Listeners loop with " + _listeners.Count + " listeners"); //The event listener loop (inner loop) for (var i = 0; i < _listeners.Count; ++i) { handler = _listeners[i]; callFrame.Function = handler; if (handler != null) { if (_useCaptures.Contains(handler)) { e.Phase = JSEvent.Phases.Captureing; //TODO: Capturing } callFrame.Function.Call(ref callFrame); if (e.PropagationStopped) { eventPropagationStopped = true; } if (e.ImmediatePropagationStopped) { eventPropagationStopped = true; break; } } } return(eventPropagationStopped); } catch (System.Exception ex) { Diagnostics.WriteException(ex, "when processing event"); return(false); } }
// ECMA-262 section 15.5.4.15 void substring(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.substring()"); string thisString = callFrame.This.ToString(); int argsCount = callFrame.PassedArgsCount; int start = Math.Min(Math.Max(callFrame.Arg0.AsInt32(), 0), thisString.Length); int end = Math.Min(Math.Max((argsCount > 1) ? callFrame.Arg1.AsInt32() : thisString.Length, 0), thisString.Length); int from = Math.Min(start, end); int to = Math.Max(start, end); callFrame.Return.Set(thisString.Substring(from, to - from)); }
public static void removeEventListener(ref mdr.CallFrame callFrame) { var eventName = "on" + callFrame.Arg0.AsString(); var listenerFunction = callFrame.Arg1.AsDFunction(); var eventListeners = GetEventListeners(callFrame.This, eventName); if (eventListeners == null) { return; } eventListeners.Remove(listenerFunction); }
private static void SetTimer(ref mdr.CallFrame callFrame, bool isInterval) { mdr.DFunction handler = null; //TODO: We might need to do it better using sth like Callable property if (callFrame.Arg0.ValueType == mdr.ValueTypes.Function) { handler = callFrame.Arg0.AsDFunction(); } else if (callFrame.Arg0.ValueType == mdr.ValueTypes.String) { handler = HTMLRuntime.Instance.PrepareScript(callFrame.Arg0.AsString()); } else { Debug.WriteLine("Invalid argument type {0} for setInterval", callFrame.Arg0.ValueType); //Trace.Fail("Invalid argument type {0} for setInterval", callFrame.Arg0.ValueType); } //TODO: Consider the case in which it's nor function or string long times = (long)callFrame.Arg1.AsInt32(); int argCount = callFrame.PassedArgsCount; TimeoutEvent timeout = new TimeoutEvent(times, isInterval); timeout.CallFrame.Function = handler; Debug.WriteLineIf( handler == null , "The {0} handler function of timer {1} is null and arg0.ValueType={2} with value {3}" , (isInterval ? "setInterval" : "setTimeout") , timeout.Id , callFrame.Arg0.ValueType , mjr.Operations.Convert.ToString.Run(ref callFrame.Arg0) ); //TODO: we need the following ASSERT, but for some reason, this will cause strange problems with WrappedObject.cpp:85 gcGetWrapper(), so we're going to catch this again later in TimerQueue.ProcessEvents //Debug.Assert(timeout.CallFrame.Function != null, "The setTimeout handler function must not be null"); if (argCount > 2) { timeout.CallFrame.PassedArgsCount = argCount - 2; if (timeout.CallFrame.PassedArgsCount > 4) { timeout.CallFrame.Arguments = new mdr.DValue[timeout.CallFrame.PassedArgsCount - 4]; } for (int i = 0; i < argCount - 2; i++) { var arg = callFrame.Arg(i + 2); timeout.CallFrame.SetArg(i, ref arg); } } HTMLRuntime.Instance.TimerQueue.SetTimeoutOrInterval(timeout); callFrame.Return.Set(timeout.Id); }
public override void Execute(ref mdr.CallFrame callFrame) { if (SpecializedMethod != null && !Metadata.IsBlackListed) { SpecializedMethod(ref callFrame); } else { ///NOTE: don't try to use interpreter instances since we may run this function recursively. var currProfiler = Profiler; if (Profiler != null) { var canProfile = //Profiler.ExecutionCount > 0 &&//We don't want to profile in the very first execution SpecializedMethodHandle == null &&//to be sure function is not being Jitted !Metadata.IsBlackListed ; ++Profiler.ExecutionCount; if (canProfile) { Profiler.Prepare(); } else { Profiler = null; //Remove it to prevent profiling } } if (GenericMethod != null) { GenericMethod(ref callFrame); } else if (JSRuntime.Instance.Configuration.EnableRecursiveInterpreter) { (new CodeGen.Interpreter()).Execute(ref callFrame); } else { Operations.ICMethods.Execute(ref callFrame, 0, Metadata.InlineCache.Length - 1); } if (currProfiler == null && JSRuntime.Instance.Configuration.EnableProfiling && !Metadata.IsBlackListed) { //This was the first excution currProfiler = new CodeGen.Profiler(Metadata); currProfiler.ExecutionCount = 1; } Profiler = currProfiler; //put it back } }
public static void Call(ref mdr.CallFrame callFrame, int argsCount, int resultIndex, bool hasThis, bool isDirectEvalCall) { var values = callFrame.Values; var calleeFrame = new mdr.CallFrame(); var sp = resultIndex; calleeFrame.Function = values[sp++].AsDFunction(); if (hasThis) calleeFrame.This = values[sp++].AsDObject(); else { if (isDirectEvalCall) { calleeFrame.CallerFunction = callFrame.Function; calleeFrame.CallerContext = GetContext(ref callFrame); calleeFrame.This = callFrame.This; } else calleeFrame.This = mdr.Runtime.Instance.GlobalContext; } ReadArguments(ref callFrame, sp, argsCount, ref calleeFrame); calleeFrame.Function.Call(ref calleeFrame); values[resultIndex] = calleeFrame.Return; }
public static void New(int argsCount, ref Stack stack) { //Debug.WriteLine("calling Exec.New"); var callFrame = new mdr.CallFrame(); ReadArguments(ref callFrame, argsCount, ref stack); int funcIndex = stack.Sp - argsCount - 1; callFrame.Function = stack.Items[funcIndex].AsDFunction(); callFrame.Function.Construct(ref callFrame); stack.Items[funcIndex].Set(callFrame.This); stack.Sp = funcIndex + 1; }
public static void Call(ref mdr.CallFrame callerFrame, mdr.DObject context, int argsCount, bool hasThis, bool isDirectEvalCall, ref Stack stack) { //Debug.WriteLine("calling Exec.Call"); var calleeFrame = new mdr.CallFrame(); ReadArguments(ref calleeFrame, argsCount, ref stack); int thisIndex = stack.Sp - argsCount - 1; int funcIndex; if (hasThis) { calleeFrame.This = Convert.ToObject.Run(ref stack.Items[thisIndex]); funcIndex = thisIndex - 1; } else { funcIndex = thisIndex; if (isDirectEvalCall)// && calleeFrame.Function == Builtins.JSGlobalObject.BuiltinEval) //We don't need to check for built in eval, .. { calleeFrame.CallerFunction = callerFrame.Function; calleeFrame.CallerContext = context; calleeFrame.This = callerFrame.This; } else calleeFrame.This = (mdr.Runtime.Instance.GlobalContext); } calleeFrame.Function = stack.Items[funcIndex].AsDFunction(); int returnIndex = funcIndex; calleeFrame.Function.Call(ref calleeFrame); stack.Items[returnIndex] = calleeFrame.Return; stack.Sp = returnIndex + 1; }
public JSFunction() : base(mdr.Runtime.Instance.DFunctionPrototype, "Function") { JittedCode = (ref mdr.CallFrame callFrame) => { //ECMA 15.3.2.1 Debug.WriteLine("calling new Function"); StringBuilder properFunctionDeclaration = new StringBuilder("return function "); int argsCount = 0; string body; if (callFrame.PassedArgsCount == 0){ argsCount = 0; body = ""; } else if (callFrame.PassedArgsCount == 1){ argsCount = 0; body = callFrame.Arg(0).AsString(); } else{ argsCount = callFrame.PassedArgsCount - 1; body = callFrame.Arg(callFrame.PassedArgsCount - 1).AsString(); } properFunctionDeclaration.Append("("); for (int i = 0; i < argsCount;i++ ) { properFunctionDeclaration.Append(callFrame.Arg(i).AsString()); if (i < argsCount - 1) { properFunctionDeclaration.Append(","); } } properFunctionDeclaration.Append(")"); properFunctionDeclaration.Append("{").Append(body).Append("}"); string properFunctionDecString = properFunctionDeclaration.ToString(); Debug.WriteLine("new Function: {0}", properFunctionDecString); JSGlobalObject.EvalString(properFunctionDecString, ref callFrame.Return); if (IsConstrutor) callFrame.This = callFrame.Return.AsDFunction(); }; // toString is implementd in DObject //TargetPrototype.DefineOwnProperty("toString", new mdr.DFunction((ref mdr.CallFrame callFrame) => //{ // Debug.WriteLine("calling JSFunction.toString"); // var function = callFrame.This as mdr.DFunction; // if (function == null) // Trace.Fail("TypeError"); // var funcStream = new System.IO.StringWriter(); // funcStream.WriteLine("{0} {{", Declaration(function)); // var astWriter = new mjr.Expressions.AstWriter(funcStream); // astWriter.Execute((JSFunctionMetadata)function.Metadata); // funcStream.WriteLine("}"); // callFrame.Return.Set(funcStream.ToString()); // //callFrame.Return.Set(function.ToString()); //}), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data); TargetPrototype.DefineOwnProperty("apply", new mdr.DFunction((ref mdr.CallFrame callFrame) => { Debug.WriteLine("calling JSFunction.apply"); var tmpCallFrame = new mdr.CallFrame(); tmpCallFrame.Function = callFrame.This.ToDFunction(); if (tmpCallFrame.Function == null) throw new InvalidOperationException(".apply should be called on a Function object"); if (mdr.ValueTypesHelper.IsDefined(callFrame.Arg0.ValueType)) tmpCallFrame.This = Operations.Convert.ToObject.Run(ref callFrame.Arg0); else tmpCallFrame.This = mdr.Runtime.Instance.GlobalContext; if (callFrame.PassedArgsCount > 1) { if (callFrame.Arg1.ValueType != mdr.ValueTypes.Array) throw new InvalidOperationException("second argument of .apply should be an array"); var args = callFrame.Arg1.AsDArray(); tmpCallFrame.PassedArgsCount = args.Length; switch (tmpCallFrame.PassedArgsCount) { //putting goto case x will crash the mono on linux case 0: break; case 1: tmpCallFrame.Arg0 = args.Elements[0]; break; case 2: tmpCallFrame.Arg1 = args.Elements[1]; goto case 1; //tmpCallFrame.Arg0 = args.Elements[0]; //break; case 3: tmpCallFrame.Arg2 = args.Elements[2]; goto case 2; //tmpCallFrame.Arg1 = args.Elements[1]; //tmpCallFrame.Arg0 = args.Elements[0]; //break; case 4: tmpCallFrame.Arg3 = args.Elements[3]; goto case 3; //tmpCallFrame.Arg2 = args.Elements[2]; //tmpCallFrame.Arg1 = args.Elements[1]; //tmpCallFrame.Arg0 = args.Elements[0]; //break; default: tmpCallFrame.Arguments = JSFunctionArguments.Allocate(tmpCallFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount); Array.Copy(args.Elements, mdr.CallFrame.InlineArgsCount, tmpCallFrame.Arguments, 0, tmpCallFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount); goto case 4; //tmpCallFrame.Arg3 = args.Elements[3]; //tmpCallFrame.Arg2 = args.Elements[2]; //tmpCallFrame.Arg1 = args.Elements[1]; //tmpCallFrame.Arg0 = args.Elements[0]; //break; } tmpCallFrame.Signature = new mdr.DFunctionSignature(args.Elements, tmpCallFrame.PassedArgsCount); } else tmpCallFrame.PassedArgsCount = 0; tmpCallFrame.Function.Call(ref tmpCallFrame); if (tmpCallFrame.Arguments != null) JSFunctionArguments.Release(tmpCallFrame.Arguments); callFrame.Return = tmpCallFrame.Return; }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data); TargetPrototype.DefineOwnProperty("call", new mdr.DFunction((ref mdr.CallFrame callFrame) => { Debug.WriteLine("calling JSFunction.call"); var tmpCallFrame = new mdr.CallFrame(); tmpCallFrame.Function = callFrame.This.ToDFunction(); if (tmpCallFrame.Function == null) throw new InvalidOperationException(".call should be called on a Function object"); switch (callFrame.PassedArgsCount) { case 0: tmpCallFrame.PassedArgsCount = 0; tmpCallFrame.This = mdr.Runtime.Instance.GlobalContext; //throw new InvalidOperationException(".call should be called with at least one parameter"); break; case 1: //tmpCallFrame.This = callFrame.Arg0; if (mdr.ValueTypesHelper.IsDefined(callFrame.Arg0.ValueType)) tmpCallFrame.This = Operations.Convert.ToObject.Run(ref callFrame.Arg0); else tmpCallFrame.This = mdr.Runtime.Instance.GlobalContext; tmpCallFrame.PassedArgsCount = callFrame.PassedArgsCount - 1; break; case 2: tmpCallFrame.Arg0 = callFrame.Arg1; goto case 1; //tmpCallFrame.This = callFrame.Arg0; //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1; //break; case 3: tmpCallFrame.Arg1 = callFrame.Arg2; goto case 2; //tmpCallFrame.Arg0 = callFrame.Arg1; //tmpCallFrame.This = callFrame.Arg0; //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1; //break; case 4: tmpCallFrame.Arg2 = callFrame.Arg3; goto case 3; //tmpCallFrame.Arg1 = callFrame.Arg2; //tmpCallFrame.Arg0 = callFrame.Arg1; //tmpCallFrame.This = callFrame.Arg0; //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1; //break; case 5: tmpCallFrame.Arg3 = callFrame.Arguments[0]; goto case 4; //tmpCallFrame.Arg2 = callFrame.Arg3; //tmpCallFrame.Arg1 = callFrame.Arg2; //tmpCallFrame.Arg0 = callFrame.Arg1; //tmpCallFrame.This = callFrame.Arg0; //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1; //break; default: tmpCallFrame.Arguments = JSFunctionArguments.Allocate(tmpCallFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount); Array.Copy(tmpCallFrame.Arguments, 0, callFrame.Arguments, 1, callFrame.PassedArgsCount - 1 - mdr.CallFrame.InlineArgsCount); tmpCallFrame.Arg3 = callFrame.Arguments[0]; goto case 5; //tmpCallFrame.Arg2 = callFrame.Arg3; //tmpCallFrame.Arg1 = callFrame.Arg2; //tmpCallFrame.Arg0 = callFrame.Arg1; //tmpCallFrame.This = callFrame.Arg0; //tmpCallFrame.ArgsCount = callFrame.ArgsCount - 1; //break; } tmpCallFrame.Signature = new mdr.DFunctionSignature(ref tmpCallFrame, tmpCallFrame.PassedArgsCount); tmpCallFrame.Function.Call(ref tmpCallFrame); if (tmpCallFrame.Arguments != null) JSFunctionArguments.Release(tmpCallFrame.Arguments); callFrame.Return = tmpCallFrame.Return; }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data); /*TargetPrototype.DefineOwnProperty("bind", new mdr.DFunction((ref mdr.CallFrame callFrame) => { Debug.WriteLine("calling JSFunction.bind"); Trace.Fail("Unimplemented"); }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);*/ }
public static string ToString(ref mdr.DValue arg) { //TODO: it seems eventually, this is the right implementation, but for now, we use the special implementation //mdr.DValue output; //if (Operations.Internals.CallToStringProperty(Operations.Convert.ToObject.Run(ref arg), out output)) // return output.AsString(); //else // return Operations.Convert.ToString.Run(ref arg); string s; if (!mdr.ValueTypesHelper.IsObject(arg.ValueType)) { s = Operations.Convert.ToString.Run(ref arg); } else { var argObj = arg.AsDObject(); //TODO: should we call ToObject(arg) here instead?! var toString = argObj.GetField("toString"); if (toString.ValueType == mdr.ValueTypes.Function) { var cf = new mdr.CallFrame(); cf.Function = toString.AsDFunction(); cf.Signature = mdr.DFunctionSignature.EmptySignature; cf.This = argObj; cf.Arguments = null; cf.Function.Call(ref cf); s = Operations.Convert.ToString.Run(ref cf.Return); } else { s = arg.AsString(); } } return s; }
// ECMA-262, section 15.5.4.11 void replace(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.replace()"); string source = Operations.Convert.ToString.Run(callFrame.This); if (callFrame.PassedArgsCount == 0 || source.Length == 0 //This means if we enter the code, we have some chars in the string and don't have to keep checking the length ) { callFrame.Return.Set(source); return; } //Trace.Assert(!string.IsNullOrEmpty(source), "Invalid situation, we should have returned by now!"); var regexp = callFrame.Arg0.As<mdr.DRegExp>(); if (regexp != null) { int count; int lastIndex; if (regexp.Global) { count = int.MaxValue; lastIndex = 0; regexp.LastIndex = 0; } else { count = 1; lastIndex = Math.Max(0, regexp.LastIndex - 1); } var result = source; if (lastIndex < source.Length) { if (callFrame.Arg1.ValueType == mdr.ValueTypes.Function) { var function = callFrame.Arg1.AsDFunction(); result = regexp.Value.Replace(source, (Match m) => { mdr.CallFrame replaceCallFrame = new mdr.CallFrame(); replaceCallFrame.Function = function; replaceCallFrame.This = (JSRuntime.Instance.GlobalContext); if (!regexp.Global) { regexp.LastIndex = m.Index + 1; } replaceCallFrame.PassedArgsCount = m.Groups.Count + 2; var extraArgsCount = replaceCallFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount; if (extraArgsCount > 0) replaceCallFrame.Arguments = new mdr.DValue[extraArgsCount]; replaceCallFrame.SetArg(0, m.Value); int i; for (i = 1; i < m.Groups.Count; i++) { if (m.Groups[i].Success) { replaceCallFrame.SetArg(i, m.Groups[i].Value); } else { replaceCallFrame.SetArg(i, mdr.Runtime.Instance.DefaultDUndefined); } } replaceCallFrame.SetArg(i++, m.Index); replaceCallFrame.SetArg(i++, source); replaceCallFrame.Signature = new mdr.DFunctionSignature(ref replaceCallFrame, i); function.Call(ref replaceCallFrame); return replaceCallFrame.Return.AsString(); }, count, lastIndex); } else { var newString = Operations.Convert.ToString.Run(ref callFrame.Arg1); result = regexp.Value.Replace(source, (Match m) => { if (!regexp.Global) { regexp.LastIndex = m.Index + 1; } string after = source.Substring(Math.Min(source.Length - 1, m.Index + m.Length)); return EvaluateReplacePattern(m.Value, source.Substring(0, m.Index), after, newString, m.Groups); }, count, lastIndex); } } callFrame.Return.Set(result); return; } else { string search = callFrame.Arg0.AsString(); int index = source.IndexOf(search); if (index != -1) { if (callFrame.Arg1.ValueType == mdr.ValueTypes.Function) { var function = callFrame.Arg1.AsDFunction(); mdr.CallFrame replaceCallFrame = new mdr.CallFrame(); replaceCallFrame.Function = function; replaceCallFrame.This = (JSRuntime.Instance.GlobalContext); replaceCallFrame.SetArg(0, search); replaceCallFrame.SetArg(1, index); replaceCallFrame.SetArg(2, source); replaceCallFrame.PassedArgsCount = 3; replaceCallFrame.Signature = new mdr.DFunctionSignature(ref replaceCallFrame, 3); function.Call(ref replaceCallFrame); string replaceString = Operations.Convert.ToString.Run(ref replaceCallFrame.Return); callFrame.Return.Set(source.Substring(0, index) + replaceString + source.Substring(index + search.Length)); return; } else { string replaceValue = Operations.Convert.ToString.Run(ref callFrame.Arg1); string before = source.Substring(0, index); string after = source.Substring(index + search.Length); string newString = EvaluateReplacePattern(search, before, after, replaceValue, null); callFrame.Return.Set(before + newString + after); return; } } else { callFrame.Return.Set(source); return; } } }
public bool HandleEvent(JSEvent e) { try { Debug.WriteLine("Listeners loop starts here"); var callFrame = new mdr.CallFrame(); callFrame.PassedArgsCount = 1; callFrame.Arg0.Set(e); callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 1); callFrame.This = e.CurrentTarget; mdr.DFunction handler; bool eventPropagationStopped = false; if (_listeners == null) { return false; } Debug.WriteLine("Listeners loop with " + _listeners.Count + " listeners"); //The event listener loop (inner loop) for (var i = 0; i < _listeners.Count; ++i) { handler = _listeners[i]; callFrame.Function = handler; if (handler != null) { if (_useCaptures.Contains(handler)) { e.Phase = JSEvent.Phases.Captureing; //TODO: Capturing } callFrame.Function.Call(ref callFrame); if (e.PropagationStopped) { eventPropagationStopped = true; } if (e.ImmediatePropagationStopped) { eventPropagationStopped = true; break; } } } return eventPropagationStopped; } catch (System.Exception ex) { Diagnostics.WriteException(ex, "when processing event"); return false; } }
public override void Execute(ref mdr.DValue result, ref mdr.CallFrame callFrame, Interpreter interpreter) { interpreter.PushLocation(this); var tmpCallFrame = new mdr.CallFrame(); Function.Execute(ref result, ref callFrame, interpreter); interpreter.LoadArguments(this.Arguments, ref tmpCallFrame, ref callFrame); tmpCallFrame.Function = result.AsDFunction(); JSRuntime.StopTimer(interpreter.Timer); tmpCallFrame.Function.Construct(ref tmpCallFrame); JSRuntime.StartTimer(interpreter.Timer); result.Set(tmpCallFrame.This); interpreter.PopLocation(this, tmpCallFrame.Function); }
public override void Execute(ref mdr.DValue result, ref mdr.CallFrame callFrame, Interpreter interpreter) { interpreter.PushLocation(this); var tmpCallFrame = new mdr.CallFrame(); Function.Execute(ref result, ref callFrame, interpreter); if (ThisArg != null) { var thisValue = new mdr.DValue(); ThisArg.Execute(ref thisValue, ref callFrame, interpreter); tmpCallFrame.This = thisValue.AsDObject(); } else if (IsDirectEvalCall) { tmpCallFrame.CallerFunction = callFrame.Function; tmpCallFrame.CallerContext = interpreter.Context; tmpCallFrame.This = callFrame.This; } else { tmpCallFrame.This = mdr.Runtime.Instance.GlobalContext; } interpreter.LoadArguments(this.Arguments, ref tmpCallFrame, ref callFrame); tmpCallFrame.Function = result.AsDFunction(); JSRuntime.StopTimer(interpreter.Timer); tmpCallFrame.Function.Call(ref tmpCallFrame); JSRuntime.StartTimer(interpreter.Timer); result = tmpCallFrame.Return; interpreter.PopLocation(this, tmpCallFrame.Function); }