~ubuntu-branches/ubuntu/karmic/phppgadmin/karmic

« back to all changes in this revision

Viewing changes to selenium/scripts/narcissus-exec.js

  • Committer: Bazaar Package Importer
  • Author(s): Peter Eisentraut
  • Date: 2008-12-31 19:32:22 UTC
  • mfrom: (1.3.1 upstream) (8.1.2 sid)
  • mto: (8.1.4 sid)
  • mto: This revision was merged to the branch mainline in revision 17.
  • Revision ID: james.westby@ubuntu.com-20081231193222-swr5hb1fie1enl4l
* New upstream release
  - Fixes local file inclusion vulnerability (CVE-2008-5587) (closes: #508026)
* Removed register_globals from debian/apache.conf (closes: #508026)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ***** BEGIN LICENSE BLOCK *****
2
 
 * vim: set ts=4 sw=4 et tw=80:
3
 
 *
4
 
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
 
 *
6
 
 * The contents of this file are subject to the Mozilla Public License Version
7
 
 * 1.1 (the "License"); you may not use this file except in compliance with
8
 
 * the License. You may obtain a copy of the License at
9
 
 * http://www.mozilla.org/MPL/
10
 
 *
11
 
 * Software distributed under the License is distributed on an "AS IS" basis,
12
 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 
 * for the specific language governing rights and limitations under the
14
 
 * License.
15
 
 *
16
 
 * The Original Code is the Narcissus JavaScript engine.
17
 
 *
18
 
 * The Initial Developer of the Original Code is
19
 
 * Brendan Eich <brendan@mozilla.org>.
20
 
 * Portions created by the Initial Developer are Copyright (C) 2004
21
 
 * the Initial Developer. All Rights Reserved.
22
 
 *
23
 
 * Contributor(s):
24
 
 *
25
 
 * Alternatively, the contents of this file may be used under the terms of
26
 
 * either the GNU General Public License Version 2 or later (the "GPL"), or
27
 
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
 
 * in which case the provisions of the GPL or the LGPL are applicable instead
29
 
 * of those above. If you wish to allow use of your version of this file only
30
 
 * under the terms of either the GPL or the LGPL, and not to allow others to
31
 
 * use your version of this file under the terms of the MPL, indicate your
32
 
 * decision by deleting the provisions above and replace them with the notice
33
 
 * and other provisions required by the GPL or the LGPL. If you do not delete
34
 
 * the provisions above, a recipient may use your version of this file under
35
 
 * the terms of any one of the MPL, the GPL or the LGPL.
36
 
 *
37
 
 * ***** END LICENSE BLOCK ***** */
38
 
 
39
 
/*
40
 
 * Narcissus - JS implemented in JS.
41
 
 *
42
 
 * Execution of parse trees.
43
 
 *
44
 
 * Standard classes except for eval, Function, Array, and String are borrowed
45
 
 * from the host JS environment.  Function is metacircular.  Array and String
46
 
 * are reflected via wrapping the corresponding native constructor and adding
47
 
 * an extra level of prototype-based delegation.
48
 
 */
49
 
 
50
 
// jrh
51
 
//module('JS.Exec');
52
 
// end jrh
53
 
 
54
 
GLOBAL_CODE = 0; EVAL_CODE = 1; FUNCTION_CODE = 2;
55
 
 
56
 
function ExecutionContext(type) {
57
 
    this.type = type;
58
 
}
59
 
 
60
 
// jrh
61
 
var agenda = new Array();
62
 
var skip_setup = 0;
63
 
// end jrh
64
 
 
65
 
var global = {
66
 
    // Value properties.
67
 
    NaN: NaN, Infinity: Infinity, undefined: undefined,
68
 
    alert : function(msg) { alert(msg) },
69
 
    confirm : function(msg) { return confirm(msg) },
70
 
    document : document,
71
 
    window : window,
72
 
    // jrh
73
 
    //debug: window.open('','debugwindow','width=600,height=400,scrollbars=yes,resizable=yes'),     
74
 
    // end jrh
75
 
    navigator : navigator,
76
 
    XMLHttpRequest : function() { return new XMLHttpRequest() },
77
 
    // Function properties.
78
 
    eval: function(s) {
79
 
        if (typeof s != "string") {
80
 
            return s;
81
 
        }
82
 
 
83
 
        var x = ExecutionContext.current;
84
 
        var x2 = new ExecutionContext(EVAL_CODE);
85
 
        x2.thisObject = x.thisObject;
86
 
        x2.caller = x.caller;
87
 
        x2.callee = x.callee;
88
 
        x2.scope = x.scope;
89
 
        ExecutionContext.current = x2;
90
 
        try {
91
 
            execute(parse(s), x2);
92
 
        } catch (e) {
93
 
            x.result = x2.result;
94
 
            throw e;
95
 
        } finally {
96
 
            ExecutionContext.current = x;
97
 
        }
98
 
        return x2.result;
99
 
    },
100
 
    parseInt: parseInt, parseFloat: parseFloat,
101
 
    isNaN: isNaN, isFinite: isFinite,
102
 
    decodeURI: decodeURI, encodeURI: encodeURI,
103
 
    decodeURIComponent: decodeURIComponent,
104
 
    encodeURIComponent: encodeURIComponent,
105
 
 
106
 
    // Class constructors.  Where ECMA-262 requires C.length == 1, we declare
107
 
    // a dummy formal parameter.
108
 
    Object: Object,
109
 
    Function: function(dummy) {
110
 
        var p = "", b = "", n = arguments.length;
111
 
        if (n) {
112
 
            var m = n - 1;
113
 
            if (m) {
114
 
                p += arguments[0];
115
 
                for (var k = 1; k < m; k++)
116
 
                    p += "," + arguments[k];
117
 
            }
118
 
            b += arguments[m];
119
 
        }
120
 
 
121
 
        // XXX We want to pass a good file and line to the tokenizer.
122
 
        // Note the anonymous name to maintain parity with Spidermonkey.
123
 
        var t = new Tokenizer("anonymous(" + p + ") {" + b + "}");
124
 
 
125
 
        // NB: Use the STATEMENT_FORM constant since we don't want to push this
126
 
        // function onto the null compilation context.
127
 
        var f = FunctionDefinition(t, null, false, STATEMENT_FORM);
128
 
        var s = {object: global, parent: null};
129
 
        return new FunctionObject(f, s);
130
 
    },
131
 
    Array: function(dummy) {
132
 
        // Array when called as a function acts as a constructor.
133
 
        return GLOBAL.Array.apply(this, arguments);
134
 
    },
135
 
    String: function(s) {
136
 
        // Called as function or constructor: convert argument to string type.
137
 
        s = arguments.length ? "" + s : "";
138
 
        if (this instanceof String) {
139
 
            // Called as constructor: save the argument as the string value
140
 
            // of this String object and return this object.
141
 
            this.value = s;
142
 
            return this;
143
 
        }
144
 
        return s;
145
 
    },
146
 
    Boolean: Boolean, Number: Number, Date: Date, RegExp: RegExp,
147
 
    Error: Error, EvalError: EvalError, RangeError: RangeError,
148
 
    ReferenceError: ReferenceError, SyntaxError: SyntaxError,
149
 
    TypeError: TypeError, URIError: URIError,
150
 
 
151
 
    // Other properties.
152
 
    Math: Math,
153
 
 
154
 
    // Extensions to ECMA.
155
 
    //snarf: snarf,
156
 
    evaluate: evaluate,
157
 
    load: function(s) {
158
 
        if (typeof s != "string")
159
 
            return s;
160
 
        var req = new XMLHttpRequest();
161
 
        req.open('GET', s, false);
162
 
        req.send(null);
163
 
 
164
 
        evaluate(req.responseText, s, 1)
165
 
    },
166
 
    print: print, version: null
167
 
};
168
 
 
169
 
// jrh
170
 
//global.debug.document.body.innerHTML = ''
171
 
// end jrh
172
 
 
173
 
// Helper to avoid Object.prototype.hasOwnProperty polluting scope objects.
174
 
function hasDirectProperty(o, p) {
175
 
    return Object.prototype.hasOwnProperty.call(o, p);
176
 
}
177
 
 
178
 
// Reflect a host class into the target global environment by delegation.
179
 
function reflectClass(name, proto) {
180
 
    var gctor = global[name];
181
 
    gctor.prototype = proto;
182
 
    proto.constructor = gctor;
183
 
    return proto;
184
 
}
185
 
 
186
 
// Reflect Array -- note that all Array methods are generic.
187
 
reflectClass('Array', new Array);
188
 
 
189
 
// Reflect String, overriding non-generic methods.
190
 
var gSp = reflectClass('String', new String);
191
 
gSp.toSource = function () { return this.value.toSource(); };
192
 
gSp.toString = function () { return this.value; };
193
 
gSp.valueOf  = function () { return this.value; };
194
 
global.String.fromCharCode = String.fromCharCode;
195
 
 
196
 
var XCp = ExecutionContext.prototype;
197
 
ExecutionContext.current = XCp.caller = XCp.callee = null;
198
 
XCp.scope = {object: global, parent: null};
199
 
XCp.thisObject = global;
200
 
XCp.result = undefined;
201
 
XCp.target = null;
202
 
XCp.ecmaStrictMode = false;
203
 
 
204
 
function Reference(base, propertyName, node) {
205
 
    this.base = base;
206
 
    this.propertyName = propertyName;
207
 
    this.node = node;
208
 
}
209
 
 
210
 
Reference.prototype.toString = function () { return this.node.getSource(); }
211
 
 
212
 
function getValue(v) {
213
 
    if (v instanceof Reference) {
214
 
        if (!v.base) {
215
 
            throw new ReferenceError(v.propertyName + " is not defined",
216
 
                                     v.node.filename(), v.node.lineno);
217
 
        }
218
 
        return v.base[v.propertyName];
219
 
    }
220
 
    return v;
221
 
}
222
 
 
223
 
function putValue(v, w, vn) {
224
 
    if (v instanceof Reference)
225
 
        return (v.base || global)[v.propertyName] = w;
226
 
    throw new ReferenceError("Invalid assignment left-hand side",
227
 
                             vn.filename(), vn.lineno);
228
 
}
229
 
 
230
 
function isPrimitive(v) {
231
 
    var t = typeof v;
232
 
    return (t == "object") ? v === null : t != "function";
233
 
}
234
 
 
235
 
function isObject(v) {
236
 
    var t = typeof v;
237
 
    return (t == "object") ? v !== null : t == "function";
238
 
}
239
 
 
240
 
// If r instanceof Reference, v == getValue(r); else v === r.  If passed, rn
241
 
// is the node whose execute result was r.
242
 
function toObject(v, r, rn) {
243
 
    switch (typeof v) {
244
 
      case "boolean":
245
 
        return new global.Boolean(v);
246
 
      case "number":
247
 
        return new global.Number(v);
248
 
      case "string":
249
 
        return new global.String(v);
250
 
      case "function":
251
 
        return v;
252
 
      case "object":
253
 
        if (v !== null)
254
 
            return v;
255
 
    }
256
 
    var message = r + " (type " + (typeof v) + ") has no properties";
257
 
    throw rn ? new TypeError(message, rn.filename(), rn.lineno)
258
 
             : new TypeError(message);
259
 
}
260
 
 
261
 
function execute(n, x) {
262
 
    if (!this.new_block)
263
 
        new_block = new Array();
264
 
    //alert (n)
265
 
    var a, f, i, j, r, s, t, u, v;
266
 
    switch (n.type) {
267
 
      case FUNCTION:
268
 
        if (n.functionForm != DECLARED_FORM) {
269
 
            if (!n.name || n.functionForm == STATEMENT_FORM) {
270
 
                v = new FunctionObject(n, x.scope);
271
 
                if (n.functionForm == STATEMENT_FORM)
272
 
                    x.scope.object[n.name] = v;
273
 
            } else {
274
 
                t = new Object;
275
 
                x.scope = {object: t, parent: x.scope};
276
 
                try {
277
 
                    v = new FunctionObject(n, x.scope);
278
 
                    t[n.name] = v;
279
 
                } finally {
280
 
                    x.scope = x.scope.parent;
281
 
                }
282
 
            }
283
 
        }
284
 
        break;
285
 
 
286
 
      case SCRIPT:      
287
 
        t = x.scope.object;
288
 
        a = n.funDecls;
289
 
        for (i = 0, j = a.length; i < j; i++) {
290
 
            s = a[i].name;
291
 
            f = new FunctionObject(a[i], x.scope);
292
 
            t[s] = f;
293
 
        }
294
 
        a = n.varDecls;
295
 
        for (i = 0, j = a.length; i < j; i++) {
296
 
            u = a[i];
297
 
            s = u.name;
298
 
            if (u.readOnly && hasDirectProperty(t, s)) {
299
 
                throw new TypeError("Redeclaration of const " + s,
300
 
                                    u.filename(), u.lineno);
301
 
            }
302
 
            if (u.readOnly || !hasDirectProperty(t, s)) {
303
 
                t[s] = null;
304
 
            }
305
 
        }
306
 
        // FALL THROUGH
307
 
 
308
 
      case BLOCK:        
309
 
        for (i = 0, j = n.$length; i < j; i++)  {  
310
 
            //jrh
311
 
            //execute(n[i], x);      
312
 
            //new_block.unshift([n[i], x]);            
313
 
            new_block.push([n[i], x]);         
314
 
        }
315
 
        new_block.reverse();        
316
 
        agenda = agenda.concat(new_block);   
317
 
        //agenda = new_block.concat(agenda)
318
 
        // end jrh
319
 
        break;
320
 
 
321
 
      case IF:
322
 
        if (getValue(execute(n.condition, x)))
323
 
            execute(n.thenPart, x);
324
 
        else if (n.elsePart)
325
 
            execute(n.elsePart, x);
326
 
        break;
327
 
 
328
 
      case SWITCH:
329
 
        s = getValue(execute(n.discriminant, x));
330
 
        a = n.cases;
331
 
        var matchDefault = false;
332
 
      switch_loop:
333
 
        for (i = 0, j = a.length; ; i++) {
334
 
            if (i == j) {
335
 
                if (n.defaultIndex >= 0) {
336
 
                    i = n.defaultIndex - 1; // no case matched, do default
337
 
                    matchDefault = true;
338
 
                    continue;
339
 
                }
340
 
                break;                      // no default, exit switch_loop
341
 
            }
342
 
            t = a[i];                       // next case (might be default!)
343
 
            if (t.type == CASE) {
344
 
                u = getValue(execute(t.caseLabel, x));
345
 
            } else {
346
 
                if (!matchDefault)          // not defaulting, skip for now
347
 
                    continue;
348
 
                u = s;                      // force match to do default
349
 
            }
350
 
            if (u === s) {
351
 
                for (;;) {                  // this loop exits switch_loop
352
 
                    if (t.statements.length) {
353
 
                        try {
354
 
                            execute(t.statements, x);
355
 
                        } catch (e) {
356
 
                            if (!(e == BREAK && x.target == n)) { throw e }
357
 
                            break switch_loop;
358
 
                        }
359
 
                    }
360
 
                    if (++i == j)
361
 
                        break switch_loop;
362
 
                    t = a[i];
363
 
                }
364
 
                // NOT REACHED
365
 
            }
366
 
        }
367
 
        break;
368
 
 
369
 
      case FOR:
370
 
        // jrh
371
 
        // added "skip_setup" so initialization doesn't get called
372
 
        // on every call..
373
 
        if (!skip_setup)
374
 
            n.setup && getValue(execute(n.setup, x));
375
 
        // FALL THROUGH
376
 
      case WHILE:
377
 
        // jrh       
378
 
        //while (!n.condition || getValue(execute(n.condition, x))) {
379
 
        if (!n.condition || getValue(execute(n.condition, x))) {
380
 
            try {
381
 
                // jrh 
382
 
                //execute(n.body, x);
383
 
                new_block.push([n.body, x]);
384
 
                agenda.push([n.body, x])
385
 
                //agenda.unshift([n.body, x])
386
 
                // end jrh
387
 
            } catch (e) {
388
 
                if (e == BREAK && x.target == n) {
389
 
                    break;
390
 
                } else if (e == CONTINUE && x.target == n) {
391
 
                    // jrh
392
 
                    // 'continue' is invalid inside an 'if' clause
393
 
                    // I don't know what commenting this out will break!
394
 
                    //continue;
395
 
                    // end jrh
396
 
                    
397
 
                } else {
398
 
                    throw e;
399
 
                }
400
 
            }    
401
 
            n.update && getValue(execute(n.update, x));
402
 
            // jrh
403
 
            new_block.unshift([n, x])
404
 
            agenda.splice(agenda.length-1,0,[n, x])
405
 
            //agenda.splice(1,0,[n, x])
406
 
            skip_setup = 1
407
 
            // end jrh
408
 
        } else {
409
 
            skip_setup = 0
410
 
        }
411
 
        
412
 
        break;
413
 
 
414
 
      case FOR_IN:
415
 
        u = n.varDecl;
416
 
        if (u)
417
 
            execute(u, x);
418
 
        r = n.iterator;
419
 
        s = execute(n.object, x);
420
 
        v = getValue(s);
421
 
 
422
 
        // ECMA deviation to track extant browser JS implementation behavior.
423
 
        t = (v == null && !x.ecmaStrictMode) ? v : toObject(v, s, n.object);
424
 
        a = [];
425
 
        for (i in t)
426
 
            a.push(i);
427
 
        for (i = 0, j = a.length; i < j; i++) {
428
 
            putValue(execute(r, x), a[i], r);
429
 
            try {
430
 
                execute(n.body, x);
431
 
            } catch (e) {
432
 
                if (e == BREAK && x.target == n) {
433
 
                    break;
434
 
                } else if (e == CONTINUE && x.target == n) {
435
 
                    continue;
436
 
                } else {
437
 
                    throw e;
438
 
                }
439
 
            }
440
 
        }
441
 
        break;
442
 
 
443
 
      case DO:
444
 
        do {
445
 
            try {
446
 
                execute(n.body, x);
447
 
            } catch (e) {
448
 
                if (e == BREAK && x.target == n) {
449
 
                    break;
450
 
                } else if (e == CONTINUE && x.target == n) {
451
 
                    continue;
452
 
                } else {
453
 
                    throw e;
454
 
                }
455
 
            }
456
 
        } while (getValue(execute(n.condition, x)));
457
 
        break;
458
 
 
459
 
      case BREAK:
460
 
      case CONTINUE:
461
 
        x.target = n.target;
462
 
        throw n.type;
463
 
 
464
 
      case TRY:
465
 
        try {
466
 
            execute(n.tryBlock, x);
467
 
        } catch (e) {
468
 
            if (!(e == THROW && (j = n.catchClauses.length))) {
469
 
                throw e;
470
 
            }
471
 
            e = x.result;
472
 
            x.result = undefined;
473
 
            for (i = 0; ; i++) {
474
 
                if (i == j) {
475
 
                    x.result = e;
476
 
                    throw THROW;
477
 
                }
478
 
                t = n.catchClauses[i];
479
 
                x.scope = {object: {}, parent: x.scope};
480
 
                x.scope.object[t.varName] = e;
481
 
                try {
482
 
                    if (t.guard && !getValue(execute(t.guard, x)))
483
 
                        continue;
484
 
                    execute(t.block, x);
485
 
                    break;
486
 
                } finally {
487
 
                    x.scope = x.scope.parent;
488
 
                }
489
 
            }
490
 
        } finally {
491
 
            if (n.finallyBlock)
492
 
                execute(n.finallyBlock, x);
493
 
        }
494
 
        break;
495
 
 
496
 
      case THROW:
497
 
        x.result = getValue(execute(n.exception, x));
498
 
        throw THROW;
499
 
 
500
 
      case RETURN:
501
 
        x.result = getValue(execute(n.value, x));
502
 
        throw RETURN;
503
 
 
504
 
      case WITH:
505
 
        r = execute(n.object, x);
506
 
        t = toObject(getValue(r), r, n.object);
507
 
        x.scope = {object: t, parent: x.scope};
508
 
        try {
509
 
            execute(n.body, x);
510
 
        } finally {
511
 
            x.scope = x.scope.parent;
512
 
        }
513
 
        break;
514
 
 
515
 
      case VAR:
516
 
      case CONST:
517
 
        for (i = 0, j = n.$length; i < j; i++) {
518
 
            u = n[i].initializer;
519
 
            if (!u)
520
 
                continue;
521
 
            t = n[i].name;
522
 
            for (s = x.scope; s; s = s.parent) {
523
 
                if (hasDirectProperty(s.object, t))
524
 
                    break;
525
 
            }
526
 
            u = getValue(execute(u, x));
527
 
            if (n.type == CONST)
528
 
                s.object[t] = u;
529
 
            else
530
 
                s.object[t] = u;
531
 
        }
532
 
        break;
533
 
 
534
 
      case DEBUGGER:
535
 
        throw "NYI: " + tokens[n.type];
536
 
 
537
 
      case REQUIRE:
538
 
        var req = new XMLHttpRequest();
539
 
        req.open('GET', n.filename, 'false');
540
 
 
541
 
      case SEMICOLON:
542
 
        if (n.expression)
543
 
            // print debugging statements
544
 
                     
545
 
            var the_start = n.start
546
 
            var the_end = n.end
547
 
            var the_statement = parse_result.tokenizer.source.slice(the_start,the_end)
548
 
            //global.debug.document.body.innerHTML += ('<pre>&gt;&gt;&gt; <b>' + the_statement + '</b></pre>')
549
 
            LOG.info('>>>' + the_statement)
550
 
            x.result = getValue(execute(n.expression, x));   
551
 
            //if (x.result)
552
 
            //global.debug.document.body.innerHTML += ( '<pre>&gt;&gt;&gt; ' + x.result + '</pre>')
553
 
            
554
 
        break;
555
 
 
556
 
      case LABEL:
557
 
        try {
558
 
            execute(n.statement, x);
559
 
        } catch (e) {
560
 
            if (!(e == BREAK && x.target == n)) { throw e }
561
 
        }
562
 
        break;
563
 
 
564
 
      case COMMA:
565
 
        for (i = 0, j = n.$length; i < j; i++)
566
 
            v = getValue(execute(n[i], x));
567
 
        break;
568
 
 
569
 
      case ASSIGN:
570
 
        r = execute(n[0], x);
571
 
        t = n[0].assignOp;
572
 
        if (t)
573
 
            u = getValue(r);
574
 
        v = getValue(execute(n[1], x));
575
 
        if (t) {
576
 
            switch (t) {
577
 
              case BITWISE_OR:  v = u | v; break;
578
 
              case BITWISE_XOR: v = u ^ v; break;
579
 
              case BITWISE_AND: v = u & v; break;
580
 
              case LSH:         v = u << v; break;
581
 
              case RSH:         v = u >> v; break;
582
 
              case URSH:        v = u >>> v; break;
583
 
              case PLUS:        v = u + v; break;
584
 
              case MINUS:       v = u - v; break;
585
 
              case MUL:         v = u * v; break;
586
 
              case DIV:         v = u / v; break;
587
 
              case MOD:         v = u % v; break;
588
 
            }
589
 
        }
590
 
        putValue(r, v, n[0]);
591
 
        break;
592
 
 
593
 
      case CONDITIONAL:
594
 
        v = getValue(execute(n[0], x)) ? getValue(execute(n[1], x))
595
 
                                       : getValue(execute(n[2], x));
596
 
        break;
597
 
 
598
 
      case OR:
599
 
        v = getValue(execute(n[0], x)) || getValue(execute(n[1], x));
600
 
        break;
601
 
 
602
 
      case AND:
603
 
        v = getValue(execute(n[0], x)) && getValue(execute(n[1], x));
604
 
        break;
605
 
 
606
 
      case BITWISE_OR:
607
 
        v = getValue(execute(n[0], x)) | getValue(execute(n[1], x));
608
 
        break;
609
 
 
610
 
      case BITWISE_XOR:
611
 
        v = getValue(execute(n[0], x)) ^ getValue(execute(n[1], x));
612
 
        break;
613
 
 
614
 
      case BITWISE_AND:
615
 
        v = getValue(execute(n[0], x)) & getValue(execute(n[1], x));
616
 
        break;
617
 
 
618
 
      case EQ:
619
 
        v = getValue(execute(n[0], x)) == getValue(execute(n[1], x));
620
 
        break;
621
 
 
622
 
      case NE:
623
 
        v = getValue(execute(n[0], x)) != getValue(execute(n[1], x));
624
 
        break;
625
 
 
626
 
      case STRICT_EQ:
627
 
        v = getValue(execute(n[0], x)) === getValue(execute(n[1], x));
628
 
        break;
629
 
 
630
 
      case STRICT_NE:
631
 
        v = getValue(execute(n[0], x)) !== getValue(execute(n[1], x));
632
 
        break;
633
 
 
634
 
      case LT:
635
 
        v = getValue(execute(n[0], x)) < getValue(execute(n[1], x));
636
 
        break;
637
 
 
638
 
      case LE:
639
 
        v = getValue(execute(n[0], x)) <= getValue(execute(n[1], x));
640
 
        break;
641
 
 
642
 
      case GE:
643
 
        v = getValue(execute(n[0], x)) >= getValue(execute(n[1], x));
644
 
        break;
645
 
 
646
 
      case GT:
647
 
        v = getValue(execute(n[0], x)) > getValue(execute(n[1], x));
648
 
        break;
649
 
 
650
 
      case IN:
651
 
        v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));
652
 
        break;
653
 
 
654
 
      case INSTANCEOF:
655
 
        t = getValue(execute(n[0], x));
656
 
        u = getValue(execute(n[1], x));
657
 
        if (isObject(u) && typeof u.__hasInstance__ == "function")
658
 
            v = u.__hasInstance__(t);
659
 
        else
660
 
            v = t instanceof u;
661
 
        break;
662
 
 
663
 
      case LSH:
664
 
        v = getValue(execute(n[0], x)) << getValue(execute(n[1], x));
665
 
        break;
666
 
 
667
 
      case RSH:
668
 
        v = getValue(execute(n[0], x)) >> getValue(execute(n[1], x));
669
 
        break;
670
 
 
671
 
      case URSH:
672
 
        v = getValue(execute(n[0], x)) >>> getValue(execute(n[1], x));
673
 
        break;
674
 
 
675
 
      case PLUS:
676
 
        v = getValue(execute(n[0], x)) + getValue(execute(n[1], x));
677
 
        break;
678
 
 
679
 
      case MINUS:
680
 
        v = getValue(execute(n[0], x)) - getValue(execute(n[1], x));
681
 
        break;
682
 
 
683
 
      case MUL:
684
 
        v = getValue(execute(n[0], x)) * getValue(execute(n[1], x));
685
 
        break;
686
 
 
687
 
      case DIV:
688
 
        v = getValue(execute(n[0], x)) / getValue(execute(n[1], x));
689
 
        break;
690
 
 
691
 
      case MOD:
692
 
        v = getValue(execute(n[0], x)) % getValue(execute(n[1], x));
693
 
        break;
694
 
 
695
 
      case DELETE:
696
 
        t = execute(n[0], x);
697
 
        v = !(t instanceof Reference) || delete t.base[t.propertyName];
698
 
        break;
699
 
 
700
 
      case VOID:
701
 
        getValue(execute(n[0], x));
702
 
        break;
703
 
 
704
 
      case TYPEOF:
705
 
        t = execute(n[0], x);
706
 
        if (t instanceof Reference)
707
 
            t = t.base ? t.base[t.propertyName] : undefined;
708
 
        v = typeof t;
709
 
        break;
710
 
 
711
 
      case NOT:
712
 
        v = !getValue(execute(n[0], x));
713
 
        break;
714
 
 
715
 
      case BITWISE_NOT:
716
 
        v = ~getValue(execute(n[0], x));
717
 
        break;
718
 
 
719
 
      case UNARY_PLUS:
720
 
        v = +getValue(execute(n[0], x));
721
 
        break;
722
 
 
723
 
      case UNARY_MINUS:
724
 
        v = -getValue(execute(n[0], x));
725
 
        break;
726
 
 
727
 
      case INCREMENT:
728
 
      case DECREMENT:
729
 
        t = execute(n[0], x);
730
 
        u = Number(getValue(t));
731
 
        if (n.postfix)
732
 
            v = u;
733
 
        putValue(t, (n.type == INCREMENT) ? ++u : --u, n[0]);
734
 
        if (!n.postfix)
735
 
            v = u;
736
 
        break;
737
 
 
738
 
      case DOT:
739
 
        r = execute(n[0], x);
740
 
        t = getValue(r);
741
 
        u = n[1].value;
742
 
        v = new Reference(toObject(t, r, n[0]), u, n);
743
 
        break;
744
 
 
745
 
      case INDEX:
746
 
        r = execute(n[0], x);
747
 
        t = getValue(r);
748
 
        u = getValue(execute(n[1], x));
749
 
        v = new Reference(toObject(t, r, n[0]), String(u), n);
750
 
        break;
751
 
 
752
 
      case LIST:
753
 
        // Curse ECMA for specifying that arguments is not an Array object!
754
 
        v = {};
755
 
        for (i = 0, j = n.$length; i < j; i++) {
756
 
            u = getValue(execute(n[i], x));
757
 
            v[i] = u;
758
 
        }
759
 
        v.length = i;
760
 
        break;
761
 
 
762
 
      case CALL:
763
 
        r = execute(n[0], x);
764
 
        a = execute(n[1], x);
765
 
        f = getValue(r);
766
 
        if (isPrimitive(f) || typeof f.__call__ != "function") {
767
 
            throw new TypeError(r + " is not callable",
768
 
                                n[0].filename(), n[0].lineno);
769
 
        }
770
 
        t = (r instanceof Reference) ? r.base : null;
771
 
        if (t instanceof Activation)
772
 
            t = null;
773
 
        v = f.__call__(t, a, x);
774
 
        break;
775
 
 
776
 
      case NEW:
777
 
      case NEW_WITH_ARGS:
778
 
        r = execute(n[0], x);
779
 
        f = getValue(r);
780
 
        if (n.type == NEW) {
781
 
            a = {};
782
 
            a.length = 0;
783
 
        } else {
784
 
            a = execute(n[1], x);
785
 
        }
786
 
        if (isPrimitive(f) || typeof f.__construct__ != "function") {
787
 
            throw new TypeError(r + " is not a constructor",
788
 
                                n[0].filename(), n[0].lineno);
789
 
        }
790
 
        v = f.__construct__(a, x);
791
 
        break;
792
 
 
793
 
      case ARRAY_INIT:
794
 
        v = [];
795
 
        for (i = 0, j = n.$length; i < j; i++) {
796
 
            if (n[i])
797
 
                v[i] = getValue(execute(n[i], x));
798
 
        }
799
 
        v.length = j;
800
 
        break;
801
 
 
802
 
      case OBJECT_INIT:
803
 
        v = {};
804
 
        for (i = 0, j = n.$length; i < j; i++) {
805
 
            t = n[i];
806
 
            if (t.type == PROPERTY_INIT) {
807
 
                v[t[0].value] = getValue(execute(t[1], x));
808
 
            } else {
809
 
                f = new FunctionObject(t, x.scope);
810
 
                /*
811
 
                u = (t.type == GETTER) ? '__defineGetter__'
812
 
                                       : '__defineSetter__';
813
 
                v[u](t.name, thunk(f, x));
814
 
                */
815
 
            }
816
 
        }
817
 
        break;
818
 
 
819
 
      case NULL:
820
 
        v = null;
821
 
        break;
822
 
 
823
 
      case THIS:
824
 
        v = x.thisObject;
825
 
        break;
826
 
 
827
 
      case TRUE:
828
 
        v = true;
829
 
        break;
830
 
 
831
 
      case FALSE:
832
 
        v = false;
833
 
        break;
834
 
 
835
 
      case IDENTIFIER:
836
 
        for (s = x.scope; s; s = s.parent) {
837
 
            if (n.value in s.object)
838
 
                break;
839
 
        }
840
 
        v = new Reference(s && s.object, n.value, n);
841
 
        break;
842
 
 
843
 
      case NUMBER:
844
 
      case STRING:
845
 
      case REGEXP:
846
 
        v = n.value;
847
 
        break;
848
 
 
849
 
      case GROUP:
850
 
        v = execute(n[0], x);
851
 
        break;
852
 
 
853
 
      default:
854
 
        throw "PANIC: unknown operation " + n.type + ": " + uneval(n);
855
 
    }
856
 
    return v;
857
 
}
858
 
 
859
 
