/// <summary> Convert the value to an object. /// /// See ECMA 9.9. /// </summary> public static IScriptable ToObject(Context cx, IScriptable scope, object val) { if (val is IScriptable) { return((IScriptable)val); } if (val == null) { throw ScriptRuntime.TypeErrorById("msg.null.to.object"); } if (val == Undefined.Value) { throw ScriptRuntime.TypeErrorById("msg.undef.to.object"); } string className = val is string? "String" : (CliHelper.IsNumber(val) ? "Number" : (val is bool? "Boolean" : null)); if (className != null) { object [] args = new object [] { val }; scope = ScriptableObject.GetTopLevelScope(scope); return(ScriptRuntime.NewObject(cx == null ? Context.CurrentContext : cx, scope, className, args)); } // Extension: Wrap as a LiveConnect object. object wrapped = cx.Wrap(scope, val, null); if (wrapped is IScriptable) { return((IScriptable)wrapped); } throw ScriptRuntime.errorWithClassName("msg.invalid.type", val); }
/* * Analog of match_glob() in jsstr.c */ private static void match_glob(GlobData mdata, Context cx, IScriptable scope, int count, RegExpImpl reImpl) { if (mdata.arrayobj == null) { IScriptable s = ScriptableObject.GetTopLevelScope(scope); mdata.arrayobj = ScriptRuntime.NewObject(cx, s, "Array", null); } SubString matchsub = reImpl.lastMatch; string matchstr = matchsub.ToString(); mdata.arrayobj.Put(count, mdata.arrayobj, matchstr); }
public static void Init(Context cx, IScriptable scope, bool zealed) { BuiltinGlobal obj = new BuiltinGlobal(); for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) { string name; int arity = 1; switch (id) { case Id_decodeURI: name = "decodeURI"; break; case Id_decodeURIComponent: name = "decodeURIComponent"; break; case Id_encodeURI: name = "encodeURI"; break; case Id_encodeURIComponent: name = "encodeURIComponent"; break; case Id_escape: name = "escape"; break; case Id_eval: name = "eval"; break; case Id_isFinite: name = "isFinite"; break; case Id_isNaN: name = "isNaN"; break; case Id_isXMLName: name = "isXMLName"; break; case Id_parseFloat: name = "parseFloat"; break; case Id_parseInt: name = "parseInt"; arity = 2; break; case Id_unescape: name = "unescape"; break; case Id_uneval: name = "uneval"; break; default: throw Context.CodeBug(); } IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name, arity, scope); if (zealed) { f.SealObject(); } f.ExportAsScopeProperty(); } ScriptableObject.DefineProperty(scope, "NaN", (object)double.NaN, ScriptableObject.DONTENUM); ScriptableObject.DefineProperty(scope, "Infinity", (System.Double.PositiveInfinity), ScriptableObject.DONTENUM); ScriptableObject.DefineProperty(scope, "undefined", Undefined.Value, ScriptableObject.DONTENUM); string [] errorMethods = new string [] { "ConversionError", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "InternalError", "JavaException" }; /* * Each error constructor gets its own Error object as a prototype, * with the 'name' property set to the name of the error. */ for (int i = 0; i < errorMethods.Length; i++) { string name = errorMethods [i]; IScriptable errorProto = ScriptRuntime.NewObject(cx, scope, "Error", ScriptRuntime.EmptyArgs); errorProto.Put("name", errorProto, name); if (zealed) { if (errorProto is ScriptableObject) { ((ScriptableObject)errorProto).SealObject(); } } IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_new_CommonError, name, 1, scope); ctor.MarkAsConstructor(errorProto); if (zealed) { ctor.SealObject(); } ctor.ExportAsScopeProperty(); } }
/* * See ECMA 15.5.4.8. Modified to match JS 1.2 - optionally takes * a limit argument and accepts a regular expression as the split * argument. */ private static object ImplSplit(Context cx, IScriptable scope, string target, object [] args) { // create an empty Array to return; IScriptable top = GetTopLevelScope(scope); IScriptable result = ScriptRuntime.NewObject(cx, top, "Array", null); // return an array consisting of the target if no separator given // don't check against undefined, because we want // 'fooundefinedbar'.split(void 0) to split to ['foo', 'bar'] if (args.Length < 1) { result.Put(0, result, target); return(result); } // Use the second argument as the split limit, if given. bool limited = (args.Length > 1) && (args [1] != Undefined.Value); long limit = 0; // Initialize to avoid warning. if (limited) { /* Clamp limit between 0 and 1 + string length. */ limit = ScriptConvert.ToUint32(args [1]); if (limit > target.Length) { limit = 1 + target.Length; } } string separator = null; int [] matchlen = new int [1]; IScriptable re = null; RegExpProxy reProxy = null; if (args [0] is IScriptable) { reProxy = cx.RegExpProxy; if (reProxy != null) { IScriptable test = (IScriptable)args [0]; if (reProxy.IsRegExp(test)) { re = test; } } } if (re == null) { separator = ScriptConvert.ToString(args [0]); matchlen [0] = separator.Length; } // split target with separator or re int [] ip = new int [] { 0 }; int match; int len = 0; bool [] matched = new bool [] { false }; string [] [] parens = new string [] [] { null }; Context.Versions version = cx.Version; while ((match = find_split(cx, scope, target, separator, version, reProxy, re, ip, matchlen, matched, parens)) >= 0) { if ((limited && len >= limit) || (match > target.Length)) { break; } string substr; if (target.Length == 0) { substr = target; } else { substr = target.Substring(ip [0], (match) - (ip [0])); } result.Put(len, result, substr); len++; /* * Imitate perl's feature of including parenthesized substrings * that matched part of the delimiter in the new array, after the * split substring that was delimited. */ // CB, 02.01.2007: Don't do this, causes bug #287630 // https://bugzilla.mozilla.org/show_bug.cgi?query_format=specific&order=relevance+desc&bug_status=__open__&id=287630 /* * if (re != null && matched [0] == true) { * int size = parens [0].Length; * for (int num = 0; num < size; num++) { * if (limited && len >= limit) * break; * result.Put (len, result, parens [0] [num]); * len++; * } * matched [0] = false; * } */ ip [0] = match + matchlen [0]; if (version < Context.Versions.JS1_3 && version != Context.Versions.Default) { /* * Deviate from ECMA to imitate Perl, which omits a final * split unless a limit argument is given and big enough. */ if (!limited && ip [0] == target.Length) { break; } } } return(result); }