Ejemplo n.º 1
0
        public override object Construct(ExecutionContext GLOBAL, JSObjectBase args, ExecutionContext x)
        {
            JSObject result = new BoolObject(GLOBAL, (int)JSObject.ToNumber(GLOBAL, args.GetItem(GLOBAL, "length").GetValue(GLOBAL)) > 0 && JSObject.ToBool(GLOBAL, args.GetItem(GLOBAL, "0").GetValue(GLOBAL)));

            result.DefProp(GLOBAL, "constructor", this);
            return(result);
        }
Ejemplo n.º 2
0
            public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
            {
                JSObjectBase thisArgs = a;

                if (mMethodProp.mThisArg)
                {
                    int      i, alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));
                    JSObject newArgs = new JSObject();
                    newArgs.DefProp(GLOBAL, "length", (double)(alen + 1));
                    for (i = alen; i > 0; i--)
                    {
                        newArgs.SetItem(GLOBAL, i.ToString(), a.GetItem(GLOBAL, (i - 1).ToString()));
                    }
                    newArgs.DefProp(GLOBAL, "0", t);
                    thisArgs = newArgs;
                }
                foreach (MethodInfo mi in mMethodProp.mMethodInfo)
                {
                    object[] nargs = SatisfyArgumentList(GLOBAL, isThisArg(mi) ? thisArgs : a, mi.GetParameters());
                    if (nargs != null)
                    {
                        return(ToJS(GLOBAL, mi.Invoke(mi.IsStatic ? null : ToNative(t), nargs)));
                    }
                }
                throw new TypeError("Couldn't match arguments for " + mMethodProp.mOverallName);
            }
Ejemplo n.º 3
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            int alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));

            if (alen == 0)
            {
                return(false);
            }
            return(JSObject.ToBool(GLOBAL, a.GetItem(GLOBAL, "0").GetValue(GLOBAL)));
        }
Ejemplo n.º 4
0
            int IComparer <object> .Compare(object a, object b)
            {
                if (a.Equals(b))
                {
                    return(0);
                }
                JSArray array  = new JSArray(GLOBAL, new object[] { a, b });
                double  number = JSObject.ToNumber(GLOBAL, mSorter.Call(GLOBAL, GLOBAL.currentContext.thisOb, array, GLOBAL.currentContext));

                return((int)number);
            }
Ejemplo n.º 5
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            int alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));

            if (alen == 0)
            {
                return("");
            }
            byte[] bytes = UTF8Encoding.UTF8.GetBytes(a.GetItem(GLOBAL, "0").GetValue(GLOBAL).ToString());
            return(URIFunctionPrivate.Encode(bytes, true));
        }
Ejemplo n.º 6
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            int alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));

            if (alen == 0)
            {
                return("");
            }
            string uri = a.GetItem(GLOBAL, "0").GetValue(GLOBAL).ToString();

            return(URIFunctionPrivate.Decode(uri, URIFunctionPrivate.uriEmptySet));
        }
Ejemplo n.º 7
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            int alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));

            if (alen == 0)
            {
                return(false);
            }
            double val = JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "0").GetValue(GLOBAL));

            return(!double.IsNaN(val) && !double.IsPositiveInfinity(val) && !double.IsNegativeInfinity(val));
        }
Ejemplo n.º 8
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            int alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));

            if (alen == 0)
            {
                return(Double.NaN);
            }
            else
            {
                return((double)(long)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "0").GetValue(GLOBAL)));
            }
        }
Ejemplo n.º 9
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            object result;

            if (JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL)) > 0)
            {
                result = JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "0").GetValue(GLOBAL));
            }
            else
            {
                result = 0.0;
            }
            return(result);
        }
Ejemplo n.º 10
0
        // Punct
        // Mask 1 excludes @*_-.
        // Mask 2 excludes @*_-.
        // Mask 4 excludes @*_-.+/
        // AlphaNumeric, spaces
        // Mask 1 excludes letters and numbers
        // Mask 2 escapes ' ' with +
        // Mask 4 excludes letters and numbers
        // 1 and 4 unexclude ' '
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            int alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));
            int mask = 4;

            if (alen == 0)
            {
                return(JSUndefined.Undefined);
            }
            else if (alen > 1)
            {
                mask = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "1").GetValue(GLOBAL));
            }
            string        instr  = JSObject.ToPrimitive(GLOBAL, a.GetItem(GLOBAL, "0").GetValue(GLOBAL));
            StringBuilder result = new StringBuilder();

            foreach (char ch in instr)
            {
                if (ch == ' ' && mask == 2)
                {
                    result.Append('+');
                }
                else if ((ch == '+' || ch == '/') && (mask & 4) != 0)
                {
                    result.Append(ch);
                }
                else if ((ch == '@' || ch == '*' || ch == '_' || ch == '-' || ch == '.') && mask != 0)
                {
                    result.Append(ch);
                }
                else if (char.IsLetterOrDigit(ch) && mask != 0)
                {
                    result.Append(ch);
                }
                else
                {
                    if (ch >= (char)0x100)
                    {
                        result.Append(string.Format("%u{0:X4}", (int)ch));
                    }
                    else
                    {
                        result.Append(string.Format("%{0:X2}", (int)ch));
                    }
                }
            }
            return(result.ToString());
        }