function Activation(f, a) {
860
 
    for (var i = 0, j = f.params.length; i < j; i++)
861
 
        this[f.params[i]] = a[i];
862
 
    this.arguments = a;
863
 
}
864
 
 
865
 
// Null Activation.prototype's proto slot so that Object.prototype.* does not
866
 
// pollute the scope of heavyweight functions.  Also delete its 'constructor'
867
 
// property so that it doesn't pollute function scopes.
868
 
 
869
 
Activation.prototype.__proto__ = null;
870
 
delete Activation.prototype.constructor;
871
 
 
872
 
function FunctionObject(node, scope) {
873
 
    this.node = node;
874
 
    this.scope = scope;
875
 
    this.length = node.params.length;
876
 
    var proto = {};
877
 
    this.prototype = proto;
878
 
    proto.constructor = this;
879
 
}
880
 
 
881
 
var FOp = FunctionObject.prototype = {
882
 
    // Internal methods.
883
 
    __call__: function (t, a, x) {
884
 
        var x2 = new ExecutionContext(FUNCTION_CODE);
885
 
        x2.thisObject = t || global;
886
 
        x2.caller = x;
887
 
        x2.callee = this;
888
 
        a.callee = this;
889
 
        var f = this.node;
890
 
        x2.scope = {object: new Activation(f, a), parent: this.scope};
891
 
 
892
 
        ExecutionContext.current = x2;
893
 
        try {
894
 
            execute(f.body, x2);
895
 
        } catch (e) {
896
 
            if (!(e == RETURN)) { throw e } else if (e == RETURN) {
897
 
                return x2.result;
898
 
            }
899
 
            if (e != THROW) { throw e }
900
 
            x.result = x2.result;
901
 
            throw THROW;
902
 
        } finally {
903
 
            ExecutionContext.current = x;
904
 
        }
905
 
        return undefined;
906
 
    },
907
 
 
908
 
    __construct__: function (a, x) {
909
 
        var o = new Object;
910
 
        var p = this.prototype;
911
 
        if (isObject(p))
912
 
            o.__proto__ = p;
913
 
        // else o.__proto__ defaulted to Object.prototype
914
 
 
915
 
        var v = this.__call__(o, a, x);
916
 
        if (isObject(v))
917
 
            return v;
918
 
        return o;
919
 
    },
920
 
 
921
 
    __hasInstance__: function (v) {
922
 
        if (isPrimitive(v))
923
 
            return false;
924
 
        var p = this.prototype;
925
 
        if (isPrimitive(p)) {
926
 
            throw new TypeError("'prototype' property is not an object",
927
 
                                this.node.filename(), this.node.lineno);
928
 
        }
929
 
        var o;
930
 
        while ((o = v.__proto__)) {
931
 
            if (o == p)
932
 
                return true;
933
 
            v = o;
934
 
        }
935
 
        return false;
936
 
    },
937
 
 
938
 
    // Standard methods.
939
 
    toString: function () {
940
 
        return this.node.getSource();
941
 
    },
942
 
 
943
 
    apply: function (t, a) {
944
 
        // Curse ECMA again!
945
 
        if (typeof this.__call__ != "function") {
946
 
            throw new TypeError("Function.prototype.apply called on" +
947
 
                                " uncallable object");
948
 
        }
949
 
 
950
 
        if (t === undefined || t === null)
951
 
            t = global;
952
 
        else if (typeof t != "object")
953
 
            t = toObject(t, t);
954
 
 
955
 
        if (a === undefined || a === null) {
956
 
            a = {};
957
 
            a.length = 0;
958
 
        } else if (a instanceof Array) {
959
 
            var v = {};
960
 
            for (var i = 0, j = a.length; i < j; i++)
961
 
                v[i] = a[i];
962
 
            v.length = i;
963
 
            a = v;
964
 
        } else if (!(a instanceof Object)) {
965
 
            // XXX check for a non-arguments object
966
 
            throw new TypeError("Second argument to Function.prototype.apply" +
967
 
                                " must be an array or arguments object",
968
 
                                this.node.filename(), this.node.lineno);
969
 
        }
970
 
 
971
 
        return this.__call__(t, a, ExecutionContext.current);
972
 
    },
973
 
 
974
 
    call: function (t) {
975
 
        // Curse ECMA a third time!
976
 
        var a = Array.prototype.splice.call(arguments, 1);
977
 
        return this.apply(t, a);
978
 
    }
979
 
};
980
 
 
981
 
