Beispiel #1
0
 public FunctionObject(ExecutionContext GLOBAL, Node node, ExecutionContext scope)
 {
     this.node = node;
     if (this.node.type == TokenType.SCRIPT)
         this.node = this.node[0];
     this.scope = scope;
     this.SetItem(GLOBAL, "length", new JSSimpleProperty("length", (double)node.fparams.Count, true, true, true));
     JSObject prototype = new JSObject();
     this.SetItem(GLOBAL, "prototype", new JSSimpleProperty("prototype", prototype, true));
     prototype.SetItem(GLOBAL, "toString", new JSNativeMethod(typeof(JSObject), "ToString"));
     prototype.SetItem(GLOBAL, "valueOf", new JSNativeMethod(typeof(JSObject), "ToPrimitive"));
     this.SetItem(GLOBAL, "constructor", new JSSimpleProperty("constructor", this, false, false, true));
 }
Beispiel #2
0
 public static void SetupPrototype(ExecutionContext GLOBAL, JSObject Prototype)
 {
     Prototype.SetItem(GLOBAL, "getDate", new JSNativeMethod(typeof(JSDate), "getDate"));
     Prototype.SetItem(GLOBAL, "getDay", new JSNativeMethod(typeof(JSDate), "getDay"));
     Prototype.SetItem(GLOBAL, "getFullYear", new JSNativeMethod(typeof(JSDate), "getFullYear"));
     Prototype.SetItem(GLOBAL, "getHours", new JSNativeMethod(typeof(JSDate), "getHours"));
     Prototype.SetItem(GLOBAL, "getMilliseconds", new JSNativeMethod(typeof(JSDate), "getMilliseconds"));
     Prototype.SetItem(GLOBAL, "getMinutes", new JSNativeMethod(typeof(JSDate), "getMinutes"));
     Prototype.SetItem(GLOBAL, "getMonth", new JSNativeMethod(typeof(JSDate), "getMonth"));
     Prototype.SetItem(GLOBAL, "getSeconds", new JSNativeMethod(typeof(JSDate), "getSeconds"));
     Prototype.SetItem(GLOBAL, "getTime", new JSNativeMethod(typeof(JSDate), "getTime"));
     Prototype.SetItem(GLOBAL, "getTimezoneOffset", new JSNativeMethod(typeof(JSDate), "getTimezoneOffset"));
     Prototype.SetItem(GLOBAL, "getUTCDate", new JSNativeMethod(typeof(JSDate), "getUTCDate"));
     Prototype.SetItem(GLOBAL, "getUTCDay", new JSNativeMethod(typeof(JSDate), "getUTCDay"));
     Prototype.SetItem(GLOBAL, "getUTCMonth", new JSNativeMethod(typeof(JSDate), "getUTCMonth"));
     Prototype.SetItem(GLOBAL, "getUTCFullYear", new JSNativeMethod(typeof(JSDate), "getUTCFullYear"));
     Prototype.SetItem(GLOBAL, "getUTCHours", new JSNativeMethod(typeof(JSDate), "getUTCHours"));
     Prototype.SetItem(GLOBAL, "getUTCMinutes", new JSNativeMethod(typeof(JSDate), "getUTCMinutes"));
     Prototype.SetItem(GLOBAL, "getUTCSeconds", new JSNativeMethod(typeof(JSDate), "getUTCSeconds"));
     Prototype.SetItem(GLOBAL, "getUTCMilliseconds", new JSNativeMethod(typeof(JSDate), "getUTCMilliseconds"));
     Prototype.SetItem(GLOBAL, "getYear", new JSNativeMethod(typeof(JSDate), "getYear"));
     Prototype.SetItem(GLOBAL, "parse", new JSNativeMethod(typeof(JSDate), "parse"));
     Prototype.SetItem(GLOBAL, "setDate", new JSNativeMethod(typeof(JSDate), "setDate"));
     Prototype.SetItem(GLOBAL, "setFullYear", new JSNativeMethod(typeof(JSDate), "setFullYear"));
     Prototype.SetItem(GLOBAL, "setHours", new JSNativeMethod(typeof(JSDate), "setHours"));
     Prototype.SetItem(GLOBAL, "setMilliseconds", new JSNativeMethod(typeof(JSDate), "setMilliseconds"));
     Prototype.SetItem(GLOBAL, "setMinutes", new JSNativeMethod(typeof(JSDate), "setMinutes"));
     Prototype.SetItem(GLOBAL, "setMonth", new JSNativeMethod(typeof(JSDate), "setMonth"));
     Prototype.SetItem(GLOBAL, "setSeconds", new JSNativeMethod(typeof(JSDate), "setSeconds"));
     Prototype.SetItem(GLOBAL, "setTime", new JSNativeMethod(typeof(JSDate), "setTime"));
     Prototype.SetItem(GLOBAL, "setUTCDate", new JSNativeMethod(typeof(JSDate), "setUTCDate"));
     Prototype.SetItem(GLOBAL, "setUTCMonth", new JSNativeMethod(typeof(JSDate), "setUTCMonth"));
     Prototype.SetItem(GLOBAL, "setUTCFullYear", new JSNativeMethod(typeof(JSDate), "setUTCFullYear"));
     Prototype.SetItem(GLOBAL, "setUTCHours", new JSNativeMethod(typeof(JSDate), "setUTCHours"));
     Prototype.SetItem(GLOBAL, "setUTCMinutes", new JSNativeMethod(typeof(JSDate), "setUTCMinutes"));
     Prototype.SetItem(GLOBAL, "setUTCSeconds", new JSNativeMethod(typeof(JSDate), "setUTCSeconds"));
     Prototype.SetItem(GLOBAL, "setUTCMilliseconds", new JSNativeMethod(typeof(JSDate), "setUTCMilliseconds"));
     Prototype.SetItem(GLOBAL, "setYear", new JSNativeMethod(typeof(JSDate), "setYear"));
     Prototype.SetItem(GLOBAL, "toDateString", new JSNativeMethod(typeof(JSDate), "toDateString"));
     Prototype.SetItem(GLOBAL, "toGMTString", new JSNativeMethod(typeof(JSDate), "toGMTString"));
     Prototype.SetItem(GLOBAL, "toLocaleDateString", new JSNativeMethod(typeof(JSDate), "toLocaleDateString"));
     Prototype.SetItem(GLOBAL, "toLocaleTimeString", new JSNativeMethod(typeof(JSDate), "toLocaleTimeString"));
     Prototype.SetItem(GLOBAL, "toLocaleString", new JSNativeMethod(typeof(JSDate), "toLocaleString"));
     //toSource() 	Represents the source code of an object 	1 	-
     Prototype.SetItem(GLOBAL, "toString", new JSNativeMethod(typeof(JSDate), "ToString"));
     Prototype.SetItem(GLOBAL, "toTimeString", new JSNativeMethod(typeof(JSDate), "toTimeString"));
     Prototype.SetItem(GLOBAL, "toUTCString", new JSNativeMethod(typeof(JSDate), "toUTCString"));
     Prototype.SetItem(GLOBAL, "UTC", new JSNativeMethod(typeof(JSDate), "UTC"));
     Prototype.SetItem(GLOBAL, "valueOf", new JSNativeMethod(typeof(JSDate), "getTime"));
 }
