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); }
// ECMA-262 section 15.5.3.2 void fromCharCode(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.fromCharCode()"); var l = callFrame.PassedArgsCount; var str = new System.Text.StringBuilder(); for (var i = 0; i < l; i++) { var arg = callFrame.Arg(i); str.Append(Operations.Convert.ToChar.Run(Operations.Convert.ToUInt16.Run(ref arg))); } callFrame.Return.Set(str.ToString()); }
// ECMA-262, section 15.5.4.6 void concat(ref mdr.CallFrame callFrame) { Debug.WriteLine("Calling JSString.concat()"); var argLen = callFrame.PassedArgsCount; string thisString = callFrame.This.ToString(); if (argLen == 1) { callFrame.Return.Set(thisString + Operations.Convert.ToString.Run(ref callFrame.Arg0)); } string result = thisString; for (var i = 0; i < argLen; i++) { var tmp = callFrame.Arg(i); result += Operations.Convert.ToString.Run(ref tmp); } callFrame.Return.Set(result); }
static string FormatArgs(ref mdr.CallFrame callFrame) { var formatString = callFrame.Arg0.AsString(); StringBuilder str = new StringBuilder(); int escapeIdx = 0, nextEscapeIdx = 0; var nextArg = 1; while ((nextEscapeIdx = formatString.IndexOfAny(FormatChars, escapeIdx)) != -1) { // Append non-escape characters str.Append(formatString.Substring(escapeIdx, nextEscapeIdx - escapeIdx)); // If we're at the last character in the string, just break out of the loop if (nextEscapeIdx == formatString.Length - 1) { escapeIdx = nextEscapeIdx; break; } // Interpret escape character if (formatString[nextEscapeIdx] == '\\') { if (formatString[nextEscapeIdx + 1] == '%') { str.Append('%'); } else { str.AppendFormat("\\{0}", formatString[nextEscapeIdx + 1]); } } else if (formatString[nextEscapeIdx] == '%') { var arg = callFrame.Arg(nextArg++); if (formatString[nextEscapeIdx + 1] == 's') { str.Append(mjr.Operations.Convert.ToString.Run(ref arg)); } else if (formatString[nextEscapeIdx + 1] == 'd') { str.Append(mjr.Operations.Convert.ToInt64.Run(ref arg)); } else if (formatString[nextEscapeIdx + 1] == 'i') { str.Append(mjr.Operations.Convert.ToInt64.Run(ref arg)); } else if (formatString[nextEscapeIdx + 1] == 'f') { str.Append(mjr.Operations.Convert.ToDouble.Run(ref arg)); } else { str.AppendFormat("[%{0}]", formatString[nextEscapeIdx + 1]); } } // Advance past the escaped character escapeIdx = nextEscapeIdx + 2; } // Append any remaining characters str.Append(formatString.Substring(escapeIdx)); // Return the finished formatted string return(str.ToString()); }