Пример #1
0
        /// <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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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));
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        /*
         * 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);
        }
Пример #7
0
 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);
 }
Пример #8
0
        /*
         * 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);
            }
        }
Пример #9
0
        /// <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);
        }