Beispiel #3
0
 public static JSObjectBase RegisterNamespace(ExecutionContext GLOBAL, JSObjectBase scope, string[] names, int idx)
 {
     JSObjectBase parent = idx == 0 ? scope : RegisterNamespace(GLOBAL, scope, names, idx - 1);
     if (!parent.HasProperty(GLOBAL, names[idx]))
     {
         JSObject wrapper = new JSObject();
         parent.GetItem(GLOBAL, names[idx]).SetValue(GLOBAL, wrapper);
         return wrapper;
     }
     return (JSObjectBase)parent.GetItem(GLOBAL, names[idx]).GetValue(GLOBAL);
 }
Beispiel #4
0
        public override object Construct(ExecutionContext GLOBAL, JSObjectBase a, ExecutionContext x)
        {
            JSObjectBase o = new JSObject();
            object p = this.GetItem(GLOBAL, "prototype").GetValue(GLOBAL);

            if (!(p == null || p is JSUndefined || p is double || p is string || p is bool))
                o.SetItem(GLOBAL, "prototype", new JSSimpleProperty("prototype", p, false, false, true));

            object v = Call(GLOBAL, o, a, x);
            if (v == null || v is JSUndefined || v is double || v is string || v is bool)
                return o;
            else
                return v;
        }
Beispiel #5
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)
                System.Console.Write("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 = 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 = 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.ReferenceEquals(Reference.GetValue(GLOBAL, execute(n[0], x)), Reference.GetValue(GLOBAL, execute(n[1], x)));
                        break;

                    case TokenType.STRICT_NE:
                        v = !Object.ReferenceEquals(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);
                            JSObjectBase fun = (JSObjectBase)Reference.GetValue(GLOBAL, r);
                            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)
                System.Console.WriteLine(v == null ? "(null)" : v.ToString() + " ]");

            return v;
        }
Beispiel #6
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);
        }