Ejemplo n.º 11
0
        public override object Construct(ExecutionContext GLOBAL, JSObjectBase args, ExecutionContext x)
        {
            JSObject result;

            if (JSObject.ToNumber(GLOBAL, args.GetItem(GLOBAL, "length").GetValue(GLOBAL)) > 0)
            {
                result = new NumberObject(GLOBAL, JSObject.ToNumber(GLOBAL, args.GetItem(GLOBAL, "0").GetValue(GLOBAL)));
            }
            else
            {
                result = new NumberObject(GLOBAL, 0.0);
            }
            result.DefProp(GLOBAL, "prototype", this.GetItem(GLOBAL, "prototype").GetValue(GLOBAL));
            result.DefProp(GLOBAL, "constructor", this);
            return(result);
        }
Ejemplo n.º 12
0
        public static string join(ExecutionContext GLOBAL, object selfOb, string sep)
        {
            JSObjectBase  self    = (JSObjectBase)selfOb;
            List <string> strings = new List <string>();
            int           idx;

            for (idx = 0; idx < JSObject.ToNumber(GLOBAL, self.GetItem(GLOBAL, "length").GetValue(GLOBAL)); idx++)
            {
                string istr = idx.ToString();
                if (self.HasOwnProperty(istr) && self.GetItem(GLOBAL, istr).GetValue(GLOBAL) != null)
                {
                    strings.Add(JSObject.ToPrimitive(GLOBAL, self.GetItem(GLOBAL, istr).GetValue(GLOBAL)));
                }
                else
                {
                    strings.Add("");
                }
            }
            return(string.Join(sep, strings.ToArray()));
        }
Ejemplo n.º 13
0
        public override object Construct(ExecutionContext GLOBAL, JSObjectBase a, ExecutionContext x)
        {
            JSArray ar   = new JSArray(GLOBAL);
            long    alen = (long)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));

            if (alen == 1 && a.GetItem(GLOBAL, "0").GetValue(GLOBAL) is double)
            {
                ar = new JSArray(GLOBAL, (long)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "0").GetValue(GLOBAL)));
            }
            else
            {
                long i;
                for (i = 0; i < alen; i++)
                {
                    ar.push(a.GetItem(GLOBAL, i.ToString()).GetValue(GLOBAL));
                }
            }
            ar.DefProp(GLOBAL, "prototype", mPrototype, false);
            ar.DefProp(GLOBAL, "constructor", this);
            return(ar);
        }
Ejemplo n.º 14
0
        internal object Add(object res1, object res2)
        {
            object v;

            if (res1 is string || res2 is string)
            {
                string s1 = res1 != null?JSObject.ToPrimitive(GLOBAL, res1) : "";

                string s2 = res2 != null?JSObject.ToPrimitive(GLOBAL, res2) : "";

                v = s1 + s2;
            }
            else if (res1 is double || res2 is double || res1 is bool || res2 is bool)
            {
                v = (double)(JSObject.ToNumber(GLOBAL, res1) + JSObject.ToNumber(GLOBAL, res2));
            }
            else
            {
                v = JSObject.ToPrimitive(GLOBAL, res1) + JSObject.ToPrimitive(GLOBAL, res2);
            }
            return(v);
        }
Ejemplo n.º 15
0
        internal object apply(bool callMe, JSObjectBase f, object t, JSObjectBase args, ExecutionContext x)
        {
            // Curse ECMA again!
            if (t == JSUndefined.Undefined || t == null)
            {
                t = x;
            }

            if (!(t is JSObjectBase))
            {
                t = JSObject.ToObject(GLOBAL, t);
            }

            if (args == JSUndefined.Undefined || args == null)
            {
                args = new JSObject();
                args.SetItem(GLOBAL, "length", new JSSimpleProperty("length", 0.0, false, false, true));
            }
            else if (args is JSArray)
            {
                var vv = new JSObject();
                int ii, jj;
                for (ii = 0, jj = (int)JSObject.ToNumber(GLOBAL, args.GetItem(GLOBAL, "length").GetValue(GLOBAL)); ii < jj; ii++)
                {
                    vv.SetItem(GLOBAL, ii.ToString(), new JSSimpleProperty(ii.ToString(), args.GetItem(GLOBAL, ii.ToString()).GetValue(GLOBAL), false, false, true));
                }
                vv.SetItem(GLOBAL, "length", new JSSimpleProperty("length", (double)ii, false, false, true));
                args = vv;
            }

            if (callMe)
            {
                return(f.Call(GLOBAL, t, args, x));
            }
            else
            {
                return(f.Construct(GLOBAL, args, x));
            }
        }
Ejemplo n.º 16
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            if (!a.HasProperty(GLOBAL, "length"))
            {
                return(JSUndefined.Undefined);
            }
            int alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));

            if (alen < 1)
            {
                return(JSUndefined.Undefined);
            }

            object s = a.GetItem(GLOBAL, "0").GetValue(GLOBAL);

            if (!(s is string))
            {
                return(s);
            }
            //string str = (string)s;

            ExecutionContext x2 = new ExecutionContext(CodeType.EVAL_CODE);

            x2.thisOb             = x.thisOb;
            x2.caller             = x.caller;
            x2.callee             = x.callee;
            x2.scope              = x.scope;
            GLOBAL.currentContext = x2;
            try {
                jsexec JSExec = (jsexec)GLOBAL.jobject.GetItem(GLOBAL, "JSExec").GetValue(GLOBAL);
                JSExec.execute(jsparse.parse(GLOBAL, s.ToString(), null, 0), x2);
            } catch (ThrownException) {
                x.result = x2.result;
                throw;
            } finally {
                GLOBAL.currentContext = x;
            }
            return(x2.result);
        }
