[ Index ]
 

Code source de PRADO 3.0.6

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/tests/test_tools/selenium/core/scripts/ -> narcissus-exec.js (source)

   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  }


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7