1 28 29 package com.caucho.es; 30 31 import java.util.Enumeration ; 32 import java.util.Iterator ; 33 34 37 public final class Call extends ESBase { 38 static ESId ARGUMENTS = ESId.intern("arguments"); 39 static ESId ARRAY = ESId.intern("Array"); 40 41 Call caller; 42 ESObject callThis; 43 int callLength; 44 ESBase callee; 45 46 public ESBase []stack; 47 int top; 48 49 public ESGlobal global; 50 ESBase []scope; 51 int scopeLength; 52 53 public ESBase []values; 54 55 ESObject aux; 56 57 Call child; 59 62 Call() 63 { 64 prototype = esBase; 65 66 stack = new ESBase[64]; 67 scope = new ESBase[16]; 68 values = new ESBase[64]; 69 top = 0; 70 } 71 72 void clear() 73 { 74 aux = null; 75 child = null; 76 top = 0; 77 } 78 79 public Call getCall() 80 { 81 Call child = this.child; 82 83 if (child == null) 84 child = this.child = new Call(); 85 86 child.caller = this; 87 88 child.global = global; 89 90 return child; 91 } 92 93 Global getGlobalProto() { return Global.getGlobalProto(); } 94 95 public ESBase wrap(Object o) throws Throwable { return Global.wrap(o); } 96 97 public ESBase wrap(long n) throws Throwable 98 { 99 return ESNumber.create(n); 100 } 101 102 public ESBase wrapClass(Class cl) throws Throwable 103 { 104 return Global.getGlobalProto().classWrap(cl); 105 } 106 107 109 final ESBase getArg(int i) 110 { 111 return stack[top + i]; 112 } 113 114 public final ESBase getArg(int i, int len) 115 { 116 return i < len ? stack[top + i] : esUndefined; 117 } 118 119 public final int getArgInt32(int i, int len) throws Throwable 120 { 121 return i < len ? stack[top + i].toInt32() : 0; 122 } 123 124 public final double getArgNum(int i, int len) throws Throwable 125 { 126 return i < len ? stack[top + i].toNum() : (0.0/0.0); 127 } 128 129 public final String getArgString(int i, int len) throws Throwable 130 { 131 return i < len ? stack[top + i].toJavaString() : null; 132 } 133 134 public final Object getArgObject(int i, int len) throws Throwable 135 { 136 return i < len ? stack[top + i].toJavaObject() : null; 137 } 138 139 public ESObject createObject() 140 { 141 return new ESObject("Object", getGlobalProto().objProto); 142 } 143 144 public ESBase createDate(long time) 145 { 146 return new ESDate(time, getGlobalProto().dateProto); 147 } 148 149 public String printf(int length) 150 throws Throwable 151 { 152 return Printf.sprintf(this, length); 153 } 154 155 void setArg(int i, ESBase obj) 156 { 157 stack[top + i] = obj; 158 } 159 160 public final ESObject getThis() throws Throwable 161 { 162 return stack[top - 1].toObject(); 163 } 164 165 public final Object getThisWrapper() throws Throwable 166 { 167 return stack[top - 1].toJavaObject(); 168 } 169 170 void setThis(ESBase obj) 171 { 172 stack[top - 1] = obj; 173 } 174 175 public ESGlobal getGlobal() 176 { 177 return global; 178 } 179 180 public final ESObject getCallThis() throws Throwable 181 { 182 ESBase obj = caller.stack[caller.top - 1]; 183 184 return obj.toObject(); 185 } 186 187 ESBase getContext() 188 { 189 return scope[scopeLength - 1]; 190 } 191 192 ESBase getFunctionContext() 193 { 194 if (caller == null || caller.scopeLength == 0) 195 return global; 196 else 197 return caller.scope[caller.scopeLength - 1]; 198 } 199 200 public void pushScope(ESBase value) 201 { 202 scope[scopeLength++] = value; 203 } 204 205 public void popScope() 206 { 207 scopeLength--; 208 } 209 210 public ESObject getEval() 211 { 212 return (ESObject) scope[scopeLength - 1]; 213 } 214 215 public ESObject createArg(ESId []args, int length) 216 throws Throwable 217 { 218 ESObject arg = ESArguments.create(args, this, length); 219 220 scope[scopeLength++] = arg; 221 222 return arg; 223 } 224 225 public void setProperty(ESString name, ESBase value) throws Throwable 226 { 227 } 229 230 public ESBase delete(ESString key) throws Throwable 231 { 232 return aux == null ? ESBoolean.FALSE : aux.delete(key); 233 } 234 235 public ESBase findScopeProperty(ESString id) throws Throwable 236 { 237 for (int i = scopeLength - 1; i > 0; i--) { 238 if (scope[i].getProperty(id) != esEmpty) 239 return scope[i]; 240 } 241 242 return global; 243 } 244 245 public ESBase scopeTypeof(ESString id) throws Throwable 246 { 247 for (int i = scopeLength - 1; i >= 0; i--) { 248 ESBase value; 249 if ((value = scope[i].getProperty(id)) != esEmpty) 250 return value.typeof(); 251 } 252 253 return esEmpty.typeof(); 254 } 255 256 public static ESBase setProperty(ESBase base, ESString field, ESBase value) 257 throws Throwable 258 { 259 base.setProperty(field, value); 260 261 return value; 262 } 263 264 public static ESBase doVoid(ESBase value) 265 { 266 return ESBase.esUndefined; 267 } 268 269 public ESBase array(ESBase value) 270 throws Throwable 271 { 272 ESBase array = call(global, ARRAY, 0); 273 array.setProperty(0, value); 274 return array; 275 } 276 277 public static ESBase comma(ESBase left, ESBase right) 278 { 279 return right; 280 } 281 282 public static ESBase _first(ESBase left, ESBase right) 283 throws Throwable 284 { 285 if (! (left instanceof ESNumber)) 287 return ESNumber.create(left.toNum()); 288 else 289 return left; 290 } 291 292 public static double _first(double left, double right) 293 throws Throwable 294 { 295 return left; 296 } 297 298 306 public static int _first(int left, int right) 307 throws Throwable 308 { 309 return left; 310 } 311 312 public static double _pre(ESBase expr, ESString field, int inc) 313 throws Throwable 314 { 315 double oldVal = expr.getProperty(field).toNum(); 316 ESNumber newVal = ESNumber.create(oldVal + inc); 317 318 expr.setProperty(field, newVal); 319 320 return oldVal + inc; 321 } 322 323 public static double _post(ESBase expr, ESString field, int inc) 324 throws Throwable 325 { 326 double oldVal = expr.getProperty(field).toNum(); 327 ESNumber newVal = ESNumber.create(oldVal + inc); 328 329 expr.setProperty(field, newVal); 330 331 return oldVal; 332 } 333 334 public double _pre(ESString field, int inc) 335 throws Throwable 336 { 337 double oldVal = getScopeProperty(field).toNum(); 338 ESNumber newVal = ESNumber.create(oldVal + inc); 339 340 setScopeProperty(field, newVal); 341 342 return oldVal + inc; 343 } 344 345 public double _post(ESString field, int inc) 346 throws Throwable 347 { 348 double oldVal = getScopeProperty(field).toNum(); 349 ESNumber newVal = ESNumber.create(oldVal + inc); 350 351 setScopeProperty(field, newVal); 352 353 return oldVal; 354 } 355 356 public ESBase setGlobalProperty(ESString id, ESBase value) throws Throwable 357 { 358 global.setProperty(id, value); 359 360 return value; 361 } 362 363 367 public ESBase getGlobalVariable(ESString id) throws Throwable 368 { 369 ESBase value = global.getProperty(id); 370 if (value == ESBase.esEmpty) 371 throw new ESUndefinedException("undefined variable `" + id + "'"); 372 373 return value; 374 } 375 376 public ESBase getScopeProperty(ESString id) throws Throwable 377 { 378 for (int i = scopeLength - 1; i >= 0; i--) { 379 ESBase value; 380 if ((value = scope[i].getProperty(id)) != esEmpty) { 381 return value; 382 } 383 } 384 385 throw new ESUndefinedException("undefined variable `" + id + "'"); 386 } 387 388 public void fillScope() 389 { 390 if (callee instanceof ESClosure) { 391 ESClosure closure = (ESClosure) callee; 392 393 if (closure.scopeLength == 0) { 394 scope[0] = caller.global; 395 scopeLength = 1; 396 return; 397 } 398 for (int i = 0; i < closure.scopeLength; i++) { 399 scope[i] = closure.scope[i]; 400 } 401 scopeLength = closure.scopeLength; 402 } 403 else { 404 scope[0] = caller.global; 405 scopeLength = 1; 406 } 407 } 408 409 public ESBase hasScopeProperty(ESString id) throws Throwable 410 { 411 for (int i = scopeLength - 1; i >= 0; i--) { 412 ESBase value; 413 if ((value = scope[i].getProperty(id)) != esEmpty) 414 return value; 415 } 416 417 return esEmpty; 418 } 419 420 public ESBase setScopeProperty(ESString id, ESBase value) throws Throwable 421 { 422 if (value == esEmpty) 423 value = esUndefined; 424 425 for (int i = scopeLength - 1; i > 0; i--) { 426 if (scope[i].getProperty(id) != esEmpty) { 427 scope[i].setProperty(id, value); 428 return value; 429 } 430 } 431 432 global.setProperty(id, value); 433 434 return value; 435 } 436 437 public ESBase deleteScopeProperty(ESString id) throws Throwable 438 { 439 for (int i = scopeLength - 1; i > 0; i--) { 440 if (scope[i].getProperty(id) != esEmpty) 441 return scope[i].delete(id); 442 } 443 444 return global.delete(id); 445 } 446 463 464 public int arg(int i, ESBase arg) 465 { 466 stack[i + 1] = arg; 467 468 return 1; 469 } 470 471 public ESBase callScope(ESString id, int i) throws Throwable 472 { 473 top = i + 1; 474 475 int scopeLength = caller.scopeLength; 476 ESBase []scope = caller.scope; 477 for (int j = scopeLength - 1; j >= 0; j--) { 478 ESBase value; 479 480 if ((value = scope[j].getProperty(id)) != esEmpty) { 481 callee = value; 482 stack[i] = scope[j]; 483 return value.call(this, 0); 484 } 485 } 486 487 throw new ESUndefinedException("undefined call `" + id + "'"); 488 } 489 490 public ESBase callScope(ESString id, int i, ESBase a) throws Throwable 491 { 492 top = i + 1; 493 494 int scopeLength = caller.scopeLength; 495 ESBase []scope = caller.scope; 496 for (int j = scopeLength - 1; j >= 0; j--) { 497 ESBase value; 498 499 if ((value = scope[j].getProperty(id)) != esEmpty) { 500 callee = value; 501 stack[i] = scope[j]; 502 stack[i + 1] = a; 503 return value.call(this, 1); 504 } 505 } 506 507 throw new ESUndefinedException("undefined call `" + id + "'"); 508 } 509 510 public ESBase callScope(ESString id, int i, ESBase a, ESBase b) 511 throws Throwable 512 { 513 top = i + 1; 514 515 int scopeLength = caller.scopeLength; 516 ESBase []scope = caller.scope; 517 for (int j = scopeLength - 1; j >= 0; j--) { 518 ESBase value; 519 520 if ((value = scope[j].getProperty(id)) != esEmpty) { 521 callee = value; 522 stack[i] = scope[j]; 523 stack[i + 1] = a; 524 stack[i + 2] = b; 525 return value.call(this, 2); 526 } 527 } 528 529 throw new ESUndefinedException("undefined call `" + id + "'"); 530 } 531 532 public ESBase callScope(ESString id, int i, ESBase a, ESBase b, ESBase c, 533 int length) 534 throws Throwable 535 { 536 top = i + 1; 537 538 int scopeLength = caller.scopeLength; 539 ESBase []scope = caller.scope; 540 for (int j = scopeLength - 1; j >= 0; j--) { 541 ESBase value; 542 if ((value = scope[j].getProperty(id)) != esEmpty) { 543 callee = value; 544 stack[i] = scope[j]; 545 stack[i + 1] = a; 546 stack[i + 2] = b; 547 stack[i + 3] = c; 548 return value.call(this, length); 549 } 550 } 551 552 throw new ESUndefinedException("undefined call `" + id + "'"); 553 } 554 555 public ESBase call(ESBase base, ESString name, int i) 556 throws Throwable 557 { 558 top = i + 1; 559 560 stack[i] = base; 561 562 return base.call(this, 0, name); 563 } 564 565 public ESBase call(ESBase base, ESString name, int i, ESBase a) 566 throws Throwable 567 { 568 top = i + 1; 569 570 stack[i] = base; 571 stack[i + 1] = a; 572 573 return base.call(this, 1, name); 574 } 575 576 public ESBase call(ESBase base, ESString name, int i, ESBase a, ESBase b) 577 throws Throwable 578 { 579 top = i + 1; 580 581 stack[i] = base; 582 stack[i + 1] = a; 583 stack[i + 2] = b; 584 585 return base.call(this, 2, name); 586 } 587 588 public ESBase call(ESBase base, ESString name, int i, 589 ESBase a, ESBase b, ESBase c, int length) 590 throws Throwable 591 { 592 top = i + 1; 593 594 stack[i] = base; 595 stack[i + 1] = a; 596 stack[i + 2] = b; 597 stack[i + 3] = c; 598 599 return base.call(this, length, name); 600 } 601 602 public ESBase call(ESBase base, int i) 603 throws Throwable 604 { 605 top = i + 1; 606 607 stack[i] = global; 608 callee = base; 609 610 return base.call(this, 0); 611 } 612 613 public ESBase call(ESBase base, int i, ESBase a) 614 throws Throwable 615 { 616 top = i + 1; 617 618 stack[i + 1] = a; 619 stack[i] = global; 620 callee = base; 621 return base.call(this, 1); 622 } 623 624 public ESBase call(ESBase base, int i, ESBase a, ESBase b) 625 throws Throwable 626 { 627 top = i + 1; 628 629 stack[i] = base; 630 stack[i + 1] = a; 631 stack[i + 2] = b; 632 stack[i] = global; 633 callee = base; 634 return base.call(this, 2); 635 } 636 637 public ESBase call(ESBase base, int i, 638 ESBase a, ESBase b, ESBase c, int length) 639 throws Throwable 640 { 641 top = i + 1; 642 643 stack[i] = base; 644 stack[i + 1] = a; 645 stack[i + 2] = b; 646 stack[i + 3] = c; 647 stack[i] = global; 648 callee = base; 649 return base.call(this, length); 650 } 651 652 public ESBase newScope(ESString id, int i) throws Throwable 653 { 654 top = i + 1; 655 656 int scopeLength = caller.scopeLength; 657 ESBase []scope = caller.scope; 658 for (int j = scopeLength - 1; j >= 0; j--) { 659 ESBase value; 660 661 if ((value = scope[j].getProperty(id)) != esEmpty) { 662 callee = value; 663 stack[i] = global; 664 return value.construct(this, 0); 665 } 666 } 667 668 throw new ESUndefinedException("undefined constructor `" + id + "'"); 669 } 670 671 public ESBase newScope(ESString id, int i, ESBase a) throws Throwable 672 { 673 top = i + 1; 674 675 int scopeLength = caller.scopeLength; 676 ESBase []scope = caller.scope; 677 for (int j = scopeLength - 1; j >= 0; j--) { 678 ESBase value; 679 680 if ((value = scope[j].getProperty(id)) != esEmpty) { 681 callee = value; 682 stack[i] = global; 683 stack[i + 1] = a; 684 return value.construct(this, 1); 685 } 686 } 687 688 throw new ESUndefinedException("undefined constructor `" + id + "'"); 689 } 690 691 public ESBase newScope(ESString id, int i, ESBase a, ESBase b) 692 throws Throwable 693 { 694 top = i + 1; 695 696 int scopeLength = caller.scopeLength; 697 ESBase []scope = caller.scope; 698 for (int j = scopeLength - 1; j >= 0; j--) { 699 ESBase value; 700 701 if ((value = scope[j].getProperty(id)) != esEmpty) { 702 callee = value; 703 stack[i] = global; 704 stack[i + 1] = a; 705 stack[i + 2] = b; 706 return value.construct(this, 2); 707 } 708 } 709 710 throw new ESUndefinedException("undefined constructor `" + id + "'"); 711 } 712 713 public ESBase newScope(ESString id, int i, ESBase a, ESBase b, ESBase c, 714 int length) 715 throws Throwable 716 { 717 top = i + 1; 718 719 int scopeLength = caller.scopeLength; 720 ESBase []scope = caller.scope; 721 for (int j = scopeLength - 1; j >= 0; j--) { 722 ESBase value; 723 724 if ((value = scope[j].getProperty(id)) != esEmpty) { 725 callee = value; 726 stack[i] = global; 727 stack[i + 1] = a; 728 stack[i + 2] = b; 729 stack[i + 3] = c; 730 return value.construct(this, length); 731 } 732 } 733 734 throw new ESUndefinedException("undefined constructor `" + id + "'"); 735 } 736 737 public ESBase doNew(ESBase base, ESString name, int i) 738 throws Throwable 739 { 740 top = i + 1; 741 742 ESBase obj = base.getProperty(name); 743 stack[i] = base; 744 callee = obj; 745 if (obj != esEmpty) 746 return obj.construct(this, 0); 747 else 748 throw new ESUndefinedException("undefined constructor `" + name + "'"); 749 } 750 751 public ESBase doNew(ESBase base, ESString name, int i, ESBase a) 752 throws Throwable 753 { 754 top = i + 1; 755 756 stack[i] = base; 757 stack[i + 1] = a; 758 759 ESBase obj = base.getProperty(name); 760 callee = obj; 761 if (obj != esEmpty) 762 return obj.construct(this, 1); 763 else 764 throw new ESUndefinedException("undefined constructor `" + name + "'"); 765 } 766 767 public ESBase doNew(ESBase base, ESString name, int i, ESBase a, ESBase b) 768 throws Throwable 769 { 770 top = i + 1; 771 772 stack[i] = base; 773 stack[i + 1] = a; 774 stack[i + 2] = b; 775 776 ESBase obj = base.getProperty(name); 777 callee = obj; 778 if (obj != esEmpty) 779 return obj.construct(this, 2); 780 else 781 throw new ESUndefinedException("undefined constructor `" + name + "'"); 782 } 783 784 public ESBase doNew(ESBase base, ESString name, int i, 785 ESBase a, ESBase b, ESBase c, int length) 786 throws Throwable 787 { 788 top = i + 1; 789 790 stack[i] = base; 791 stack[i + 1] = a; 792 stack[i + 2] = b; 793 stack[i + 3] = c; 794 795 ESBase obj = base.getProperty(name); 796 callee = obj; 797 if (obj != esEmpty) 798 return obj.construct(this, length); 799 else 800 throw new ESUndefinedException("undefined constructor `" + name + "'"); 801 } 802 803 public ESBase doNew(ESBase base, int i) 804 throws Throwable 805 { 806 top = i + 1; 807 808 stack[i] = global; 809 callee = base; 810 return base.construct(this, 0); 811 } 812 813 public ESBase doNew(ESBase base, int i, ESBase a) 814 throws Throwable 815 { 816 top = i + 1; 817 818 stack[i] = global; 819 stack[i + 1] = a; 820 callee = base; 821 822 return base.construct(this, 1); 823 } 824 825 public ESBase doNew(ESBase base, int i, ESBase a, ESBase b) 826 throws Throwable 827 { 828 top = i + 1; 829 830 stack[i] = global; 831 stack[i + 1] = a; 832 stack[i + 2] = b; 833 callee = base; 834 835 return base.construct(this, 2); 836 } 837 838 public ESBase doNew(ESBase base, int i, 839 ESBase a, ESBase b, ESBase c, int length) 840 throws Throwable 841 { 842 top = i + 1; 843 844 stack[i] = global; 845 stack[i + 1] = a; 846 stack[i + 2] = b; 847 stack[i + 3] = c; 848 callee = base; 849 850 return base.construct(this, length); 851 } 852 853 public void free() 854 { 855 clear(); 856 857 for (int i = stack.length - 1; i >= 0; i--) 858 stack[i] = null; 859 for (int i = scope.length - 1; i >= 0; i--) 860 scope[i] = null; 861 for (int i = values.length - 1; i >= 0; i--) 862 values[i] = null; 863 global = null; 864 } 865 866 public static Iterator toESIterator(Iterator i) 867 { 868 return new ESIterator(i); 869 } 870 871 public static Iterator toESIterator(Enumeration e) 872 { 873 return new ESEnumIterator(e); 874 } 875 876 public static boolean matchException(ESBase test, Exception e) 877 { 878 String testString; 879 try { 880 testString = test.toStr().toString(); 881 } catch (Throwable foo) { 882 testString = "undefined"; 883 } 884 885 Class eClass = e.getClass(); 886 String dotted = "." + test; 887 888 for (; eClass != null; eClass = eClass.getSuperclass()) { 889 String eString = eClass.getName(); 890 891 if (testString.equals(eString) || eString.endsWith(dotted)) 892 return true; 893 } 894 895 return false; 896 } 897 898 static class ESIterator implements Iterator { 899 Global resin; 900 Iterator i; 901 902 public boolean hasNext() 903 { 904 return i != null && i.hasNext(); 905 } 906 907 public Object next() 908 { 909 Object value = i == null ? null : i.next(); 910 911 Object result; 912 try { 913 if (value == null) 914 result = ESBase.esNull; 915 else 916 result = resin.objectWrap(value); 917 } catch (Throwable e) { 918 result = ESBase.esNull; 919 } 920 921 return result; 922 } 923 924 public void remove() { throw new RuntimeException (); } 925 926 ESIterator(Iterator i) 927 { 928 this.i = i; 929 this.resin = Global.getGlobalProto(); 930 } 931 } 932 933 static class ESEnumIterator implements Iterator { 934 Global resin; 935 Enumeration e; 936 937 public boolean hasNext() 938 { 939 return e != null && e.hasMoreElements(); 940 } 941 942 public Object next() 943 { 944 Object value = e != null ? e.nextElement() : null;; 945 946 try { 947 if (value == null) 948 return ESBase.esNull; 949 else 950 return resin.objectWrap(value); 951 } catch (Throwable e) { 952 return ESBase.esNull; 953 } 954 } 955 956 public void remove() { throw new RuntimeException (); } 957 958 ESEnumIterator(Enumeration e) 959 { 960 this.e = e; 961 this.resin = Global.getGlobalProto(); 962 } 963 } 964 } 965 | Popular Tags |