Ejemplo n.º 17
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            JSObject result;
            int      i, alen = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));
            string   fundef = "function anonymous(";
            string   comma  = "";

            for (i = 0; i < alen - 1; i++)
            {
                string arg = a.GetItem(GLOBAL, i.ToString()).GetValue(GLOBAL).ToString();
                if (!argRe.IsMatch(arg))
                {
                    throw new SyntaxError("Malformed parameter in function", null, 0);
                }
                fundef += comma + arg;
                comma   = ",";
            }
            fundef += ") { " + (alen > 0 ? a.GetItem(GLOBAL, i.ToString()).GetValue(GLOBAL).ToString() : "") + " }";
            Node n = jsparse.parse(GLOBAL, fundef, null, 0);

            result = new FunctionObject(GLOBAL, n, x);
            DefProp(GLOBAL, "length", (double)n.fparams.Count, false, false, false);
            return(result);
        }
Ejemplo n.º 18
0
        public override object Call(ExecutionContext GLOBAL, object t, JSObjectBase a, ExecutionContext x)
        {
            int           alen   = (int)JSObject.ToNumber(GLOBAL, a.GetItem(GLOBAL, "length").GetValue(GLOBAL));
            StringBuilder result = new StringBuilder();
            Match         escChar;

            if (alen == 0)
            {
                return(JSUndefined.Undefined);
            }
            string instr    = JSObject.ToPrimitive(GLOBAL, a.GetItem(GLOBAL, "0").GetValue(GLOBAL));
            int    startAt  = 0;
            int    lastUsed = 0;

            while (startAt < instr.Length && (escChar = escapedChar.Match(instr, startAt)).Success)
            {
                startAt = escChar.Index;
                result.Append(instr.Substring(lastUsed, startAt - lastUsed));
                if (escChar.Groups[0].Value[1] == 'u')
                {
                    startAt += 6;
                    result.Append((char)int.Parse(escChar.Groups[0].Value.Substring(2), NumberStyles.HexNumber));
                }
                else
                {
                    startAt += 3;
                    result.Append((char)int.Parse(escChar.Groups[0].Value.Substring(1), NumberStyles.HexNumber));
                }
                lastUsed = startAt;
            }
            if (lastUsed < instr.Length)
            {
                result.Append(instr.Substring(lastUsed));
            }
            return(result.ToString());
        }
