public override object ExecIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, object[] args) { if (!f.HasTag(STRING_TAG)) { return base.ExecIdCall(f, cx, scope, thisObj, args); } int id = f.MethodId(); for (; ; ) { switch (id) { case ConstructorId_charAt: case ConstructorId_charCodeAt: case ConstructorId_indexOf: case ConstructorId_lastIndexOf: case ConstructorId_split: case ConstructorId_substring: case ConstructorId_toLowerCase: case ConstructorId_toUpperCase: case ConstructorId_substr: case ConstructorId_concat: case ConstructorId_slice: case ConstructorId_equalsIgnoreCase: case ConstructorId_match: case ConstructorId_search: case ConstructorId_replace: case ConstructorId_localeCompare: case ConstructorId_toLocaleLowerCase: { if (args.Length > 0) { thisObj = ScriptRuntime.ToObject(scope, ScriptRuntime.ToCharSequence(args[0])); object[] newArgs = new object[args.Length - 1]; for (int i = 0; i < newArgs.Length; i++) { newArgs[i] = args[i + 1]; } args = newArgs; } else { thisObj = ScriptRuntime.ToObject(scope, ScriptRuntime.ToCharSequence(thisObj)); } id = -id; goto again_continue; } case ConstructorId_fromCharCode: { int N = args.Length; if (N < 1) { return string.Empty; } StringBuilder sb = new StringBuilder(N); for (int i = 0; i != N; ++i) { sb.Append(ScriptRuntime.ToUint16(args[i])); } return sb.ToString(); } case Id_constructor: { CharSequence s = (args.Length >= 1) ? ScriptRuntime.ToCharSequence(args[0]) : string.Empty; if (thisObj == null) { // new String(val) creates a new String object. return new Rhino.NativeString(s); } // String(val) converts val to a string value. return s is string ? s : s.ToString(); } case Id_toString: case Id_valueOf: { // ECMA 15.5.4.2: 'the toString function is not generic. CharSequence cs = RealThis(thisObj, f).@string; return cs is string ? cs : cs.ToString(); } case Id_toSource: { CharSequence s = RealThis(thisObj, f).@string; return "(new String(\"" + ScriptRuntime.EscapeString(s.ToString()) + "\"))"; } case Id_charAt: case Id_charCodeAt: { // See ECMA 15.5.4.[4,5] CharSequence target = ScriptRuntime.ToCharSequence(thisObj); double pos = ScriptRuntime.ToInteger(args, 0); if (pos < 0 || pos >= target.Length) { if (id == Id_charAt) { return string.Empty; } else { return ScriptRuntime.NaNobj; } } char c = target[(int)pos]; if (id == Id_charAt) { return c.ToString(); } else { return ScriptRuntime.WrapInt(c); } goto case Id_indexOf; } case Id_indexOf: { return ScriptRuntime.WrapInt(Js_indexOf(ScriptRuntime.ToString(thisObj), args)); } case Id_lastIndexOf: { return ScriptRuntime.WrapInt(Js_lastIndexOf(ScriptRuntime.ToString(thisObj), args)); } case Id_split: { return ScriptRuntime.CheckRegExpProxy(cx).Js_split(cx, scope, ScriptRuntime.ToString(thisObj), args); } case Id_substring: { return Js_substring(cx, ScriptRuntime.ToCharSequence(thisObj), args); } case Id_toLowerCase: { // See ECMA 15.5.4.11 return ScriptRuntime.ToString(thisObj).ToLower(ScriptRuntime.ROOT_LOCALE); } case Id_toUpperCase: { // See ECMA 15.5.4.12 return ScriptRuntime.ToString(thisObj).ToUpper(ScriptRuntime.ROOT_LOCALE); } case Id_substr: { return Js_substr(ScriptRuntime.ToCharSequence(thisObj), args); } case Id_concat: { return Js_concat(ScriptRuntime.ToString(thisObj), args); } case Id_slice: { return Js_slice(ScriptRuntime.ToCharSequence(thisObj), args); } case Id_bold: { return Tagify(thisObj, "b", null, null); } case Id_italics: { return Tagify(thisObj, "i", null, null); } case Id_fixed: { return Tagify(thisObj, "tt", null, null); } case Id_strike: { return Tagify(thisObj, "strike", null, null); } case Id_small: { return Tagify(thisObj, "small", null, null); } case Id_big: { return Tagify(thisObj, "big", null, null); } case Id_blink: { return Tagify(thisObj, "blink", null, null); } case Id_sup: { return Tagify(thisObj, "sup", null, null); } case Id_sub: { return Tagify(thisObj, "sub", null, null); } case Id_fontsize: { return Tagify(thisObj, "font", "size", args); } case Id_fontcolor: { return Tagify(thisObj, "font", "color", args); } case Id_link: { return Tagify(thisObj, "a", "href", args); } case Id_anchor: { return Tagify(thisObj, "a", "name", args); } case Id_equals: case Id_equalsIgnoreCase: { string s1 = ScriptRuntime.ToString(thisObj); string s2 = ScriptRuntime.ToString(args, 0); return ScriptRuntime.WrapBoolean((id == Id_equals) ? s1.Equals(s2) : Sharpen.Runtime.EqualsIgnoreCase(s1, s2)); } case Id_match: case Id_search: case Id_replace: { int actionType; if (id == Id_match) { actionType = RegExpProxyConstants.RA_MATCH; } else { if (id == Id_search) { actionType = RegExpProxyConstants.RA_SEARCH; } else { actionType = RegExpProxyConstants.RA_REPLACE; } } return ScriptRuntime.CheckRegExpProxy(cx).Action(cx, scope, thisObj, args, actionType); } case Id_localeCompare: { // ECMA-262 1 5.5.4.9 // For now, create and configure a collator instance. I can't // actually imagine that this'd be slower than caching them // a la ClassCache, so we aren't trying to outsmart ourselves // with a caching mechanism for now. Collator collator = Collator.GetInstance(cx.GetLocale()); collator.SetStrength(Collator.IDENTICAL); collator.SetDecomposition(Collator.CANONICAL_DECOMPOSITION); return ScriptRuntime.WrapNumber(collator.Compare(ScriptRuntime.ToString(thisObj), ScriptRuntime.ToString(args, 0))); } case Id_toLocaleLowerCase: { return ScriptRuntime.ToString(thisObj).ToLower(cx.GetLocale()); } case Id_toLocaleUpperCase: { return ScriptRuntime.ToString(thisObj).ToUpper(cx.GetLocale()); } case Id_trim: { string str = ScriptRuntime.ToString(thisObj); char[] chars = str.ToCharArray(); int start = 0; while (start < chars.Length && ScriptRuntime.IsJSWhitespaceOrLineTerminator(chars[start])) { start++; } int end = chars.Length; while (end > start && ScriptRuntime.IsJSWhitespaceOrLineTerminator(chars[end - 1])) { end--; } return Sharpen.Runtime.Substring(str, start, end); } } throw new ArgumentException(id.ToString()); again_continue: ; } again_break: ; }