Exemple #1
0
        // TODO: Find a *much* nicer way of dealing with this. :X
        public ReferenceListItem(Reference reference, Display display, Resource context)
        {
            this.Reference = reference;

            string displayStr;

            switch (display)
            {
                case Display.NoMod:
                    displayStr = reference.ToString(false, context);
                    break;
                case Display.WithMod:
                    displayStr = reference.ToString(true, context);
                    break;
                case Display.SourcedNoMod:
                    displayStr = reference.ToStringSourced(false, context);
                    break;
                case Display.SourcedIncoming:
                    displayStr = "[INCOMING] " + reference.ToStringSourced(false, context);
                    break;
                default:
                    throw new ArgumentException("display");
            }

            this.AddText(displayStr);

            SetBackground(reference.Valid ? ItemStatus.Okay : ItemStatus.Error);

            this.CommandBindings.Add(new System.Windows.Input.CommandBinding(
                System.Windows.Input.ApplicationCommands.Copy,
                (o, e) => System.Windows.Clipboard.SetText(string.Concat(reference.Origin.Location, " : ", reference.Target.Location))
                ));

            this.ContextMenu = new ContextMenu();

            var items = this.ContextMenu.Items;

            items.Add(new MenuItem { Header = "_Copy...", Command = System.Windows.Input.ApplicationCommands.Copy, CommandTarget = this });

            items.Add(CreateItem(Reference.Definition, "_Definition: "));
            // Add the origin unless it's the same
            if (Reference.Definition != reference.Origin)
                items.Add(CreateItem(Reference.Origin, "_Origin: "));
            // Add the definition *unless* it's either.
            if (Reference.Definition != Reference.Target && Reference.Origin != Reference.Target)
                items.Add(CreateItem(Reference.Target, "_Target: "));
        }
Exemple #2
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;
        }