Ejemplo n.º 19
0
        internal object execute(Node n, ExecutionContext x)
        {
            int              i, j;
            List <Node>      aNode;
            ExecutionContext sEcon;
            JSObjectBase     jaa;
            JSObjectBase     f, tVal;
            object           r, s, u = null, v = null;
            Node             tNode = null, rNode = null, uNode = null;
            bool             matchDefault = false;
            bool             switchLoop;

            if (TraceExec)
            {
                UnityEngine.Debug.Log("Execute[" + n.ToString() + " => ");
            }

            try
            {
                switch (n.type)
                {
                case TokenType.Function:
                    if (n.functionForm != StatementForm.DECLARED_FORM)
                    {
                        if (n.name == null || n.name == "" || n.functionForm == StatementForm.STATEMENT_FORM)
                        {
                            v = new FunctionObject(GLOBAL, n, x.scope);
                            if (n.functionForm == StatementForm.STATEMENT_FORM)
                            {
                                x.scope.jobject.SetItem(GLOBAL, n.name, new JSSimpleProperty(n.name, v));
                            }
                        }
                        else
                        {
                            tVal = new JSObject();
                            ExecutionContext tmp = x.scope;
                            x.scope         = new ExecutionContext();
                            x.scope.jobject = tVal;
                            x.scope.parent  = tmp;
                            try
                            {
                                v = new FunctionObject(GLOBAL, n, x.scope);
                                tVal.SetItem(GLOBAL, n.name, new JSSimpleProperty(n.name, v, true, true));
                            }
                            finally
                            {
                                x.scope = x.scope.parent;
                            }
                        }
                    }
                    break;

                case TokenType.SCRIPT:
                    tVal  = x.scope.jobject;
                    aNode = n.funDecls;
                    for (i = 0, j = aNode.Count; i < j; i++)
                    {
                        s = aNode[i].name;
                        f = new FunctionObject(GLOBAL, aNode[i], x.scope);
                        tVal.SetItem(GLOBAL, s.ToString(), new JSSimpleProperty(s.ToString(), f, x.type != CodeType.EVAL_CODE));
                    }
                    aNode = n.varDecls;
                    for (i = 0, j = aNode.Count; i < j; i++)
                    {
                        uNode = aNode[i];
                        s     = uNode.name;
                        if (uNode.readOnly && tVal.HasOwnProperty(s.ToString()))
                        {
                            throw new TypeError
                                      ("Redeclaration of const " + s, uNode.filename, uNode.lineno);
                        }
                        if (uNode.readOnly || !tVal.HasOwnProperty(s.ToString()))
                        {
                            tVal.SetItem(GLOBAL, s.ToString(), new JSSimpleProperty(s.ToString(), JSUndefined.Undefined, x.type != CodeType.EVAL_CODE, uNode.readOnly));
                        }
                    }
                    // FALL THROUGH
                    for (i = 0, j = n.Count; i < j; i++)
                    {
                        execute(n[i], x);
                    }
                    break;

                case TokenType.BLOCK:
                    for (i = 0, j = n.Count; i < j; i++)
                    {
                        execute(n[i], x);
                    }
                    break;

                case TokenType.If:
                    if (JSObject.ToBool(GLOBAL, execute(n.condition, x)))
                    {
                        execute(n.thenPart, x);
                    }
                    else if (n.elsePart != null)
                    {
                        execute(n.elsePart, x);
                    }
                    break;

                case TokenType.Switch:
                    s     = Reference.GetValue(GLOBAL, execute(n.discriminant, x));
                    aNode = n.cases;
                    Node tt;
                    switchLoop = false;
                    for (i = 0, j = aNode.Count; ; i++)
                    {
                        if (i == j)
                        {
                            if (n.defaultIndex >= 0)
                            {
                                i            = n.defaultIndex - 1; // no case matched, do default
                                matchDefault = true;
                                continue;
                            }
                            break;                          // no default, exit switch_loop
                        }
                        tt = aNode[i];                      // next case (might be default!)
                        if (tt.type == TokenType.Case)
                        {
                            u = Reference.GetValue(GLOBAL, execute(tt.caseLabel, x));
                        }
                        else
                        {
                            if (!matchDefault)              // not defaulting, skip for now
                            {
                                continue;
                            }
                            u = s;                          // force match to do default
                        }
                        if (object.Equals(u, s))
                        {
                            for (; ;)
                            {                      // this loop exits switch_loop
                                if (tt.statements != null)
                                {
                                    try
                                    {
                                        execute(tt.statements, x);
                                    }
                                    catch (BreakException)
                                    {
                                        if (x.target == n)
                                        {
                                            switchLoop = true;
                                            break;
                                        }
                                        else
                                        {
                                            throw;
                                        }
                                    }
                                }
                                if (++i == j)
                                {
                                    switchLoop = true;
                                    break;
                                }
                                tNode = aNode[i];
                            }
                            // NOT REACHED
                        }
                        if (switchLoop)
                        {
                            break;
                        }
                    }
                    break;

                case TokenType.For:
                    if (n.setup != null)
                    {
                        Reference.GetValue(GLOBAL, execute(n.setup, x));
                    }
                    // FALL THROUGH
                    while (n.condition == null ||
                           JSObject.ToBool(GLOBAL, Reference.GetValue(GLOBAL, execute(n.condition, x))))
                    {
                        try
                        {
                            execute(n.body, x);
                        }
                        catch (BreakException)
                        {
                            if (x.target == n)
                            {
                                break;
                            }
                            throw;
                        }
                        catch (ContinueException)
                        {
                            if (x.target == n)
                            {
                                if (n.update != null)
                                {
                                    Reference.GetValue(GLOBAL, execute(n.update, x));
                                }
                                if (n.condition != null && !JSObject.ToBool(GLOBAL, Reference.GetValue(GLOBAL, execute(n.condition, x))))
                                {
                                    break;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            throw;
                        }
                        if (n.update != null)
                        {
                            Reference.GetValue(GLOBAL, execute(n.update, x));
                        }
                    }
                    break;

                case TokenType.While:
                    while (n.condition == null ||
                           JSObject.ToBool(GLOBAL, Reference.GetValue(GLOBAL, execute(n.condition, x))))
                    {
                        try
                        {
                            execute(n.body, x);
                        }
                        catch (BreakException)
                        {
                            if (x.target == n)
                            {
                                break;
                            }
                            throw;
                        }
                        catch (ContinueException)
                        {
                            if (x.target == n)
                            {
                                continue;
                            }
                            throw;
                        }
                        if (n.update != null)
                        {
                            Reference.GetValue(GLOBAL, execute(n.update, x));
                        }
                    }
                    break;

                case TokenType.FOR_IN:
                    uNode = n.varDecl;
                    if (uNode != null)
                    {
                        execute(uNode, x);
                    }
                    rNode = n.iterator;
                    v     = Reference.GetValue(GLOBAL, execute(n.jobject, x));

                    // ECMA deviation to track extant browser JS implementation behavior.
                    tVal = JSObject.ToObject(GLOBAL, v);
                    i    = 0;
                    jaa  = new JSArray(GLOBAL);
                    foreach (string ii in tVal.Properties)
                    {
                        string istr = (i++).ToString();
                        jaa.SetItem(GLOBAL, istr, new JSSimpleProperty(istr, ii));
                    }
                    for (j = i, i = 0; i < j; i++)
                    {
                        Reference.PutValue(GLOBAL, execute(rNode, x), jaa.GetItem(GLOBAL, i.ToString()).GetValue(GLOBAL));
                        try
                        {
                            execute(n.body, x);
                        }
                        catch (BreakException)
                        {
                            if (x.target == n)
                            {
                                break;
                            }
                            throw;
                        }
                        catch (ContinueException)
                        {
                            if (x.target == n)
                            {
                                continue;
                            }
                            throw;
                        }
                    }
                    break;

                case TokenType.Do:
                    do
                    {
                        try
                        {
                            execute(n.body, x);
                        }
                        catch (BreakException)
                        {
                            if (x.target != n)
                            {
                                break;
                            }
                            throw;
                        }
                        catch (ContinueException)
                        {
                            if (x.target != n)
                            {
                                continue;
                            }
                            throw;
                        }
                    } while (JSObject.ToBool(GLOBAL, Reference.GetValue(GLOBAL, execute(n.condition, x))));
                    break;

                case TokenType.Break:
                    x.target = n.target;
                    throw new BreakException();

                case TokenType.Continue:
                    x.target = ((Node)n).target;
                    throw new ContinueException();

                case TokenType.Try:
                    try
                    {
                        execute(n.tryBlock, x);
                    }
                    catch (Exception exn)
                    {
                        ThrownException ex = exn as ThrownException;
                        object          e;
                        if (ex != null)
                        {
                            e = ex.Value;
                        }
                        else
                        {
                            e = new JSInstanceWrapper(GLOBAL, exn);
                        }
                        j        = n.catchClauses.Count;
                        x.result = JSUndefined.Undefined;
                        for (i = 0; ; i++)
                        {
                            if (i == j)
                            {
                                throw;
                            }
                            tNode = n.catchClauses[i];
                            ExecutionContext xscope = new ExecutionContext();
                            xscope.jobject = new JSObject();
                            xscope.jobject.SetItem(GLOBAL, tNode.varName, new JSSimpleProperty(tNode.varName, e, false, false, true));
                            xscope.parent = x.scope;
                            x.scope       = xscope;
                            try
                            {
                                if (tNode.guard != null && !JSObject.ToBool(GLOBAL, Reference.GetValue(GLOBAL, execute(tNode.guard, x))))
                                {
                                    continue;
                                }
                                execute(tNode.block, x);
                                break;
                            }
                            finally
                            {
                                x.scope = x.scope.parent;
                            }
                        }
                    }
                    finally
                    {
                        if (n.finallyBlock != null)
                        {
                            execute(n.finallyBlock, x);
                        }
                    }
                    break;

                case TokenType.Throw:
                    x.result = Reference.GetValue(GLOBAL, execute(n.exception, x));
                    throw new ThrownException((double)(int)TokenType.Throw);

                case TokenType.Return:
                    x.result = n.valueNode == null ? JSUndefined.Undefined : Reference.GetValue(GLOBAL, execute(n.valueNode, x));
                    throw new ReturnException();

                case TokenType.With:
                {
                    r    = execute(n.jobject, x);
                    tVal = JSObject.ToObject(GLOBAL, Reference.GetValue(GLOBAL, r));
                    ExecutionContext tmp = x.scope;
                    x.scope         = new ExecutionContext();
                    x.scope.jobject = tVal;
                    x.scope.parent  = tmp;
                    try
                    {
                        execute(n.body, x);
                    }
                    finally
                    {
                        x.scope = x.scope.parent;
                    }
                }
                break;

                case TokenType.Var:
                case TokenType.Const:
                    for (i = 0, j = n.Count; i < j; i++)
                    {
                        uNode = n[i].initializer;
                        if (uNode == null)
                        {
                            continue;
                        }
                        string identName = n[i].name;
                        for (sEcon = x.scope; sEcon != null; sEcon = sEcon.parent)
                        {
                            if (sEcon.jobject.HasOwnProperty(identName))
                            {
                                break;
                            }
                        }
                        u = Reference.GetValue(GLOBAL, execute(uNode, x));
                        if (n.type == TokenType.Const)
                        {
                            sEcon.jobject.SetItem(GLOBAL, identName, new JSSimpleProperty(identName, u, true, true, false));
                        }
                        else
                        {
                            sEcon.jobject.SetItem(GLOBAL, identName, new JSSimpleProperty(identName, u));
                        }
                    }
                    break;

                case TokenType.Debugger:
                    throw new Exception("NYI: debugger");

                case TokenType.SEMICOLON:
                    if (n.expression != null)
                    {
                        x.result = Reference.GetValue(GLOBAL, execute(n.expression, x));
                    }
                    break;

                case TokenType.LABEL:
                    try
                    {
                        execute(n.statement, x);
                    }
                    catch (BreakException)
                    {
                        if (x.target != n)
                        {
                            throw;
                        }
                    }
                    break;

                case TokenType.COMMA:
                    for (i = 0, j = n.Count; i < j; i++)
                    {
                        v = Reference.GetValue(GLOBAL, execute(n[i], x));
                    }
                    break;

                case TokenType.ASSIGN:
                    r = execute(n[0], x);
                    TokenType tok = jsdefs.tokenWords[n.value.ToString()];
                    v = Reference.GetValue(GLOBAL, execute(n[1], x));
                    if (tok != TokenType.ASSIGN)
                    {
                        u = Reference.GetValue(GLOBAL, r);
                        if (tok != TokenType.PLUS)
                        {
                            double ld = JSObject.ToNumber(GLOBAL, u), bd = JSObject.ToNumber(GLOBAL, v);
                            long   laa = (long)ld, bb = (long)bd;
                            int    bint = (int)bb;
                            switch (tok)
                            {
                            case TokenType.BITWISE_OR: ld = laa | bb; break;

                            case TokenType.BITWISE_XOR: ld = laa ^ bb; break;

                            case TokenType.BITWISE_AND: ld = laa & bb; break;

                            case TokenType.LSH: ld = laa << bint; break;

                            case TokenType.RSH: ld = laa >> bint; break;

                            case TokenType.URSH: ld = ((uint)laa) >> bint; break;

                            case TokenType.MINUS: ld = ld - bd; break;

                            case TokenType.MUL: ld = ld * bd; break;

                            case TokenType.DIV: ld = ld / bd; break;

                            case TokenType.MOD: ld = laa % bb; break;
                            }
                            v = ld;
                        }
                        else
                        {
                            v = Add(u, v);
                        }
                    }
                    Reference.PutValue(GLOBAL, r, v);
                    break;

                case TokenType.HOOK:
                {
                    object res1 = Reference.GetValue(GLOBAL, execute(n[0], x));
                    v = JSObject.ToBool(GLOBAL, res1) ? Reference.GetValue(GLOBAL, execute(n[1], x))
                                                       : Reference.GetValue(GLOBAL, execute(n[2], x));
                }
                break;

                case TokenType.OR:
                {
                    object res1 = Reference.GetValue(GLOBAL, execute(n[0], x));
                    v = JSObject.ToBool(GLOBAL, res1) ? res1 : Reference.GetValue(GLOBAL, execute(n[1], x));
                }
                break;

                case TokenType.AND:
                {
                    object res1 = Reference.GetValue(GLOBAL, execute(n[0], x));
                    v = JSObject.ToBool(GLOBAL, res1) ? Reference.GetValue(GLOBAL, execute(n[1], x)) : res1;
                }
                break;

                case TokenType.BITWISE_OR:
                    v = (double)((int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) | (int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x))));
                    break;

                case TokenType.BITWISE_XOR:
                    v = (double)((int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) ^ (int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x))));
                    break;

                case TokenType.BITWISE_AND:
                    v = (double)((int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) & (int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x))));
                    break;

                case TokenType.EQ:
                    v = Reference.GetValue(GLOBAL, execute(n[0], x));
                    u = Reference.GetValue(GLOBAL, execute(n[1], x));
                    if ((v == null || v == JSUndefined.Undefined) && (u == null || u == JSUndefined.Undefined))
                    {
                        v = true;
                    }
                    else
                    {
                        v = JSObject.CompareTo(GLOBAL, v, u) == 0;
                    }
                    break;

                case TokenType.NE:
                    if (((u == null || u is JSUndefined) && (v != null && !(v is JSUndefined))) ||
                        ((v == null || v is JSUndefined) && (u != null && !(u is JSUndefined))))
                    {
                        return(true);
                    }

                    v = JSObject.CompareTo(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x))) != 0;
                    break;

                case TokenType.STRICT_EQ:
                    v = Object.Equals(Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x)));
                    break;

                case TokenType.STRICT_NE:
                    v = !Object.Equals(Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x)));
                    break;

                case TokenType.LT:
                    v = JSObject.CompareTo(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x))) == -1;
                    break;

                case TokenType.LE:
                    v = JSObject.CompareTo(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x))) != 1;
                    break;

                case TokenType.GE:
                    v = JSObject.CompareTo(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x))) != -1;
                    break;

                case TokenType.GT:
                    v = JSObject.CompareTo(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x))) == 1;
                    break;

                case TokenType.In:
                    v    = execute(n[1], x);
                    tVal = Reference.GetValue(GLOBAL, v) as JSObjectBase;
                    if (tVal == null)
                    {
                        throw new TypeError("invalid 'in' operand " + v.ToString());
                    }
                    v = tVal.HasProperty(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x)).ToString());
                    break;

                case TokenType.Instanceof:
                    u    = Reference.GetValue(GLOBAL, execute(n[0], x));
                    tVal = Reference.GetValue(GLOBAL, execute(n[1], x)) as JSObjectBase;
                    if (tVal == null)
                    {
                        throw new TypeError("Not an object in instanceof");
                    }
                    v = tVal.HasInstance(GLOBAL, u);
                    break;

                case TokenType.LSH:
                    v = (double)((int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) << (int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x))));
                    break;

                case TokenType.RSH:
                    v = (double)((int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) >> (int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x))));
                    break;

                case TokenType.URSH:
                    v = (double)((int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) >> (int)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x))));
                    break;

                case TokenType.PLUS:
                    v = Add(Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x)));
                    break;

                case TokenType.MINUS:
                    v = JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) - JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x)));
                    break;

                case TokenType.MUL:
                    v = JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) * JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x)));
                    break;

                case TokenType.DIV:
                    v = JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) / JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x)));
                    break;

                case TokenType.MOD:
                    v = JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[0], x))) % (long)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute(n[1], x)));
                    break;

                case TokenType.Delete:
                {
                    u = execute((Node)n[0], x);
                    Reference refer = u as Reference;
                    if (refer != null)
                    {
                        v = refer.GetBase().Delete(refer.GetPropertyName());
                    }
                }
                break;

                case TokenType.Void:
                    Reference.GetValue(GLOBAL, execute((Node)n[0], x));
                    v = JSUndefined.Undefined;
                    break;

                case TokenType.Typeof:
                    u = execute((Node)n[0], x);
                    if (u is Reference)
                    {
                        Reference refer = (Reference)u;
                        if (refer.GetBase() == null)
                        {
                            v = JSUndefined.Undefined;
                            break;
                        }
                        u = Reference.GetValue(GLOBAL, refer);
                    }
                    v = JSObject.Typeof(u).ToLower();
                    break;

                case TokenType.NOT:
                    v = !JSObject.ToBool(GLOBAL, Reference.GetValue(GLOBAL, execute((Node)n[0], x)));
                    break;

                case TokenType.BITWISE_NOT:
                    v = (double)~(long)JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute((Node)n[0], x)));
                    break;

                case TokenType.UNARY_PLUS:
                    v = JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute((Node)n[0], x)));
                    break;

                case TokenType.UNARY_MINUS:
                    v = -JSObject.ToNumber(GLOBAL, Reference.GetValue(GLOBAL, execute((Node)n[0], x)));
                    break;

                case TokenType.INCREMENT:
                case TokenType.DECREMENT:
                {
                    object t = execute(n[0], x);
                    u = Reference.GetValue(GLOBAL, t);
                    if (n.postfix)
                    {
                        v = u;
                    }
                    Reference.PutValue(GLOBAL, t, n.type == TokenType.INCREMENT ? JSObject.ToNumber(GLOBAL, u) + 1 : JSObject.ToNumber(GLOBAL, u) - 1);
                    if (!n.postfix)
                    {
                        v = u;
                    }
                }
                break;

                case TokenType.DOT:
                {
                    r = execute((Node)n[0], x);
                    object t = Reference.GetValue(GLOBAL, r);
                    u = n[1].value;
                    v = new Reference(JSObject.ToObject(GLOBAL, t), u.ToString());
                }
                break;

                case TokenType.INDEX:
                {
                    r = execute(n[0], x);
                    object t = Reference.GetValue(GLOBAL, r);
                    u = Reference.GetValue(GLOBAL, execute(n[1], x));
                    v = new Reference(JSObject.ToObject(GLOBAL, t), u.ToString());
                }
                break;

                case TokenType.LIST:
                    // Curse ECMA for specifying that arguments is not an Array object!
                    tVal = new JSObject();
                    int k = 0;
                    CollectArguments(tVal, n, ref k, x);
                    tVal.SetItem(GLOBAL, "length", new JSSimpleProperty("length", (double)k));
                    v = tVal;
                    break;

                case TokenType.CALL:
                {
                    r = execute(n[0], x);
                    JSObjectBase args = (JSObjectBase)execute(n[1], x);
                    object       o    = Reference.GetValue(GLOBAL, r);
                    if (Object.ReferenceEquals(o, JSUndefined.Undefined))
                    {
                        throw new TypeError("Can't call undefined " + n[0].ToString() + " " + r);
                    }
                    JSObjectBase fun = (JSObjectBase)o;
                    tVal = (r is Reference) ? ((Reference)r).GetBase() : null;
                    if (tVal is Activation)
                    {
                        tVal = null;
                    }
                    try
                    {
                        v = apply(true, fun, tVal, args, x);
                    }
                    catch (TypeError te)
                    {
                        if (r is Reference)
                        {
                            throw new TypeError(((Reference)r).GetPropertyName() + ": " + te.Message);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                break;

                case TokenType.New:
                case TokenType.NEW_WITH_ARGS:
                {
                    r = execute(n[0], x);
                    JSObjectBase fun = (JSObjectBase)Reference.GetValue(GLOBAL, r);
                    if (n.type == TokenType.New)
                    {
                        jaa = new JSArray(GLOBAL);
                    }
                    else
                    {
                        jaa = (JSObjectBase)execute(n[1], x);
                    }
                    v = fun.Construct(GLOBAL, jaa, x);
                }
                break;

                case TokenType.ARRAY_INIT:
                    JSArray jaa1 = new JSArray(GLOBAL);
                    for (i = 0, j = n.Count; i < j; i++)
                    {
                        if (n[i] != null)
                        {
                            jaa1[i] = new JSSimpleProperty(i.ToString(), Reference.GetValue(GLOBAL, execute(n[i], x)));
                        }
                    }
                    jaa1.length = j;
                    v           = jaa1;
                    break;

                case TokenType.OBJECT_INIT:
                    tVal = new JSObject();
                    for (i = 0, j = n.Count; i < j; i++)
                    {
                        Node tx = n[i];
                        if (tx.type == TokenType.PROPERTY_INIT)
                        {
                            tVal.SetItem(GLOBAL, tx[0].value.ToString(),
                                         new JSSimpleProperty
                                             (tx[0].value.ToString(),
                                             Reference.GetValue(GLOBAL, execute(tx[1], x))));
                        }
                        else
                        {
                            f = new FunctionObject(GLOBAL, tx, x.scope);
                            string           tname = tx.name;
                            JSSimpleProperty prop;
                            if (!tx.fields.TryGetValue(tname, out prop))
                            {
                                tx.fields[tname] = new JSSimpleProperty(tname, v);
                            }
                            if (tx.type == TokenType.GETTER)
                            {
                                prop.DefineGetter(new Thunk(tVal, f, x));
                            }
                            else
                            {
                                prop.DefineSetter(new Thunk(tVal, f, x));
                            }
                            tVal.SetItem(GLOBAL, tname, prop);
                        }
                    }
                    v = tVal;
                    break;

                case TokenType.Null:
                    v = null;
                    break;

                case TokenType.This:
                    v = x.thisOb;
                    break;

                case TokenType.True:
                    v = true;
                    break;

                case TokenType.False:
                    v = false;
                    break;

                case TokenType.IDENTIFIER:
                {
                    for (sEcon = x.scope; sEcon != null; sEcon = sEcon.parent)
                    {
                        if (sEcon.jobject != null && sEcon.jobject.HasProperty(GLOBAL, n.value.ToString()))
                        {
                            break;
                        }
                    }
                    v = new Reference(sEcon != null ? sEcon.jobject : GLOBAL.jobject, n.value.ToString());
                }
                break;

                case TokenType.NUMBER:
                case TokenType.STRING:
                case TokenType.REGEXP:
                    v = n.value;
                    break;

                case TokenType.GROUP:
                    v = execute(n[0], x);
                    break;

                default:
                    throw new TypeError("PANIC: unknown operation " + n.type.ToString() + ": " + n.ToString());
                }
            }
            catch (FalseReturn) { v = false; }
            catch (ContinueException) { throw; }
            catch (BreakException) { throw; }
            catch (ThrownException) { throw; }
            catch (ReturnException) { throw; }
            catch (Exception e)
            {
                throw new ScriptException(e.Message, n, e);
            }
            if (TraceExec)
            {
                UnityEngine.Debug.Log(v == null ? "(null)" : v.ToString() + " ]");
            }

            return(v);
        }
