/// <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); }
protected internal virtual void AddIdFunctionProperty(IScriptable obj, object tag, int id, string name, int arity) { IScriptable scope = ScriptableObject.GetTopLevelScope(obj); IdFunctionObject f = NewIdFunction(tag, id, name, arity, scope); f.AddAsProperty(obj); }
private static object JsConstructor(Context cx, IScriptable scope, object [] args) { int arglen = args.Length; System.Text.StringBuilder sourceBuf = new System.Text.StringBuilder(); sourceBuf.Append("function "); /* version != 1.2 Function constructor behavior - * print 'anonymous' as the function name if the * version (under which the function was compiled) is * less than 1.2... or if it's greater than 1.2, because * we need to be closer to ECMA. */ if (cx.Version != Context.Versions.JS1_2) { sourceBuf.Append("anonymous"); } sourceBuf.Append('('); // Append arguments as coma separated strings for (int i = 0; i < arglen - 1; i++) { if (i > 0) { sourceBuf.Append(','); } sourceBuf.Append(ScriptConvert.ToString(args [i])); } sourceBuf.Append(") {"); if (arglen != 0) { // append function body string funBody = ScriptConvert.ToString(args [arglen - 1]); sourceBuf.Append(funBody); } sourceBuf.Append('}'); string source = sourceBuf.ToString(); int [] linep = new int [1]; string filename = Context.GetSourcePositionFromStack(linep); if (filename == null) { filename = "<eval'ed string>"; linep [0] = 1; } string sourceURI = ScriptRuntime.makeUrlForGeneratedScript(false, filename, linep [0]); IScriptable global = ScriptableObject.GetTopLevelScope(scope); ErrorReporter reporter; reporter = DefaultErrorReporter.ForEval(cx.ErrorReporter); // Compile with explicit interpreter instance to force interpreter // mode. return(cx.CompileFunction(global, source, new Interpreter(), reporter, sourceURI, 1, (object)null)); }
public void InitPrototypeMethod(object tag, int id, string name, int arity) { IScriptable scope = ScriptableObject.GetTopLevelScope(this); IdFunctionObject f = NewIdFunction(tag, id, name, arity, scope); prototypeValues.InitValue(id, name, f, DONTENUM); }
internal static object NewWithSpecial(Context cx, IScriptable scope, object [] args) { ScriptRuntime.checkDeprecated(cx, "With"); scope = ScriptableObject.GetTopLevelScope(scope); BuiltinWith thisObj = new BuiltinWith(); thisObj.SetPrototype(args.Length == 0 ? ScriptableObject.getClassPrototype(scope, "Object") : ScriptConvert.ToObject(cx, scope, args [0])); thisObj.ParentScope = scope; return(thisObj); }
/* * 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); }
internal IdFunctionObject createPrecachedConstructor() { if (constructorId != 0) { throw new ApplicationException(); } constructorId = obj.FindPrototypeId("constructor"); if (constructorId == 0) { throw new ApplicationException("No id for constructor property"); } obj.InitPrototypeId(constructorId); if (constructor == null) { throw new ApplicationException(obj.GetType().FullName + ".initPrototypeId() did not " + "initialize id=" + constructorId); } constructor.InitFunction(obj.ClassName, ScriptableObject.GetTopLevelScope(obj)); constructor.MarkAsConstructor(obj); return(constructor); }
/* * Analog of replace_glob() in jsstr.c */ private static void replace_glob(GlobData rdata, Context cx, IScriptable scope, RegExpImpl reImpl, int leftIndex, int leftlen) { int replen; string lambdaStr; if (rdata.lambda != null) { // invoke lambda function with args lastMatch, $1, $2, ... $n, // leftContext.length, whole string. SubString [] parens = reImpl.parens; int parenCount = (parens == null) ? 0 : parens.Length; object [] args = new object [parenCount + 3]; args [0] = reImpl.lastMatch.ToString(); for (int i = 0; i < parenCount; i++) { SubString sub = parens [i]; if (sub != null) { args [i + 1] = sub.ToString(); } else { args [i + 1] = Undefined.Value; } } args [parenCount + 1] = (int)reImpl.leftContext.length; args [parenCount + 2] = rdata.str; // This is a hack to prevent expose of reImpl data to // JS function which can run new regexps modifing // regexp that are used later by the engine. // TODO: redesign is necessary if (reImpl != cx.RegExpProxy) { Context.CodeBug(); } RegExpImpl re2 = new RegExpImpl(); re2.multiline = reImpl.multiline; re2.input = reImpl.input; cx.RegExpProxy = re2; try { IScriptable parent = ScriptableObject.GetTopLevelScope(scope); object result = rdata.lambda.Call(cx, parent, parent, args); lambdaStr = ScriptConvert.ToString(result); } finally { cx.RegExpProxy = reImpl; } replen = lambdaStr.Length; } else { lambdaStr = null; replen = rdata.repstr.Length; if (rdata.dollar >= 0) { int [] skip = new int [1]; int dp = rdata.dollar; do { SubString sub = interpretDollar(cx, reImpl, rdata.repstr, dp, skip); if (sub != null) { replen += sub.length - skip [0]; dp += skip [0]; } else { ++dp; } dp = rdata.repstr.IndexOf((char)'$', dp); }while (dp >= 0); } } int growth = leftlen + replen + reImpl.rightContext.length; System.Text.StringBuilder charBuf = rdata.charBuf; if (charBuf == null) { charBuf = new System.Text.StringBuilder(growth); rdata.charBuf = charBuf; } else { charBuf.EnsureCapacity(rdata.charBuf.Length + growth); } charBuf.Append(reImpl.leftContext.charArray, leftIndex, leftlen); if (rdata.lambda != null) { charBuf.Append(lambdaStr); } else { do_replace(rdata, cx, reImpl); } }
/// <summary> Analog of C match_or_replace.</summary> private static object matchOrReplace(Context cx, IScriptable scope, IScriptable thisObj, object [] args, RegExpImpl reImpl, GlobData data, bool forceFlat) { BuiltinRegExp re; string str = ScriptConvert.ToString(thisObj); data.str = str; IScriptable topScope = ScriptableObject.GetTopLevelScope(scope); if (args.Length == 0) { object compiled = BuiltinRegExp.compileRE("", "", false); re = new BuiltinRegExp(topScope, compiled); } else if (args [0] is BuiltinRegExp) { re = (BuiltinRegExp)args [0]; } else { string src = ScriptConvert.ToString(args [0]); string opt; if (data.optarg < args.Length) { args [0] = src; opt = ScriptConvert.ToString(args [data.optarg]); } else { opt = null; } object compiled = BuiltinRegExp.compileRE(src, opt, forceFlat); re = new BuiltinRegExp(topScope, compiled); } data.regexp = re; data.global = (re.Flags & BuiltinRegExp.JSREG_GLOB) != 0; int [] indexp = new int [] { 0 }; object result = null; if (data.mode == EcmaScript.NET.RegExpActions.Search) { result = re.executeRegExp(cx, scope, reImpl, str, indexp, BuiltinRegExp.TEST); if (result != null && result.Equals(true)) { result = (int)reImpl.leftContext.length; } else { result = -1; } } else if (data.global) { re.lastIndex = 0; for (int count = 0; indexp [0] <= str.Length; count++) { result = re.executeRegExp(cx, scope, reImpl, str, indexp, BuiltinRegExp.TEST); if (result == null || !result.Equals(true)) { break; } if (data.mode == EcmaScript.NET.RegExpActions.Match) { match_glob(data, cx, scope, count, reImpl); } else { if (data.mode != EcmaScript.NET.RegExpActions.Replace) { Context.CodeBug(); } SubString lastMatch = reImpl.lastMatch; int leftIndex = data.leftIndex; int leftlen = lastMatch.index - leftIndex; data.leftIndex = lastMatch.index + lastMatch.length; replace_glob(data, cx, scope, reImpl, leftIndex, leftlen); } if (reImpl.lastMatch.length == 0) { if (indexp [0] == str.Length) { break; } indexp [0]++; } } } else { result = re.executeRegExp(cx, scope, reImpl, str, indexp, ((data.mode == EcmaScript.NET.RegExpActions.Replace) ? BuiltinRegExp.TEST : BuiltinRegExp.MATCH)); } return(result); }