// Connect Function.prototype and Function.prototype.constructor in global.
982
 
reflectClass('Function', FOp);
983
 
 
984
 
// Help native and host-scripted functions be like FunctionObjects.
985
 
var Fp = Function.prototype;
986
 
var REp = RegExp.prototype;
987
 
 
988
 
if (!('__call__' in Fp)) {
989
 
    Fp.__call__ = function (t, a, x) {
990
 
        // Curse ECMA yet again!
991
 
        a = Array.prototype.splice.call(a, 0, a.length);
992
 
        return this.apply(t, a);
993
 
    };
994
 
 
995
 
    REp.__call__ = function (t, a, x) {
996
 
        a = Array.prototype.splice.call(a, 0, a.length);
997
 
        return this.exec.apply(this, a);
998
 
    };
999
 
 
1000
 
    Fp.__construct__ = function (a, x) {
1001
 
        switch (a.length) {
1002
 
          case 0:
1003
 
            return new this();
1004
 
          case 1:
1005
 
            return new this(a[0]);
1006
 
          case 2:
1007
 
            return new this(a[0], a[1]);
1008
 
          case 3:
1009
 
            return new this(a[0], a[1], a[2]);
1010
 
          case 4:
1011
 
            return new this(a[0], a[1], a[2], a[3]);
1012
 
          case 5:
1013
 
            return new this(a[0], a[1], a[2], a[3], a[4]);
1014
 
          case 6:
1015
 
            return new this(a[0], a[1], a[2], a[3], a[4], a[5]);
1016
 
          case 7:
1017
 
            return new this(a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
1018
 
        }
1019
 
        throw "PANIC: too many arguments to constructor";
1020
 
    }
1021
 
 
1022
 
    // Since we use native functions such as Date along with host ones such
1023
 
    // as global.eval, we want both to be considered instances of the native
1024
 
    // Function constructor.
1025
 
    Fp.__hasInstance__ = function (v) {
1026
 
        return v instanceof Function || v instanceof global.Function;
1027
 
    };
1028
 
}
1029
 
 
1030
 
function thunk(f, x) {
1031
 
    return function () { return f.__call__(this, arguments, x); };
1032
 
}
1033
 
 
1034
 
function evaluate(s, f, l) {
1035
 
    if (typeof s != "string")
1036
 
        return s;
1037
 
 
1038
 
    var x = ExecutionContext.current;
1039
 
    var x2 = new ExecutionContext(GLOBAL_CODE);
1040
 
    ExecutionContext.current = x2;
1041
 
    try {
1042
 
        execute(parse(s, f, l), x2);
1043
 
    } catch (e) {
1044
 
        if (e != THROW) { throw e }
1045
 
        if (x) {
1046
 
            x.result = x2.result;
1047
 
            throw(THROW);
1048
 
        }
1049
 
        throw x2.result;
1050
 
    } finally {
1051
 
        ExecutionContext.current = x;
1052
 
    }
1053
 
    return x2.result;
1054
 
}