Beispiel #7
0
        public jsexec()
        {
            GLOBAL.jobject = new JSObject();
            GLOBAL.jobject = GLOBAL.thisOb = new JSObject();

            StaticObjectFun = new ObjectFun(GLOBAL);
            GLOBAL.jobject.SetItem(GLOBAL, "StaticObjectFun", new JSSimpleProperty("StaticObjectFun", StaticObjectFun));
            StaticStringFun = new StringFun(GLOBAL);
            GLOBAL.jobject.SetItem(GLOBAL, "StaticStringFun", new JSSimpleProperty("StaticStringFun", StaticStringFun));
            StaticBooleanFun = new BooleanFun(GLOBAL);
            GLOBAL.jobject.SetItem(GLOBAL, "StaticBooleanFun", new JSSimpleProperty("StaticBooleanFun", StaticBooleanFun));
            StaticArrayFun = new ArrayFun(GLOBAL);
            GLOBAL.jobject.SetItem(GLOBAL, "StaticArrayFun", new JSSimpleProperty("StaticArrayFun", StaticArrayFun));
            StaticNumberFun = new NumberFun(GLOBAL);
            GLOBAL.jobject.SetItem(GLOBAL, "StaticNumberFun", new JSSimpleProperty("StaticNumberFun", StaticNumberFun));
            StaticFunctionFun = new FunctionFun(GLOBAL);
            GLOBAL.jobject.SetItem(GLOBAL, "StaticFunctionFun", new JSSimpleProperty("StaticFunctionFun", StaticFunctionFun));
            StaticNumberObject = new NumberObject(GLOBAL, 0.0);
            DatePrototype = new JSDate(GLOBAL);
            GLOBAL.jobject.SetItem(GLOBAL, "DatePrototype", new JSSimpleProperty("DatePrototype", DatePrototype));
            JSDate.SetupPrototype(GLOBAL, DatePrototype);

            GLOBAL.jobject.SetItem(GLOBAL, "toString", new JSNativeMethod(typeof(JSObject), "StaticToString"));

            /* Core types */
            JSObject thisOb = (JSObject)GLOBAL.thisOb;
            thisOb.DefProp(GLOBAL, "Object", StaticObjectFun);
            thisOb.DefProp(GLOBAL, "Function", StaticFunctionFun);
            thisOb.DefProp(GLOBAL, "Boolean", StaticBooleanFun);
            thisOb.DefProp(GLOBAL, "Number", StaticNumberFun);
            thisOb.DefProp(GLOBAL, "String", StaticStringFun);
            thisOb.DefProp(GLOBAL, "Array", StaticArrayFun);

            /* Types that work like classes */
            thisOb.DefProp(GLOBAL, "Math", JSClassWrapper.RegisterClass(GLOBAL, typeof(pygmalion.JSMath)));
            thisOb.DefProp(GLOBAL, "Date", JSClassWrapper.RegisterClass(GLOBAL, typeof(pygmalion.JSDate)));

            /* Standard library */
            thisOb.DefProp(GLOBAL, "decodeURI", new DecodeURIFun());
            thisOb.DefProp(GLOBAL, "decodeURIComponent", new DecodeURIComponentFun());
            thisOb.DefProp(GLOBAL, "encodeURI", new EncodeURIFun());
            thisOb.DefProp(GLOBAL, "encodeURIComponent", new EncodeURIComponentFun());
            thisOb.DefProp(GLOBAL, "escape", new EscapeFun());
            thisOb.DefProp(GLOBAL, "eval", new EvalFun());
            thisOb.DefProp(GLOBAL, "gc", new GcFun());
            thisOb.DefProp(GLOBAL, "Infinity", double.PositiveInfinity, false, false, false);
            thisOb.DefProp(GLOBAL, "isFinite", new isFiniteFun());
            thisOb.SetItem(GLOBAL, "isNaN", new JSNativeMethod(typeof(Double), "IsNaN"));
            thisOb.DefProp(GLOBAL, "parseFloat", new ParseFloat(), false, false, false);
            thisOb.DefProp(GLOBAL, "parseInt", new ParseInt(), false, false, false);
            thisOb.DefProp(GLOBAL, "NaN", double.NaN, false, false, false);
            thisOb.DefProp(GLOBAL, "unescape", new UnescapeFun());
            thisOb.DefProp(GLOBAL, "version", new VersionFun());

            GLOBAL.jobject.SetItem(GLOBAL, "JSExec", new JSSimpleProperty("JSExec", this));
            GLOBAL.thisOb = GLOBAL.jobject;
            GLOBAL.currentContext = new ExecutionContext(GLOBAL);
            GLOBAL.scope = GLOBAL.currentContext;
        }
Beispiel #8
0
 public override object Construct(ExecutionContext GLOBAL, JSObjectBase args, ExecutionContext x)
 {
     JSObject result;
     int alen = (int)JSObject.ToNumber(GLOBAL, args.GetItem(GLOBAL, "length").GetValue(GLOBAL));
     if (alen > 0) result = (JSObject)JSObject.ToObject(GLOBAL, args.GetItem(GLOBAL, "0").GetValue(GLOBAL));
     else result = new JSObject();
     result.DefProp(GLOBAL, "prototype", mPrototype);
     result.DefProp(GLOBAL, "constructor", this);
     return result;
 }
Beispiel #9
0
 public ObjectFun(ExecutionContext GLOBAL)
 {
     mPrototype = new JSObject();
     mPrototype.SetItem(GLOBAL, "toString", new JSNativeMethod(typeof(JSObject), "StaticToString"));
     mPrototype.SetItem(GLOBAL, "valueOf", new JSNativeMethod(typeof(JSObject), "ToPrimitive"));
     DefProp(GLOBAL, "prototype", mPrototype, false, false, false, false);
 }