Ejemplo n.º 20
0
        public TokenType get()
        {
            Token token;

            while (this.lookahead != 0)
            {
                --this.lookahead;
                this.tokenIndex = (this.tokenIndex + 1) & 3;
                token           = this.tokens[this.tokenIndex];
                if (token.type != TokenType.NEWLINE || this.scanNewlines)
                {
                    return(token.type);
                }
            }

            string capInput;
            Match  capMatch;

            for (;;)
            {
                capInput = this.input;
                capMatch = (this.scanNewlines ? snRegExp : nnRegExp).Match(capInput);
                if (capMatch.Success)
                {
                    string spaces = capMatch.Value;
                    this.cursor += spaces.Length;
                    Match nlMatch = elRegExp.Match(spaces);
                    if (nlMatch.Value != "")
                    {
                        this.lineno += nlMatch.Length;
                    }
                    capInput = this.input;
                }

                if (!(capMatch = cmRegExp.Match(capInput)).Success)
                {
                    break;
                }
                string comment = capMatch.Value;
                this.cursor += comment.Length;
                string newlines = elRegExp.Match(comment).Value;
                if (newlines != "")
                {
                    this.lineno += newlines.Length;
                }
            }

            this.tokenIndex = (this.tokenIndex + 1) & 3;
            if (!this.tokens.TryGetValue(this.tokenIndex, out token))
            {
                token = null;
            }

            if (token == null)
            {
                token = new Token();
                this.tokens[this.tokenIndex] = token;
            }

            if (capInput == "")
            {
                return(token.type = TokenType.END);
            }

            if ((capMatch = fpRegExp.Match(capInput)).Success)
            {
                token.type  = TokenType.NUMBER;
                token.value = JSObject.ToNumber(GLOBAL, capMatch.Groups[0].Value);
            }
            else if ((capMatch = hxRegExp.Match(capInput)).Success)
            {
                token.type  = TokenType.NUMBER;
                token.value = JSObject.ToNumber(GLOBAL, capMatch.Groups[0].Value);
            }
            else if ((capMatch = idRegExp.Match(capInput)).Success) // FIXME no ES3 unicode
            {
                string id = capMatch.Groups[0].Value;
                if (!jsdefs.keywords.TryGetValue(id, out token.type))
                {
                    token.type = TokenType.IDENTIFIER;
                }
                token.value = id;
            }
            else if ((capMatch = qtRegExp.Match(capInput)).Success) //"){
            {
                char matchCh = capMatch.Groups[0].Value[0];
                int  matched;
                token.type  = TokenType.STRING;
                token.value = JSObject.StringLiteral(capInput, out matched);
                capMatch    = new Regex("^" + matchCh + ".{" + matched.ToString() + "}" + matchCh).Match(capInput);
            }
            else if (this.scanOperand && (capMatch = reRegExp.Match(capInput)).Success)
            {
                token.type  = TokenType.REGEXP;
                token.value = new Regex(capMatch.Groups[1].Value); //, capMatch.Groups[2].Value);
            }
            else if ((capMatch = opRegExp.Match(capInput)).Success)
            {
                string op = capMatch.Groups[0].Value;
                if (jsdefs.assignOps.ContainsKey(op) && capInput[op.Length] == '=')
                {
                    token.type     = TokenType.ASSIGN;
                    token.assignOp = jsdefs.assignOps[op];
                    capMatch       = dtRegExp.Match(op + "=");
                }
                else
                {
                    token.type = jsdefs.tokenWords[op];
                    if (this.scanOperand &&
                        (token.type == TokenType.PLUS))
                    {
                        token.type = TokenType.UNARY_PLUS;
                    }
                    if (this.scanOperand &&
                        (token.type == TokenType.MINUS))
                    {
                        token.type = TokenType.UNARY_MINUS;
                    }
                    token.assignOp = TokenType.NULL;
                }
                token.value = op;
            }
            else if (this.scanNewlines && (capMatch = (elRegExp.Match(capInput))).Success)
            {
                token.type = TokenType.NEWLINE;
            }
            else
            {
                throw this.newSyntaxError("Illegal token");
            }

            token.start  = this.cursor;
            this.cursor += capMatch.Groups[0].Value.Length;
            token.end    = this.cursor;
            token.lineno = this.lineno;
            return(token.type);
        }