1 3 package org.python.compiler; 4 5 import org.python.parser.*; 6 import org.python.parser.ast.*; 7 import org.python.parser.ast.Attribute; 8 import org.python.core.CompilerFlags; 9 import org.python.core.Py; 10 import org.python.core.PyObject; 11 import org.python.core.PyInteger; 12 import org.python.core.PyFloat; 13 import org.python.core.PyLong; 14 import org.python.core.PyComplex; 15 import org.python.core.PyException; 16 import java.io.IOException ; 17 import java.util.Stack ; 18 import java.util.Hashtable ; 19 import java.util.Vector ; 20 21 public class CodeCompiler extends Visitor 22 implements ClassConstants { 24 25 public static final Object Exit=new Integer (1); 26 public static final Object NoExit=null; 27 28 public static final int GET=0; 29 public static final int SET=1; 30 public static final int DEL=2; 31 public static final int AUGGET=3; 32 public static final int AUGSET=4; 33 34 public Module module; 35 public Code code; 36 public ConstantPool pool; 37 public CodeCompiler mrefs; 38 public CompilerFlags cflags; 39 40 int temporary; 41 int augmode; 42 int augtmp1; 43 int augtmp2; 44 int augtmp3; 45 int augtmp4; 46 47 public boolean fast_locals, print_results; 48 49 public Hashtable tbl; 50 public ScopeInfo my_scope; 51 52 boolean optimizeGlobals = true; 53 public Vector names; 54 public String className; 55 56 public Stack continueLabels, breakLabels, finallyLabels; 57 public Stack inFinallyLabels; 58 public Vector yields = new Vector (); 59 60 68 public int bcfLevel = 0; 69 70 public CodeCompiler(Module module, boolean print_results) { 71 this.module = module; 72 mrefs = this; 73 pool = module.classfile.pool; 74 75 continueLabels = new Stack (); 76 breakLabels = new Stack (); 77 finallyLabels = new Stack (); 78 inFinallyLabels = new Stack (); 79 this.print_results = print_results; 80 } 81 82 public int PyNone; 83 public void getNone() throws IOException { 84 if (mrefs.PyNone == 0) { 85 mrefs.PyNone = pool.Fieldref("org/python/core/Py", "None", 86 $pyObj); 87 } 88 code.getstatic(mrefs.PyNone); 89 } 90 91 public void loadFrame() throws Exception { 92 code.aload(1); 93 } 94 95 96 int f_lasti; 97 98 public void setLastI(int idx) throws Exception { 99 if (mrefs.f_lasti == 0) { 100 mrefs.f_lasti = code.pool.Fieldref( 101 "org/python/core/PyFrame", "f_lasti", "I"); 102 } 103 loadFrame(); 104 code.iconst(idx); 105 code.putfield(mrefs.f_lasti); 106 } 107 108 public int storeTop() throws Exception { 109 int tmp = code.getLocal("org/python/core/PyObject"); 110 code.astore(tmp); 111 return tmp; 112 } 113 114 public int setline; 115 public void setline(int line) throws Exception { 116 if (module.linenumbers) { 118 code.setline(line); 119 loadFrame(); 120 code.iconst(line); 121 if (mrefs.setline == 0) { 122 mrefs.setline = pool.Methodref("org/python/core/PyFrame", 123 "setline", "(I)V"); 124 } 125 code.invokevirtual(mrefs.setline); 126 } 127 } 128 129 public void setline(SimpleNode node) throws Exception { 130 setline(node.beginLine); 131 } 132 133 public void set(SimpleNode node) throws Exception { 134 int tmp = storeTop(); 135 set(node, tmp); 136 code.aconst_null(); 137 code.astore(tmp); 138 code.freeLocal(tmp); 139 } 140 141 142 boolean inSet = false; 143 public void set(SimpleNode node, int tmp) throws Exception { 144 if (inSet) { 146 System.out.println("recurse set: "+tmp+", "+temporary); 147 } 148 temporary = tmp; 149 visit(node); 150 } 151 152 153 private void saveAugTmps(SimpleNode node, int count) throws Exception { 154 if (count >= 4) { 155 augtmp4 = code.getLocal("org/python/core/PyObject"); 156 code.astore(augtmp4); 157 } 158 if (count >= 3) { 159 augtmp3 = code.getLocal("org/python/core/PyObject"); 160 code.astore(augtmp3); 161 } 162 if (count >= 2) { 163 augtmp2 = code.getLocal("org/python/core/PyObject"); 164 code.astore(augtmp2); 165 } 166 augtmp1 = code.getLocal("org/python/core/PyObject"); 167 code.astore(augtmp1); 168 169 code.aload(augtmp1); 170 if (count >= 2) 171 code.aload(augtmp2); 172 if (count >= 3) 173 code.aload(augtmp3); 174 if (count >= 4) 175 code.aload(augtmp4); 176 } 177 178 179 private void restoreAugTmps(SimpleNode node, int count) throws Exception { 180 code.aload(augtmp1); 181 code.freeLocal(augtmp1); 182 if (count == 1) 183 return; 184 code.aload(augtmp2); 185 code.freeLocal(augtmp2); 186 if (count == 2) 187 return; 188 code.aload(augtmp3); 189 code.freeLocal(augtmp3); 190 if (count == 3) 191 return; 192 code.aload(augtmp4); 193 code.freeLocal(augtmp4); 194 } 195 196 197 public void parse(modType node, Code code, 198 boolean fast_locals, String className, 199 boolean classBody, ScopeInfo scope, CompilerFlags cflags) 200 throws Exception 201 { 202 this.fast_locals = fast_locals; 203 this.className = className; 204 this.code = code; 205 this.cflags = cflags; 206 207 my_scope = scope; 208 names = scope.names; 209 210 tbl = scope.tbl; 211 optimizeGlobals = fast_locals&&!scope.exec&&!scope.from_import_star; 212 213 Object exit = visit(node); 214 216 if (classBody) { 217 loadFrame(); 218 code.invokevirtual("org/python/core/PyFrame", "getf_locals", 219 "()" + $pyObj); 220 code.areturn(); 221 } else { 222 if (exit == null) { 223 setLastI(-1); 225 226 getNone(); 227 code.areturn(); 228 } 229 } 230 } 231 232 public Object visitInteractive(Interactive node) throws Exception { 233 traverse(node); 234 return null; 235 } 236 237 public Object visitModule(org.python.parser.ast.Module suite) 238 throws Exception 239 { 240 if (mrefs.setglobal == 0) { 241 mrefs.setglobal = code.pool.Methodref( 242 "org/python/core/PyFrame", "setglobal", 243 "(" +$str + $pyObj + ")V"); 244 } 245 246 if (suite.body.length > 0 && 247 suite.body[0] instanceof Expr && 248 ((Expr)suite.body[0]).value instanceof Str) 249 { 250 loadFrame(); 251 code.ldc("__doc__"); 252 visit(((Expr) suite.body[0]).value); 253 code.invokevirtual(mrefs.setglobal); 254 } 255 if (module.setFile) { 256 loadFrame(); 257 code.ldc("__file__"); 258 module.filename.get(code); 259 code.invokevirtual(mrefs.setglobal); 260 } 261 traverse(suite); 262 return null; 263 } 264 265 public Object visitExpression(Expression node) throws Exception { 266 if (my_scope.generator && node.body != null) { 267 module.error("'return' with argument inside generator", 268 true, node); 269 } 270 return visitReturn(new Return(node.body, node), true); 271 } 272 273 public int EmptyObjects; 274 public void makeArray(SimpleNode[] nodes) throws Exception { 275 int n; 276 277 if (nodes == null) 278 n = 0; 279 else 280 n = nodes.length; 281 282 if (n == 0) { 283 if (mrefs.EmptyObjects == 0) { 284 mrefs.EmptyObjects = code.pool.Fieldref( 285 "org/python/core/Py", "EmptyObjects", $pyObjArr); 286 } 287 code.getstatic(mrefs.EmptyObjects); 288 } else { 289 int tmp = code.getLocal("[org/python/core/PyObject"); 290 code.iconst(n); 291 code.anewarray(code.pool.Class("org/python/core/PyObject")); 292 code.astore(tmp); 293 294 for(int i=0; i<n; i++) { 295 code.aload(tmp); 296 code.iconst(i); 297 visit(nodes[i]); 298 code.aastore(); 299 } 300 code.aload(tmp); 301 code.freeLocal(tmp); 302 } 303 } 304 305 public void getDocString(stmtType[] suite) throws Exception { 306 if (suite.length > 0 && suite[0] instanceof Expr && 308 ((Expr) suite[0]).value instanceof Str) 309 { 310 visit(((Expr) suite[0]).value); 311 } else { 312 code.aconst_null(); 313 } 314 } 315 316 int getclosure; 317 318 public boolean makeClosure(Vector freenames) throws Exception { 319 if (freenames == null) return false; 320 int n = freenames.size(); 321 if (n == 0) return false; 322 323 if (mrefs.getclosure == 0) { 324 mrefs.getclosure = code.pool.Methodref( 325 "org/python/core/PyFrame", "getclosure", "(I)" + $pyObj); 326 } 327 328 int tmp = code.getLocal("[org/python/core/PyObject"); 329 code.iconst(n); 330 code.anewarray(code.pool.Class("org/python/core/PyObject")); 331 code.astore(tmp); 332 333 for(int i=0; i<n; i++) { 334 code.aload(tmp); 335 code.iconst(i); 336 code.aload(1); code.iconst(((SymInfo)tbl.get(freenames.elementAt(i))).env_index); 338 code.invokevirtual(getclosure); 339 code.aastore(); 340 } 341 342 code.aload(tmp); 343 code.freeLocal(tmp); 344 345 return true; 346 } 347 348 349 350 int f_globals, PyFunction_init, PyFunction_closure_init; 351 352 public Object visitFunctionDef(FunctionDef node) throws Exception { 353 String name = getName(node.name); 354 355 setline(node); 356 357 code.new_(code.pool.Class("org/python/core/PyFunction")); 358 code.dup(); 359 loadFrame(); 360 if (mrefs.f_globals == 0) { 361 mrefs.f_globals = code.pool.Fieldref( 362 "org/python/core/PyFrame", "f_globals", $pyObj); 363 } 364 code.getfield(mrefs.f_globals); 365 366 ScopeInfo scope = module.getScopeInfo(node); 367 368 makeArray(scope.ac.getDefaults()); 369 370 scope.setup_closure(my_scope); 371 scope.dump(); 372 module.PyCode(new Suite(node.body, node), name, true, 373 className, false, false, 374 node.beginLine, scope, cflags).get(code); 375 Vector freenames = scope.freevars; 376 377 getDocString(node.body); 378 379 if (!makeClosure(freenames)) { 380 if (mrefs.PyFunction_init == 0) { 381 mrefs.PyFunction_init = code.pool.Methodref( 382 "org/python/core/PyFunction", "<init>", 383 "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + ")V"); 384 } 385 code.invokespecial(mrefs.PyFunction_init); 386 } else { 387 if (mrefs.PyFunction_closure_init == 0) { 388 mrefs.PyFunction_closure_init = code.pool.Methodref( 389 "org/python/core/PyFunction", "<init>", 390 "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + $pyObjArr + 391 ")V"); 392 } 393 code.invokespecial(mrefs.PyFunction_closure_init); 394 395 } 396 397 set(new Name(node.name, Name.Store, node)); 398 return null; 399 } 400 401 public int printResult; 402 403 public Object visitExpr(Expr node) throws Exception { 404 setline(node); 405 visit(node.value); 406 407 if (print_results) { 408 if (mrefs.printResult == 0) { 409 mrefs.printResult = code.pool.Methodref( 410 "org/python/core/Py", 411 "printResult", "(" + $pyObj + ")V"); 412 } 413 code.invokestatic(mrefs.printResult); 414 } else { 415 code.pop(); 416 } 417 return null; 418 } 419 420 public Object visitAssign(Assign node) throws Exception { 421 setline(node); 422 visit(node.value); 423 if (node.targets.length == 1) { 424 set(node.targets[0]); 425 return null; 426 } 427 int tmp = storeTop(); 428 for (int i=node.targets.length-1; i>=0; i--) { 429 set(node.targets[i], tmp); 430 } 431 code.freeLocal(tmp); 432 return null; 433 } 434 435 public int print1, print2, print3, print4, print5, print6; 436 437 public Object visitPrint(Print node) throws Exception { 438 setline(node); 439 int tmp = -1; 440 int printcomma, printlnv, println; 441 442 if (node.dest != null) { 443 visit(node.dest); 444 tmp = storeTop(); 445 if (mrefs.print4 == 0) { 446 mrefs.print4 = pool.Methodref( 447 "org/python/core/Py", "printComma", 448 "(" + $pyObj + $pyObj + ")V"); 449 } 450 printcomma = mrefs.print4; 451 if (mrefs.print5 == 0) { 452 mrefs.print5 = pool.Methodref( 453 "org/python/core/Py", "println", 454 "(" + $pyObj + $pyObj + ")V"); 455 } 456 println = mrefs.print5; 457 if (mrefs.print6 == 0) { 458 mrefs.print6 = pool.Methodref( 459 "org/python/core/Py", "printlnv", 460 "(" + $pyObj + ")V"); 461 } 462 printlnv = mrefs.print6; 463 } 464 else { 465 if (mrefs.print1 == 0) { 466 mrefs.print1 = pool.Methodref( 467 "org/python/core/Py", "printComma", 468 "(" + $pyObj + ")V"); 469 } 470 printcomma = mrefs.print1; 471 if (mrefs.print2 == 0) { 472 mrefs.print2 = pool.Methodref( 473 "org/python/core/Py", "println", 474 "(" + $pyObj + ")V"); 475 } 476 println = mrefs.print2; 477 if (mrefs.print3 == 0) { 478 mrefs.print3 = pool.Methodref( 479 "org/python/core/Py", 480 "println", "()V"); 481 } 482 printlnv = mrefs.print3; 483 } 484 485 if (node.values == null || node.values.length == 0) { 486 if (node.dest != null) 487 code.aload(tmp); 488 code.invokestatic(printlnv); 489 } else { 490 for (int i = 0; i < node.values.length; i++) { 491 if (node.dest != null) 492 code.aload(tmp); 493 visit(node.values[i]); 494 if (node.nl && i == node.values.length - 1) { 495 code.invokestatic(println); 496 } else { 497 code.invokestatic(printcomma); 498 } 499 } 500 } 501 if (node.dest != null) 502 code.freeLocal(tmp); 503 return null; 504 } 505 506 public Object visitDelete(Delete node) throws Exception { 507 setline(node); 508 traverse(node); 509 return null; 510 } 511 512 public Object visitPass(Pass node) throws Exception { 513 setline(node); 514 return null; 515 } 516 517 public Object visitBreak(Break node) throws Exception { 518 if (breakLabels.empty()) { 520 throw new ParseException("'break' outside loop", node); 521 } 522 523 for (int i = finallyLabels.size() - 1; i >= bcfLevel; i--) { 524 doFinallyPart((InFinally)finallyLabels.elementAt(i)); 525 } 526 527 code.goto_((Label)breakLabels.peek()); 528 return null; 529 } 530 531 public Object visitContinue(Continue node) throws Exception { 532 if (continueLabels.empty()) { 534 throw new ParseException("'continue' not properly in loop", node); 535 } 536 537 for (int i = finallyLabels.size() - 1; i >= bcfLevel; i--) { 538 doFinallyPart((InFinally)finallyLabels.elementAt(i)); 539 } 540 code.goto_((Label)continueLabels.peek()); 541 return Exit; 542 } 543 544 int yield_count = 0; 545 546 int f_savedlocals; 547 548 public Object visitYield(Yield node) throws Exception { 549 550 setline(node); 551 if (!fast_locals) { 552 throw new ParseException("'yield' outside function", node); 553 } 554 555 if (!finallyLabels.empty()) { 556 throw new ParseException("'yield' not allowed in a 'try' "+ 557 "block with a 'finally' clause", node); 558 } 559 560 561 562 InFinally inFinally = null; 563 if (inFinallyLabels.size() > 0) 564 inFinally = (InFinally) inFinallyLabels.peek(); 565 566 567 if (inFinally == null) { 568 saveLocals(); 569 visit(node.value); 570 setLastI(++yield_count); 571 code.areturn(); 572 Label restart = code.getLabel(); 573 yields.addElement(restart); 574 restart.setPosition(); 575 restoreLocals(); 576 } else { 577 saveLocals(); 578 visit(node.value); 579 code.areturn(); 580 code.ret(inFinally.retLocal); 581 inFinally.labels[inFinally.cnt++].setPosition(); 582 code.stack = 1; 583 code.astore(inFinally.retLocal); 584 restoreLocals(); 585 } 586 return null; 587 } 588 589 private void restoreLocals() throws Exception { 590 Vector v = code.getActiveLocals(); 591 592 loadFrame(); 593 if (mrefs.f_savedlocals == 0) { 594 mrefs.f_savedlocals = code.pool.Fieldref( 595 "org/python/core/PyFrame", "f_savedlocals", 596 "[Ljava/lang/Object;"); 597 } 598 code.getfield(mrefs.f_savedlocals); 599 600 int locals = code.getLocal("[java/lang/Object"); 601 code.astore(locals); 602 603 for (int i = 0; i < v.size(); i++) { 604 String type = (String ) v.elementAt(i); 605 if (type == null) 606 continue; 607 code.aload(locals); 608 code.iconst(i); 609 code.aaload(); 610 code.checkcast(code.pool.Class(type)); 611 code.astore(i); 612 } 613 code.freeLocal(locals); 614 } 615 616 617 private void saveLocals() throws Exception { 618 Vector v = code.getActiveLocals(); 619 code.iconst(v.size()); 621 code.anewarray(code.pool.Class("java/lang/Object")); 623 int locals = code.getLocal("[java/lang/Object"); 624 code.astore(locals); 625 626 for (int i = 0; i < v.size(); i++) { 627 String type = (String ) v.elementAt(i); 628 if (type == null) 629 continue; 630 code.aload(locals); 631 code.iconst(i); 632 if (i == 2222) { 634 code.aconst_null(); 635 } else 636 code.aload(i); 637 code.aastore(); 638 } 639 640 if (mrefs.f_savedlocals == 0) { 641 mrefs.f_savedlocals = code.pool.Fieldref( 642 "org/python/core/PyFrame", "f_savedlocals", 643 "[Ljava/lang/Object;"); 644 } 645 646 loadFrame(); 647 code.aload(locals); 648 code.putfield(mrefs.f_savedlocals); 649 code.freeLocal(locals); 650 } 651 652 653 public Object visitReturn(Return node) throws Exception { 654 return visitReturn(node, false); 655 } 656 657 public Object visitReturn(Return node, boolean inEval) 658 throws Exception 659 { 660 setline(node); 661 if (!inEval && !fast_locals) { 662 throw new ParseException("'return' outside function", node); 663 } 664 int tmp = 0; 665 if (node.value != null) { 666 if (my_scope.generator) 667 throw new ParseException("'return' with argument " + 668 "inside generator", node); 669 visit(node.value); 670 tmp = code.getReturnLocal(); 671 code.astore(tmp); 672 } 673 for (int i = finallyLabels.size() - 1; i >= 0; i--) { 674 doFinallyPart((InFinally) finallyLabels.elementAt(i)); 675 } 676 setLastI(-1); 677 678 if (node.value != null) { 679 code.aload(tmp); 680 } else { 681 getNone(); 682 } 683 code.areturn(); 684 return Exit; 685 } 686 687 public int makeException0, makeException1, makeException2, makeException3; 688 689 public Object visitRaise(Raise node) throws Exception { 690 setline(node); 691 traverse(node); 692 if (node.type == null) { 693 if (mrefs.makeException0 == 0) { 694 mrefs.makeException0 = code.pool.Methodref( 695 "org/python/core/Py", "makeException", 696 "()" + $pyExc); 697 } 698 code.invokestatic(mrefs.makeException0); 699 } else if (node.inst == null) { 700 if (mrefs.makeException1 == 0) { 701 mrefs.makeException1 = code.pool.Methodref( 702 "org/python/core/Py", "makeException", 703 "(" + $pyObj + ")" + $pyExc); 704 } 705 code.invokestatic(mrefs.makeException1); 706 } else if (node.tback == null) { 707 if (mrefs.makeException2 == 0) { 708 mrefs.makeException2 = code.pool.Methodref( 709 "org/python/core/Py", "makeException", 710 "(" + $pyObj + $pyObj + ")" + $pyExc); 711 } 712 code.invokestatic(mrefs.makeException2); 713 } else { 714 if (mrefs.makeException3 == 0) { 715 mrefs.makeException3 = code.pool.Methodref( 716 "org/python/core/Py", "makeException", 717 "(" + $pyObj + $pyObj + $pyObj + ")" + $pyExc); 718 } 719 code.invokestatic(mrefs.makeException3); 720 } 721 code.athrow(); 722 return Exit; 723 } 724 725 public int importOne, importOneAs; 726 727 public Object visitImport(Import node) throws Exception { 728 setline(node); 729 for (int i = 0; i < node.names.length; i++) { 730 String asname = null; 731 if (node.names[i].asname != null) { 732 String name = node.names[i].name; 733 asname = node.names[i].asname; 734 code.ldc(name); 735 loadFrame(); 736 if (mrefs.importOneAs == 0) { 737 mrefs.importOneAs = code.pool.Methodref( 738 "org/python/core/imp", "importOneAs", 739 "(" + $str + $pyFrame + ")" + $pyObj); 740 } 741 code.invokestatic(mrefs.importOneAs); 742 } else { 743 String name = node.names[i].name; 744 asname = name; 745 if (asname.indexOf('.') > 0) 746 asname = asname.substring(0, asname.indexOf('.')); 747 code.ldc(name); 748 loadFrame(); 749 if (mrefs.importOne == 0) { 750 mrefs.importOne = code.pool.Methodref( 751 "org/python/core/imp", "importOne", 752 "(" + $str + $pyFrame + ")" + $pyObj); 753 } 754 code.invokestatic(mrefs.importOne); 755 } 756 set(new Name(asname, Name.Store, node)); 757 } 758 return null; 759 } 760 761 762 public int importAll, importFrom; 763 764 public Object visitImportFrom(ImportFrom node) throws Exception { 765 Future.checkFromFuture(node); setline(node); 767 code.ldc(node.module); 768 if (node.names.length > 0) { 769 String [] names = new String [node.names.length]; 770 String [] asnames = new String [node.names.length]; 771 for (int i = 0; i < node.names.length; i++) { 772 names[i] = node.names[i].name; 773 asnames[i] = node.names[i].asname; 774 if (asnames[i] == null) 775 asnames[i] = names[i]; 776 } 777 makeStrings(code, names, names.length); 778 779 loadFrame(); 780 if (mrefs.importFrom == 0) { 781 mrefs.importFrom = code.pool.Methodref( 782 "org/python/core/imp", "importFrom", 783 "(" + $str + $strArr + $pyFrame + ")" + $pyObjArr); 784 } 785 code.invokestatic(mrefs.importFrom); 786 int tmp = storeTop(); 787 for (int i = 0; i < node.names.length; i++) { 788 code.aload(tmp); 789 code.iconst(i); 790 code.aaload(); 791 set(new Name(asnames[i], Name.Store, node)); 792 } 793 code.freeLocal(tmp); 794 } else { 795 loadFrame(); 796 if (mrefs.importAll == 0) { 797 mrefs.importAll = code.pool.Methodref( 798 "org/python/core/imp", "importAll", 799 "(" + $str + $pyFrame + ")V"); 800 } 801 code.invokestatic(mrefs.importAll); 802 } 803 return null; 804 } 805 806 public Object visitGlobal(Global node) throws Exception { 807 return null; 808 } 809 810 public int exec; 811 public Object visitExec(Exec node) throws Exception { 812 setline(node); 813 visit(node.body); 814 815 if (node.globals != null) { 816 visit(node.globals); 817 } else { 818 code.aconst_null(); 819 } 820 821 if (node.locals != null) { 822 visit(node.locals); 823 } else { 824 code.aconst_null(); 825 } 826 827 if (mrefs.exec == 0) { 829 mrefs.exec = code.pool.Methodref( 830 "org/python/core/Py", "exec", 831 "(" + $pyObj + $pyObj + $pyObj + ")V"); 832 } 833 code.invokestatic(mrefs.exec); 834 return null; 835 } 836 837 public int assert1, assert2; 838 public Object visitAssert(Assert node) throws Exception { 839 setline(node); 840 Label end_of_assert = code.getLabel(); 841 842 843 loadFrame(); 844 emitGetGlobal("__debug__"); 845 846 if (mrefs.nonzero == 0) { 847 mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", 848 "__nonzero__", "()Z"); 849 } 850 code.invokevirtual(mrefs.nonzero); 851 852 code.ifeq(end_of_assert); 853 854 855 visit(node.test); 856 if (node.msg != null) { 857 visit(node.msg); 858 if (mrefs.assert2 == 0) { 859 mrefs.assert2 = code.pool.Methodref( 860 "org/python/core/Py", "assert_", 861 "(" + $pyObj + $pyObj + ")V"); 862 } 863 code.invokestatic(mrefs.assert2); 864 } else { 865 if (mrefs.assert1 == 0) { 866 mrefs.assert1 = code.pool.Methodref( 867 "org/python/core/Py", "assert_", 868 "(" + $pyObj + ")V"); 869 } 870 code.invokestatic(mrefs.assert1); 871 } 872 873 874 end_of_assert.setPosition(); 875 876 return null; 877 } 878 879 public int nonzero; 880 public Object doTest(Label end_of_if, If node, int index) 881 throws Exception 882 { 883 Label end_of_suite = code.getLabel(); 884 885 setline(node.test); 886 visit(node.test); 887 if (mrefs.nonzero == 0) { 888 mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", 889 "__nonzero__", "()Z"); 890 } 891 code.invokevirtual(mrefs.nonzero); 892 code.ifeq(end_of_suite); 893 894 Object exit = suite(node.body); 895 896 if (end_of_if != null && exit == null) 897 code.goto_(end_of_if); 898 899 end_of_suite.setPosition(); 900 901 if (node.orelse != null) { 902 return suite(node.orelse) != null ? exit : null; 903 } else { 904 return null; 905 } 906 } 907 908 public Object visitIf(If node) throws Exception { 909 Label end_of_if = null; 910 if (node.orelse != null) 911 end_of_if = code.getLabel(); 912 913 Object exit = doTest(end_of_if, node, 0); 914 if (end_of_if != null) 915 end_of_if.setPosition(); 916 return exit; 917 } 918 919 public int beginLoop() { 920 continueLabels.push(code.getLabel()); 921 breakLabels.push(code.getLabel()); 922 int savebcf = bcfLevel; 923 bcfLevel = finallyLabels.size(); 924 return savebcf; 925 } 926 927 public void finishLoop(int savebcf) { 928 continueLabels.pop(); 929 breakLabels.pop(); 930 bcfLevel = savebcf; 931 } 932 933 934 public Object visitWhile(While node) throws Exception { 935 int savebcf = beginLoop(); 936 Label continue_loop = (Label)continueLabels.peek(); 937 Label break_loop = (Label)breakLabels.peek(); 938 939 Label start_loop = code.getLabel(); 940 941 code.goto_(continue_loop); 942 start_loop.setPosition(); 943 944 suite(node.body); 946 947 continue_loop.setPosition(); 948 setline(node); 949 950 visit(node.test); 952 if (mrefs.nonzero == 0) { 953 mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", 954 "__nonzero__", "()Z"); 955 } 956 code.invokevirtual(mrefs.nonzero); 957 code.ifne(start_loop); 958 959 finishLoop(savebcf); 960 961 if (node.orelse != null) { 962 suite(node.orelse); 964 } 965 break_loop.setPosition(); 966 967 return null; 969 } 970 971 public int iter=0; 972 public int iternext=0; 973 974 public Object visitFor(For node) throws Exception { 975 int savebcf = beginLoop(); 976 Label continue_loop = (Label)continueLabels.peek(); 977 Label break_loop = (Label)breakLabels.peek(); 978 Label start_loop = code.getLabel(); 979 Label next_loop = code.getLabel(); 980 981 int iter_tmp = code.getLocal("org/python/core/PyObject"); 982 int expr_tmp = code.getLocal("org/python/core/PyObject"); 983 984 setline(node); 985 986 visit(node.iter); 988 989 if (mrefs.iter == 0) { 991 mrefs.iter = code.pool.Methodref( 992 "org/python/core/PyObject", 993 "__iter__", "()" + $pyObj); 994 } 995 code.invokevirtual(mrefs.iter); 996 code.astore(iter_tmp); 997 998 code.goto_(next_loop); 1000 1001 start_loop.setPosition(); 1002 set(node.target, expr_tmp); 1004 1005 suite(node.body); 1007 1008 continue_loop.setPosition(); 1009 1010 next_loop.setPosition(); 1011 setline(node); 1012 code.aload(iter_tmp); 1014 if (mrefs.iternext == 0) { 1015 mrefs.iternext = code.pool.Methodref( 1016 "org/python/core/PyObject", 1017 "__iternext__", "()" + $pyObj); 1018 } 1019 code.invokevirtual(mrefs.iternext); 1020 code.astore(expr_tmp); 1021 code.aload(expr_tmp); 1022 code.ifnonnull(start_loop); 1024 1025 finishLoop(savebcf); 1026 1027 if (node.orelse != null) { 1028 suite(node.orelse); 1030 } 1031 1032 break_loop.setPosition(); 1033 1034 code.freeLocal(iter_tmp); 1035 code.freeLocal(expr_tmp); 1036 1037 return null; 1039 } 1040 1041 public int match_exception; 1042 1043 public void exceptionTest(int exc, Label end_of_exceptions, 1044 TryExcept node, int index) 1045 throws Exception 1046 { 1047 for (int i = 0; i < node.handlers.length; i++) { 1048 excepthandlerType handler = node.handlers[i]; 1049 1050 Label end_of_self = code.getLabel(); 1052 1053 if (handler.type != null) { 1054 code.aload(exc); 1055 visit(handler.type); 1057 if (mrefs.match_exception == 0) { 1058 mrefs.match_exception = code.pool.Methodref( 1059 "org/python/core/Py", "matchException", 1060 "(" + $pyExc + $pyObj + ")Z"); 1061 } 1062 code.invokestatic(mrefs.match_exception); 1063 code.ifeq(end_of_self); 1064 } else { 1065 if (i != node.handlers.length-1) { 1066 throw new ParseException( 1067 "bare except must be last except clause", handler.type); 1068 } 1069 } 1070 1071 if (handler.name != null) { 1072 code.aload(exc); 1073 code.getfield(code.pool.Fieldref("org/python/core/PyException", 1074 "value", 1075 "Lorg/python/core/PyObject;")); 1076 set(handler.name); 1077 } 1078 1079 suite(handler.body); 1081 code.goto_(end_of_exceptions); 1082 end_of_self.setPosition(); 1083 } 1084 code.aload(exc); 1085 code.athrow(); 1086 } 1087 1088 public int add_traceback; 1089 public Object visitTryFinally(TryFinally node) throws Exception 1090 { 1091 Label start = code.getLabel(); 1092 Label end = code.getLabel(); 1093 Label handlerStart = code.getLabel(); 1094 Label finallyEnd = code.getLabel(); 1095 Label skipSuite = code.getLabel(); 1096 1097 Object ret; 1098 1099 int yieldCount = 0; 1101 if (my_scope.generator) { 1102 YieldChecker checker = new YieldChecker(); 1103 checker.visit(node.finalbody); 1104 yieldCount = checker.yieldCount; 1105 } 1106 if (yieldCount > 0) { 1107 throw new ParseException("'yield' in finally not yet supported", 1108 node); 1109 } 1110 1111 InFinally inFinally = new InFinally(yieldCount + 1); 1112 1113 finallyLabels.push(inFinally); 1114 1115 int excLocal = code.getLocal("java/lang/Throwable"); 1116 code.aconst_null(); 1117 code.astore(excLocal); 1118 1119 start.setPosition(); 1120 ret = suite(node.body); 1121 end.setPosition(); 1122 if (ret == null) { 1123 doFinallyPart(inFinally); 1124 code.goto_(finallyEnd); 1125 } 1126 1127 finallyLabels.pop(); 1128 1129 handlerStart.setPosition(); 1131 code.stack = 1; 1132 code.astore(excLocal); 1133 1134 code.aload(excLocal); 1135 loadFrame(); 1136 1137 if (mrefs.add_traceback == 0) { 1138 mrefs.add_traceback = code.pool.Methodref( 1139 "org/python/core/Py", "addTraceback", 1140 "(" + $throwable + $pyFrame + ")V"); 1141 } 1142 code.invokestatic(mrefs.add_traceback); 1143 1144 doFinallyPart(inFinally); 1145 code.aload(excLocal); 1146 code.checkcast(code.pool.Class("java/lang/Throwable")); 1147 code.athrow(); 1148 1149 inFinally.labels[0].setPosition(); 1151 code.stack = 1; 1152 inFinally.retLocal = code.getFinallyLocal("ret"); 1153 code.astore(inFinally.retLocal); 1154 1155 1160 inFinallyLabels.push(inFinally); 1161 1162 ret = suite(node.finalbody); 1164 1165 inFinallyLabels.pop(); 1166 1167 1170 code.ret(inFinally.retLocal); 1171 code.freeFinallyLocal(inFinally.retLocal); 1172 1173 finallyEnd.setPosition(); 1174 1175 code.freeLocal(excLocal); 1176 code.addExceptionHandler(start, end, handlerStart, 1177 code.pool.Class("java/lang/Throwable")); 1178 1179 return null; 1181 } 1182 1183 private void doFinallyPart(InFinally inFinally) throws Exception { 1184 if (inFinally.labels.length == 1) { 1185 code.jsr(inFinally.labels[0]); 1186 } else { 1187 Label endOfFinal = code.getLabel(); 1188 for (int i = 0; i < inFinally.labels.length; i++) { 1189 setLastI(++yield_count); 1190 code.jsr(inFinally.labels[i]); 1191 1192 if (i < inFinally.labels.length-1) { 1194 code.goto_(endOfFinal); 1195 Label restart = code.getLabel(); 1196 yields.addElement(restart); 1197 restart.setPosition(); 1198 } 1199 } 1200 endOfFinal.setPosition(); 1201 } 1202 } 1203 1204 class YieldChecker extends Visitor { 1205 public int yieldCount = 0; 1206 1207 public Object visitYield(Yield node) throws Exception { 1208 yieldCount++; 1209 return super.visitYield(node); 1210 } 1211 } 1212 1213 public int set_exception; 1214 public Object visitTryExcept(TryExcept node) throws Exception { 1215 Label start = code.getLabel(); 1216 Label end = code.getLabel(); 1217 Label handler_start = code.getLabel(); 1218 Label handler_end = code.getLabel(); 1219 1220 start.setPosition(); 1221 Object exit = suite(node.body); 1223 end.setPosition(); 1225 if (exit == null) 1226 code.goto_(handler_end); 1227 1228 handler_start.setPosition(); 1229 code.stack = 1; 1231 1232 loadFrame(); 1233 1234 if (mrefs.set_exception == 0) { 1235 mrefs.set_exception = code.pool.Methodref( 1236 "org/python/core/Py", "setException", 1237 "(" + $throwable + $pyFrame + ")" + $pyExc); 1238 } 1239 code.invokestatic(mrefs.set_exception); 1240 1241 int exc = code.getFinallyLocal("java/lang/Throwable"); 1242 code.astore(exc); 1243 1244 if (node.orelse == null) { 1245 exceptionTest(exc, handler_end, node, 1); 1247 handler_end.setPosition(); 1248 } else { 1249 Label else_end = code.getLabel(); 1251 exceptionTest(exc, else_end, node, 1); 1252 handler_end.setPosition(); 1253 1254 suite(node.orelse); 1256 else_end.setPosition(); 1257 } 1258 1259 code.freeFinallyLocal(exc); 1260 code.addExceptionHandler(start, end, handler_start, 1261 code.pool.Class("java/lang/Throwable")); 1262 return null; 1263 } 1264 1265 public Object visitSuite(Suite node) throws Exception { 1266 return suite(node.body); 1267 } 1268 1269 public Object suite(stmtType[] stmts) throws Exception { 1270 int n = stmts.length; 1271 for(int i = 0; i < n; i++) { 1272 Object exit = visit(stmts[i]); 1273 if (exit != null) 1275 return Exit; 1276 } 1277 return null; 1278 } 1279 1280 public Object visitBoolOp(BoolOp node) throws Exception { 1281 Label end = code.getLabel(); 1282 visit(node.values[0]); 1283 for (int i = 1; i < node.values.length; i++) { 1284 code.dup(); 1285 if (mrefs.nonzero == 0) { 1286 mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", 1287 "__nonzero__", "()Z"); 1288 } 1289 code.invokevirtual(mrefs.nonzero); 1290 switch (node.op) { 1291 case BoolOp.Or : 1292 code.ifne(end); 1293 break; 1294 case BoolOp.And : 1295 code.ifeq(end); 1296 break; 1297 } 1298 code.pop(); 1299 visit(node.values[i]); 1300 } 1301 end.setPosition(); 1302 return null; 1303 } 1304 1305 1306 public Object visitCompare(Compare node) throws Exception { 1307 int tmp1 = code.getLocal("org/python/core/PyObject"); 1308 int tmp2 = code.getLocal("org/python/core/PyObject"); 1309 int op; 1310 1311 if (mrefs.nonzero == 0) { 1312 mrefs.nonzero = code.pool.Methodref("org/python/core/PyObject", 1313 "__nonzero__", "()Z"); 1314 } 1315 1316 Label end = code.getLabel(); 1317 1318 visit(node.left); 1319 1320 int n = node.ops.length; 1321 for(int i = 0; i < n - 1; i++) { 1322 visit(node.comparators[i]); 1323 code.dup(); 1324 code.astore(tmp1); 1325 code.invokevirtual(make_cmpop(node.ops[i])); 1326 code.dup(); 1327 code.astore(tmp2); 1328 code.invokevirtual(mrefs.nonzero); 1329 code.ifeq(end); 1330 code.aload(tmp1); 1331 } 1332 1333 visit(node.comparators[n-1]); 1334 code.invokevirtual(make_cmpop(node.ops[n-1])); 1335 1336 if (n > 1) { 1337 code.astore(tmp2); 1338 end.setPosition(); 1339 code.aload(tmp2); 1340 } 1341 code.freeLocal(tmp1); 1342 code.freeLocal(tmp2); 1343 return null; 1344 } 1345 1346 int[] compare_ops = new int[11]; 1347 public int make_cmpop(int op) throws Exception { 1348 if (compare_ops[op] == 0) { 1349 String name = null; 1350 switch (op) { 1351 case Compare.Eq: name = "_eq"; break; 1352 case Compare.NotEq: name = "_ne"; break; 1353 case Compare.Lt: name = "_lt"; break; 1354 case Compare.LtE: name = "_le"; break; 1355 case Compare.Gt: name = "_gt"; break; 1356 case Compare.GtE: name = "_ge"; break; 1357 case Compare.Is: name = "_is"; break; 1358 case Compare.IsNot: name = "_isnot"; break; 1359 case Compare.In: name = "_in"; break; 1360 case Compare.NotIn: name = "_notin"; break; 1361 } 1362 compare_ops[op] = code.pool.Methodref( 1363 "org/python/core/PyObject", name, 1364 "(" + $pyObj + ")" + $pyObj); 1365 } 1366 return compare_ops[op]; 1367 } 1368 1369 static String [] bin_methods = new String [] { 1370 null, 1371 "_add", 1372 "_sub", 1373 "_mul", 1374 "_div", 1375 "_mod", 1376 "_pow", 1377 "_lshift", 1378 "_rshift", 1379 "_or", 1380 "_xor", 1381 "_and", 1382 "_floordiv", 1383 }; 1384 1385 int[] bin_ops = new int[13]; 1386 public int make_binop(int op) throws Exception { 1387 if (bin_ops[op] == 0) { 1388 String name = bin_methods[op]; 1389 if (op == BinOp.Div && module.getFutures().areDivisionOn()) { 1390 name = "_truediv"; 1391 } 1392 bin_ops[op] = code.pool.Methodref( 1393 "org/python/core/PyObject", name, 1394 "(" + $pyObj + ")" + $pyObj); 1395 } 1396 return bin_ops[op]; 1397 } 1398 1399 public Object visitBinOp(BinOp node) throws Exception { 1400 visit(node.left); 1401 visit(node.right); 1402 code.invokevirtual(make_binop(node.op)); 1403 return null; 1404 } 1405 1406 1407 static String [] unary_methods = new String [] { 1408 null, 1409 "__invert__", 1410 "__not__", 1411 "__pos__", 1412 "__neg__", 1413 }; 1414 1415 int[] unary_ops = new int[unary_methods.length]; 1416 public int make_unaryop(int op) throws Exception { 1417 if (unary_ops[op] == 0) { 1418 String name = unary_methods[op]; 1419 unary_ops[op] = code.pool.Methodref( 1420 "org/python/core/PyObject", name, "()" + $pyObj); 1421 } 1422 return unary_ops[op]; 1423 } 1424 1425 public Object visitUnaryOp(UnaryOp node) throws Exception { 1426 visit(node.operand); 1427 code.invokevirtual(make_unaryop(node.op)); 1428 return null; 1429 } 1430 1431 1432 static String [] aug_methods = new String [] { 1433 null, 1434 "__iadd__", 1435 "__isub__", 1436 "__imul__", 1437 "__idiv__", 1438 "__imod__", 1439 "__ipow__", 1440 "__ilshift__", 1441 "__irshift__", 1442 "__ior__", 1443 "__ixor__", 1444 "__iand__", 1445 "__ifloordiv__", 1446 }; 1447 1448 int[] augbin_ops = new int[aug_methods.length]; 1449 public int make_augbinop(int op) throws Exception { 1450 if (augbin_ops[op] == 0) { 1451 String name = aug_methods[op]; 1452 if (op == BinOp.Div && module.getFutures().areDivisionOn()) { 1453 name = "__itruediv__"; 1454 } 1455 augbin_ops[op] = code.pool.Methodref( 1456 "org/python/core/PyObject", name, 1457 "(" + $pyObj + ")" + $pyObj); 1458 } 1459 return augbin_ops[op]; 1460 } 1461 1462 public Object visitAugAssign(AugAssign node) throws Exception { 1463 visit(node.value); 1464 int tmp = storeTop(); 1465 1466 augmode = expr_contextType.Load; 1467 visit(node.target); 1468 1469 code.aload(tmp); 1470 code.invokevirtual(make_augbinop(node.op)); 1471 code.freeLocal(tmp); 1472 1473 temporary = storeTop(); 1474 augmode = expr_contextType.Store; 1475 visit(node.target); 1476 code.freeLocal(temporary); 1477 1478 return null; 1479 } 1480 1481 1482 public static void makeStrings(Code c, String [] names, int n) 1483 throws IOException 1484 { 1485 c.iconst(n); 1486 c.anewarray(c.pool.Class("java/lang/String")); 1487 int strings = c.getLocal("[java/lang/String"); 1488 c.astore(strings); 1489 for (int i=0; i<n; i++) { 1490 c.aload(strings); 1491 c.iconst(i); 1492 c.ldc(names[i]); 1493 c.aastore(); 1494 } 1495 c.aload(strings); 1496 c.freeLocal(strings); 1497 } 1498 1499 public int invokea0, invokea1, invokea2; 1500 public int invoke2; 1501 public Object Invoke(Attribute node, SimpleNode[] values) 1502 throws Exception 1503 { 1504 String name = getName(node.attr); 1505 visit(node.value); 1506 code.ldc(name); 1507 1508 1510 switch (values.length) { 1511 case 0: 1512 if (mrefs.invokea0 == 0) { 1513 mrefs.invokea0 = code.pool.Methodref( 1514 "org/python/core/PyObject", "invoke", 1515 "(" + $str + ")" + $pyObj); 1516 } 1517 code.invokevirtual(mrefs.invokea0); 1518 break; 1519 case 1: 1520 if (mrefs.invokea1 == 0) { 1521 mrefs.invokea1 = code.pool.Methodref( 1522 "org/python/core/PyObject", "invoke", 1523 "(" + $str + $pyObj + ")" + $pyObj); 1524 } 1525 visit(values[0]); 1526 code.invokevirtual(mrefs.invokea1); 1527 break; 1528 case 2: 1529 if (mrefs.invokea2 == 0) { 1530 mrefs.invokea2 = code.pool.Methodref( 1531 "org/python/core/PyObject", "invoke", 1532 "(" + $str + $pyObj + $pyObj + ")" + $pyObj); 1533 } 1534 visit(values[0]); 1535 visit(values[1]); 1536 code.invokevirtual(mrefs.invokea2); 1537 break; 1538 default: 1539 makeArray(values); 1540 if (mrefs.invoke2 == 0) { 1541 mrefs.invoke2 = code.pool.Methodref( 1542 "org/python/core/PyObject", "invoke", 1543 "(" + $str + $pyObjArr + ")" + $pyObj); 1544 } 1545 code.invokevirtual(mrefs.invoke2); 1546 break; 1547 } 1548 1549 return null; 1550 } 1551 1552 1553 public int callextra; 1554 public int call1, call2; 1555 public int calla0, calla1, calla2, calla3, calla4; 1556 public Object visitCall(Call node) throws Exception { 1557 String [] keys = new String [node.keywords.length]; 1558 exprType[] values = new exprType[node.args.length + keys.length]; 1559 for (int i = 0; i < node.args.length; i++) { 1560 values[i] = node.args[i]; 1561 } 1562 for (int i = 0; i < node.keywords.length; i++) { 1563 keys[i] = node.keywords[i].arg; 1564 values[node.args.length + i] = node.keywords[i].value; 1565 } 1566 1567 if (node.keywords == null && node.starargs == null && 1569 node.kwargs == null && node.func instanceof Attribute) 1570 { 1571 return Invoke((Attribute) node.func, values); 1572 } 1573 1574 visit(node.func); 1575 1576 if (node.starargs != null || node.kwargs != null) { 1577 makeArray(values); 1578 makeStrings(code, keys, keys.length); 1579 if (node.starargs == null) 1580 code.aconst_null(); 1581 else 1582 visit(node.starargs); 1583 if (node.kwargs == null) 1584 code.aconst_null(); 1585 else 1586 visit(node.kwargs); 1587 1588 if (mrefs.callextra == 0) { 1589 mrefs.callextra = code.pool.Methodref( 1590 "org/python/core/PyObject", "_callextra", 1591 "(" + $pyObjArr + $strArr + $pyObj + $pyObj + ")" + 1592 $pyObj); 1593 } 1594 code.invokevirtual(mrefs.callextra); 1595 } else if (keys.length > 0) { 1596 makeArray(values); 1597 makeStrings(code, keys, keys.length); 1598 1599 if (mrefs.call1 == 0) { 1600 mrefs.call1 = code.pool.Methodref( 1601 "org/python/core/PyObject", "__call__", 1602 "(" + $pyObjArr + $strArr + ")" + $pyObj); 1603 } 1604 code.invokevirtual(mrefs.call1); 1605 } else { 1606 switch (values.length) { 1607 case 0: 1608 if (mrefs.calla0 == 0) { 1609 mrefs.calla0 = code.pool.Methodref( 1610 "org/python/core/PyObject", "__call__", 1611 "()" + $pyObj); 1612 } 1613 code.invokevirtual(mrefs.calla0); 1614 break; 1615 case 1: 1616 if (mrefs.calla1 == 0) { 1617 mrefs.calla1 = code.pool.Methodref( 1618 "org/python/core/PyObject", "__call__", 1619 "(" + $pyObj + ")" + $pyObj); 1620 } 1621 visit(values[0]); 1622 code.invokevirtual(mrefs.calla1); 1623 break; 1624 case 2: 1625 if (mrefs.calla2 == 0) { 1626 mrefs.calla2 = code.pool.Methodref( 1627 "org/python/core/PyObject", "__call__", 1628 "(" + $pyObj + $pyObj + ")" + $pyObj); 1629 } 1630 visit(values[0]); 1631 visit(values[1]); 1632 code.invokevirtual(mrefs.calla2); 1633 break; 1634 case 3: 1635 if (mrefs.calla3 == 0) { 1636 mrefs.calla3 = code.pool.Methodref( 1637 "org/python/core/PyObject", "__call__", 1638 "(" + $pyObj + $pyObj + $pyObj + ")" + $pyObj); 1639 } 1640 visit(values[0]); 1641 visit(values[1]); 1642 visit(values[2]); 1643 code.invokevirtual(mrefs.calla3); 1644 break; 1645 case 4: 1646 if (mrefs.calla4 == 0) { 1647 mrefs.calla4 = code.pool.Methodref( 1648 "org/python/core/PyObject", "__call__", 1649 "(" + $pyObj + $pyObj + $pyObj + $pyObj + ")" + 1650 $pyObj); 1651 } 1652 visit(values[0]); 1653 visit(values[1]); 1654 visit(values[2]); 1655 visit(values[3]); 1656 code.invokevirtual(mrefs.calla4); 1657 break; 1658 default: 1659 makeArray(values); 1660 if (mrefs.call2 == 0) { 1661 mrefs.call2 = code.pool.Methodref( 1662 "org/python/core/PyObject", "__call__", 1663 "(" + $pyObjArr + ")" + $pyObj); 1664 } 1665 code.invokevirtual(mrefs.call2); 1666 break; 1667 } 1668 } 1669 return null; 1670 } 1671 1672 1673 public int getslice, setslice, delslice; 1674 public Object Slice(Subscript node, Slice slice) throws Exception { 1675 int ctx = node.ctx; 1676 if (ctx == node.AugStore && augmode == node.Store) { 1677 restoreAugTmps(node, 4); 1678 ctx = node.Store; 1679 } else { 1680 visit(node.value); 1681 if (slice.lower != null) 1682 visit(slice.lower); 1683 else 1684 code.aconst_null(); 1685 if (slice.upper != null) 1686 visit(slice.upper); 1687 else 1688 code.aconst_null(); 1689 if (slice.step != null) 1690 visit(slice.step); 1691 else 1692 code.aconst_null(); 1693 1694 if (node.ctx == node.AugStore && augmode == node.Load) { 1695 saveAugTmps(node, 4); 1696 ctx = node.Load; 1697 } 1698 } 1699 1700 switch (ctx) { 1701 case Subscript.Del: 1702 if (mrefs.delslice == 0) { 1703 mrefs.delslice = code.pool.Methodref( 1704 "org/python/core/PyObject", "__delslice__", 1705 "(" + $pyObj + $pyObj + $pyObj + ")V"); 1706 } 1707 code.invokevirtual(mrefs.delslice); 1708 return null; 1709 case Subscript.Load: 1710 if (mrefs.getslice == 0) { 1711 mrefs.getslice = code.pool.Methodref( 1712 "org/python/core/PyObject", "__getslice__", 1713 "(" + $pyObj + $pyObj + $pyObj + ")" + $pyObj); 1714 } 1715 code.invokevirtual(mrefs.getslice); 1716 return null; 1717 case Subscript.Store: 1718 code.aload(temporary); 1719 if (mrefs.setslice == 0) { 1720 mrefs.setslice = code.pool.Methodref( 1721 "org/python/core/PyObject", "__setslice__", 1722 "(" + $pyObj + $pyObj + $pyObj + $pyObj + ")V"); 1723 } 1724 code.invokevirtual(mrefs.setslice); 1725 return null; 1726 } 1727 return null; 1728 1729 } 1730 1731 public int getitem, delitem, setitem; 1732 public Object visitSubscript(Subscript node) throws Exception { 1733 if (node.slice instanceof Slice) { 1734 return Slice(node, (Slice) node.slice); 1735 } 1736 1737 int ctx = node.ctx; 1738 if (node.ctx == node.AugStore && augmode == node.Store) { 1739 restoreAugTmps(node, 2); 1740 ctx = node.Store; 1741 } else { 1742 visit(node.value); 1743 visit(node.slice); 1744 1745 if (node.ctx == node.AugStore && augmode == node.Load) { 1746 saveAugTmps(node, 2); 1747 ctx = node.Load; 1748 } 1749 } 1750 1751 switch (ctx) { 1752 case Subscript.Del: 1753 if (mrefs.delitem == 0) { 1754 mrefs.delitem = code.pool.Methodref( 1755 "org/python/core/PyObject", "__delitem__", 1756 "(" + $pyObj + ")V"); 1757 } 1758 code.invokevirtual(mrefs.delitem); 1759 return null; 1760 case Subscript.Load: 1761 if (mrefs.getitem == 0) { 1762 mrefs.getitem = code.pool.Methodref( 1763 "org/python/core/PyObject", "__getitem__", 1764 "(" + $pyObj + ")" + $pyObj); 1765 } 1766 code.invokevirtual(mrefs.getitem); 1767 return null; 1768 case Subscript.Store: 1769 code.aload(temporary); 1770 if (mrefs.setitem == 0) { 1771 mrefs.setitem = code.pool.Methodref( 1772 "org/python/core/PyObject", "__setitem__", 1773 "(" + $pyObj + $pyObj + ")V"); 1774 } 1775 code.invokevirtual(mrefs.setitem); 1776 return null; 1777 } 1778 return null; 1779 } 1780 1781 public Object visitIndex(Index node) throws Exception { 1782 traverse(node); 1783 return null; 1784 } 1785 1786 public Object visitExtSlice(ExtSlice node) throws Exception { 1787 code.new_(code.pool.Class("org/python/core/PyTuple")); 1788 code.dup(); 1789 makeArray(node.dims); 1790 if (mrefs.PyTuple_init == 0) { 1791 mrefs.PyTuple_init = code.pool.Methodref( 1792 "org/python/core/PyTuple", "<init>", 1793 "(" + $pyObjArr + ")V"); 1794 } 1795 code.invokespecial(mrefs.PyTuple_init); 1796 return null; 1797 } 1798 1799 public int getattr, delattr, setattr; 1800 public Object visitAttribute(Attribute node) throws Exception { 1801 1802 int ctx = node.ctx; 1803 if (node.ctx == node.AugStore && augmode == node.Store) { 1804 restoreAugTmps(node, 2); 1805 ctx = node.Store; 1806 } else { 1807 visit(node.value); 1808 code.ldc(getName(node.attr)); 1809 1810 if (node.ctx == node.AugStore && augmode == node.Load) { 1811 saveAugTmps(node, 2); 1812 ctx = node.Load; 1813 } 1814 } 1815 1816 switch (ctx) { 1817 case Attribute.Del: 1818 if (mrefs.delattr == 0) { 1819 mrefs.delattr = code.pool.Methodref( 1820 "org/python/core/PyObject", "__delattr__", 1821 "(" + $str + ")V"); 1822 } 1823 code.invokevirtual(mrefs.delattr); 1824 return null; 1825 case Attribute.Load: 1826 if (mrefs.getattr == 0) { 1827 mrefs.getattr = code.pool.Methodref( 1828 "org/python/core/PyObject", "__getattr__", 1829 "(" + $str + ")" + $pyObj); 1830 } 1831 code.invokevirtual(mrefs.getattr); 1832 return null; 1833 case Attribute.Store: 1834 code.aload(temporary); 1835 if (mrefs.setattr == 0) { 1836 mrefs.setattr = code.pool.Methodref( 1837 "org/python/core/PyObject", "__setattr__", 1838 "(" + $str + $pyObj + ")V"); 1839 } 1840 code.invokevirtual(mrefs.setattr); 1841 return null; 1842 } 1843 return null; 1844 } 1845 1846 public int getitem2, unpackSequence; 1847 public Object seqSet(exprType[] nodes) throws Exception { 1848 if (mrefs.unpackSequence == 0) { 1849 mrefs.unpackSequence = code.pool.Methodref( 1850 "org/python/core/Py", 1851 "unpackSequence", 1852 "(" + $pyObj + "I)" + $pyObjArr); 1853 } 1854 1855 code.aload(temporary); 1856 code.iconst(nodes.length); 1857 code.invokestatic(mrefs.unpackSequence); 1858 1859 int tmp = code.getLocal("[org/python/core/PyObject"); 1860 code.astore(tmp); 1861 1862 for (int i = 0; i < nodes.length; i++) { 1863 code.aload(tmp); 1864 code.iconst(i); 1865 code.aaload(); 1866 set(nodes[i]); 1867 } 1868 code.freeLocal(tmp); 1869 1870 return null; 1871 } 1872 1873 public Object seqDel(exprType[] nodes) throws Exception { 1874 for (int i = 0; i < nodes.length; i++) { 1875 visit(nodes[i]); 1876 } 1877 return null; 1878 } 1879 1880 public int PyTuple_init, PyList_init, PyDictionary_init; 1881 public Object visitTuple(Tuple node) throws Exception { 1882 1885 if (node.ctx == node.Store) return seqSet(node.elts); 1886 if (node.ctx == node.Del) return seqDel(node.elts); 1887 1888 code.new_(code.pool.Class("org/python/core/PyTuple")); 1889 code.dup(); 1890 makeArray(node.elts); 1891 if (mrefs.PyTuple_init == 0) { 1892 mrefs.PyTuple_init = code.pool.Methodref( 1893 "org/python/core/PyTuple", "<init>", 1894 "(" + $pyObjArr + ")V"); 1895 } 1896 code.invokespecial(mrefs.PyTuple_init); 1897 return null; 1898 } 1899 1900 1906 1907 public Object visitList(List node) throws Exception { 1908 1911 1912 if (node.ctx == node.Store) return seqSet(node.elts); 1913 if (node.ctx == node.Del) return seqDel(node.elts); 1914 1915 code.new_(code.pool.Class("org/python/core/PyList")); 1916 code.dup(); 1917 makeArray(node.elts); 1918 if (mrefs.PyList_init == 0) { 1919 mrefs.PyList_init = code.pool.Methodref( 1920 "org/python/core/PyList", "<init>", 1921 "(" + $pyObjArr + ")V"); 1922 } 1923 code.invokespecial(mrefs.PyList_init); 1924 return null; 1925 } 1926 1927 int list_comprehension_count = 0; 1928 1929 public int PyList_init2; 1930 public Object visitListComp(ListComp node) throws Exception { 1931 code.new_(code.pool.Class("org/python/core/PyList")); 1932 code.dup(); 1933 if (mrefs.PyList_init2 == 0) { 1934 mrefs.PyList_init2 = code.pool.Methodref( 1935 "org/python/core/PyList", "<init>", "()V"); 1936 } 1937 code.invokespecial(mrefs.PyList_init2); 1938 1939 code.dup(); 1940 1941 code.ldc("append"); 1942 1943 if (mrefs.getattr == 0) { 1944 mrefs.getattr = code.pool.Methodref( 1945 "org/python/core/PyObject", "__getattr__", 1946 "(" + $str + ")" + $pyObj); 1947 } 1948 code.invokevirtual(mrefs.getattr); 1949 1950 String tmp_append = "_[" + (++list_comprehension_count) + "]"; 1951 1952 set(new Name(tmp_append, Name.Store, node)); 1953 1954 stmtType n = new Expr(new Call(new Name(tmp_append, Name.Load, node), 1955 new exprType[] { node.elt }, 1956 new keywordType[0], null, null, node), 1957 node); 1958 1959 for (int i = node.generators.length - 1; i >= 0; i--) { 1960 listcompType lc = node.generators[i]; 1961 for (int j = lc.ifs.length - 1; j >= 0; j--) { 1962 n = new If(lc.ifs[j], new stmtType[] { n }, null, lc.ifs[j]); 1963 } 1964 n = new For(lc.target, lc.iter, new stmtType[] { n }, null, lc); 1965 } 1966 visit(n); 1967 visit(new Delete(new exprType[] { new Name(tmp_append, Name.Del) })); 1968 1969 return null; 1970 } 1971 1972 public Object visitDict(Dict node) throws Exception { 1973 code.new_(code.pool.Class("org/python/core/PyDictionary")); 1974 code.dup(); 1975 SimpleNode[] elts = new SimpleNode[node.keys.length * 2]; 1976 for (int i = 0; i < node.keys.length; i++) { 1977 elts[i * 2] = node.keys[i]; 1978 elts[i * 2 + 1] = node.values[i]; 1979 } 1980 makeArray(elts); 1981 if (mrefs.PyDictionary_init == 0) { 1982 mrefs.PyDictionary_init = code.pool.Methodref( 1983 "org/python/core/PyDictionary", "<init>", 1984 "(" + $pyObjArr + ")V"); 1985 } 1986 code.invokespecial(mrefs.PyDictionary_init); 1987 return null; 1988 } 1989 1990 public Object visitRepr(Repr node) throws Exception { 1991 visit(node.value); 1992 code.invokevirtual("org/python/core/PyObject", "__repr__", 1993 "()" + $pyStr); 1994 return null; 1995 } 1996 1997 public int PyFunction_init1,PyFunction_closure_init1; 1998 public Object visitLambda(Lambda node) throws Exception { 1999 String name = "<lambda>"; 2000 2001 modType retSuite = new Suite(new stmtType[] { 2003 new Return(node.body, node) }, node); 2004 2005 setline(node); 2006 2007 code.new_(code.pool.Class("org/python/core/PyFunction")); 2008 code.dup(); 2009 loadFrame(); 2010 if (mrefs.f_globals == 0) { 2011 mrefs.f_globals = code.pool.Fieldref("org/python/core/PyFrame", 2012 "f_globals", $pyObj); 2013 } 2014 code.getfield(mrefs.f_globals); 2015 2016 ScopeInfo scope = module.getScopeInfo(node); 2017 2018 makeArray(scope.ac.getDefaults()); 2019 2020 scope.setup_closure(my_scope); 2021 scope.dump(); 2022 module.PyCode(retSuite, name, true, className, 2023 false, false, node.beginLine, scope).get(code); 2024 Vector freenames = scope.freevars; 2025 2026 if (!makeClosure(freenames)) { 2027 if (mrefs.PyFunction_init1 == 0) { 2028 mrefs.PyFunction_init1 = code.pool.Methodref( 2029 "org/python/core/PyFunction", "<init>", 2030 "(" + $pyObj + $pyObjArr + $pyCode + ")V"); 2031 } 2032 code.invokespecial(mrefs.PyFunction_init1); 2033 } else { 2034 if (mrefs.PyFunction_closure_init1 == 0) { 2035 mrefs.PyFunction_closure_init1 = code.pool.Methodref( 2036 "org/python/core/PyFunction", "<init>", 2037 "(" + $pyObj + $pyObjArr + $pyCode + $pyObjArr + ")V"); 2038 } 2039 code.invokespecial(mrefs.PyFunction_closure_init1); 2040 } 2041 2042 return null; 2043 } 2044 2045 2046 public int Ellipsis; 2047 public Object visitEllipsis(Ellipsis node) throws Exception { 2048 if (mrefs.Ellipsis == 0) { 2049 mrefs.Ellipsis = code.pool.Fieldref( 2050 "org/python/core/Py", "Ellipsis", 2051 "Lorg/python/core/PyObject;"); 2052 } 2053 code.getstatic(mrefs.Ellipsis); 2054 return null; 2055 } 2056 2057 public int PySlice_init; 2058 public Object visitSlice(Slice node) throws Exception { 2059 code.new_(code.pool.Class("org/python/core/PySlice")); 2060 code.dup(); 2061 if (node.lower == null) getNone(); else visit(node.lower); 2062 if (node.upper == null) getNone(); else visit(node.upper); 2063 if (node.step == null) getNone(); else visit(node.step); 2064 if (mrefs.PySlice_init == 0) { 2065 mrefs.PySlice_init = code.pool.Methodref( 2066 "org/python/core/PySlice", "<init>", 2067 "(" + $pyObj + $pyObj + $pyObj + ")V"); 2068 } 2069 code.invokespecial(mrefs.PySlice_init); 2070 return null; 2071 } 2072 2073 public int makeClass,makeClass_closure; 2074 public Object visitClassDef(ClassDef node) throws Exception { 2075 setline(node); 2076 2077 String name = getName(node.name); 2079 code.ldc(name); 2081 2082 makeArray(node.bases); 2083 2084 ScopeInfo scope = module.getScopeInfo(node); 2085 2086 scope.setup_closure(my_scope); 2087 scope.dump(); 2088 module.PyCode(new Suite(node.body, node), name, false, name, 2090 true, false, node.beginLine, scope).get(code); 2091 Vector freenames = scope.freevars; 2092 2093 getDocString(node.body); 2095 2096 if (!makeClosure(freenames)) { 2098 if (mrefs.makeClass == 0) { 2099 mrefs.makeClass = code.pool.Methodref( 2100 "org/python/core/Py", "makeClass", 2101 "(" + $str + $pyObjArr + $pyCode + $pyObj + ")" + $pyObj); 2102 } 2103 code.invokestatic(mrefs.makeClass); 2104 } else { 2105 if (mrefs.makeClass_closure == 0) { 2106 mrefs.makeClass_closure = code.pool.Methodref( 2107 "org/python/core/Py", "makeClass", 2108 "(" + $str + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")" + 2109 $pyObj); 2110 } 2111 code.invokestatic(mrefs.makeClass_closure); 2112 } 2113 2114 set(new Name(node.name, Name.Store, node)); 2116 return null; 2117 } 2118 2119 public Object visitNum(Num node) throws Exception { 2120 if (node.n instanceof PyInteger) { 2121 module.PyInteger(((PyInteger) node.n).getValue()).get(code); 2122 } else if (node.n instanceof PyLong) { 2123 module.PyLong(((PyObject)node.n).__str__().toString()).get(code); 2124 } else if (node.n instanceof PyFloat) { 2125 module.PyFloat(((PyFloat) node.n).getValue()).get(code); 2126 } else if (node.n instanceof PyComplex) { 2127 module.PyComplex(((PyComplex) node.n).imag).get(code); 2128 } 2129 return null; 2130 } 2131 2132 private String getName(String name) { 2133 if (className != null && name.startsWith("__") && 2134 !name.endsWith("__")) 2135 { 2136 int i = 0; 2138 while (className.charAt(i) == '_') 2139 i++; 2140 return "_"+className.substring(i)+name; 2141 } 2142 return name; 2143 } 2144 2145 int getglobal, getlocal1, getlocal2; 2146 int setglobal, setlocal1, setlocal2; 2147 int delglobal, dellocal1, dellocal2; 2148 int getderef,setderef; 2149 2150 void emitGetGlobal(String name) throws Exception { 2151 code.ldc(name); 2152 if (mrefs.getglobal == 0) { 2153 mrefs.getglobal = code.pool.Methodref( 2154 "org/python/core/PyFrame", "getglobal", 2155 "(" + $str + ")" + $pyObj); 2156 } 2157 code.invokevirtual(mrefs.getglobal); 2158 } 2159 2160 public Object visitName(Name node) throws Exception { 2161 String name; 2162 if (fast_locals) 2163 name = node.id; 2164 else 2165 name = getName(node.id); 2166 2167 SymInfo syminf = (SymInfo)tbl.get(name); 2168 2169 int ctx = node.ctx; 2170 if (ctx == node.AugStore) { 2171 ctx = augmode; 2172 } 2173 2174 switch (ctx) { 2175 case Name.Load: 2176 loadFrame(); 2177 if (syminf != null) { 2178 int flags = syminf.flags; 2179 if ((flags&ScopeInfo.GLOBAL) !=0 || optimizeGlobals&& 2180 (flags&(ScopeInfo.BOUND|ScopeInfo.CELL| 2181 ScopeInfo.FREE))==0) { 2182 emitGetGlobal(name); 2183 return null; 2184 } 2185 if (fast_locals) { 2186 if ((flags&ScopeInfo.CELL) != 0) { 2187 code.iconst(syminf.env_index); 2188 if (mrefs.getderef == 0) { 2189 mrefs.getderef = code.pool.Methodref( 2190 "org/python/core/PyFrame", "getderef", 2191 "(I)" + $pyObj); 2192 } 2193 code.invokevirtual(mrefs.getderef); 2194 return null; 2195 } 2196 if ((flags&ScopeInfo.BOUND) != 0) { 2197 code.iconst(syminf.locals_index); 2198 if (mrefs.getlocal2 == 0) { 2199 mrefs.getlocal2 = code.pool.Methodref( 2200 "org/python/core/PyFrame", "getlocal", 2201 "(I)" + $pyObj); 2202 } 2203 code.invokevirtual(mrefs.getlocal2); 2204 return null; 2205 } 2206 } 2207 if ((flags&ScopeInfo.FREE) != 0 && 2208 (flags&ScopeInfo.BOUND) == 0) { 2209 code.iconst(syminf.env_index); 2210 if (mrefs.getderef == 0) { 2211 mrefs.getderef = code.pool.Methodref( 2212 "org/python/core/PyFrame", "getderef", 2213 "(I)" + $pyObj); 2214 } 2215 code.invokevirtual(mrefs.getderef); 2216 return null; 2217 } 2218 } 2219 code.ldc(name); 2220 if (mrefs.getlocal1 == 0) { 2221 mrefs.getlocal1 = code.pool.Methodref( 2222 "org/python/core/PyFrame", "getname", 2223 "(" + $str + ")" + $pyObj); 2224 } 2225 code.invokevirtual(mrefs.getlocal1); 2226 return null; 2227 2228 case Name.Store: 2229 loadFrame(); 2230 if (syminf != null && (syminf.flags&ScopeInfo.GLOBAL) != 0) { 2231 code.ldc(name); 2232 code.aload(temporary); 2233 if (mrefs.setglobal == 0) { 2234 mrefs.setglobal = code.pool.Methodref( 2235 "org/python/core/PyFrame", "setglobal", 2236 "(" + $str + $pyObj + ")V"); 2237 } 2238 code.invokevirtual(mrefs.setglobal); 2239 } else { 2240 if (!fast_locals) { 2241 code.ldc(name); 2242 code.aload(temporary); 2243 if (mrefs.setlocal1 == 0) { 2244 mrefs.setlocal1 = code.pool.Methodref( 2245 "org/python/core/PyFrame", "setlocal", 2246 "(" + $str + $pyObj + ")V"); 2247 } 2248 code.invokevirtual(mrefs.setlocal1); 2249 } else { 2250 if (syminf == null) { 2251 System.err.println("internal compiler error: "+node); 2252 } 2253 if ((syminf.flags&ScopeInfo.CELL) != 0) { 2254 code.iconst(syminf.env_index); 2255 code.aload(temporary); 2256 if (mrefs.setderef == 0) { 2257 mrefs.setderef = code.pool.Methodref( 2258 "org/python/core/PyFrame", "setderef", 2259 "(I" + $pyObj + ")V"); 2260 } 2261 code.invokevirtual(mrefs.setderef); 2262 } else { 2263 code.iconst(syminf.locals_index); 2264 code.aload(temporary); 2265 if (mrefs.setlocal2 == 0) { 2266 mrefs.setlocal2 = code.pool.Methodref( 2267 "org/python/core/PyFrame", "setlocal", 2268 "(I" + $pyObj + ")V"); 2269 } 2270 code.invokevirtual(mrefs.setlocal2); 2271 } 2272 } 2273 } 2274 return null; 2275 case Name.Del: { 2276 loadFrame(); 2277 if (syminf != null && (syminf.flags&ScopeInfo.GLOBAL) != 0) { 2278 code.ldc(name); 2279 if (mrefs.delglobal == 0) { 2280 mrefs.delglobal = code.pool.Methodref( 2281 "org/python/core/PyFrame", "delglobal", 2282 "(" + $str + ")V"); 2283 } 2284 code.invokevirtual(mrefs.delglobal); 2285 } else { 2286 if (!fast_locals) { 2287 code.ldc(name); 2288 if (mrefs.dellocal1 == 0) { 2289 mrefs.dellocal1 = code.pool.Methodref( 2290 "org/python/core/PyFrame", "dellocal", 2291 "(" + $str + ")V"); 2292 } 2293 code.invokevirtual(mrefs.dellocal1); 2294 } else { 2295 if (syminf == null) { 2296 System.err.println("internal compiler error: "+node); 2297 } 2298 if ((syminf.flags&ScopeInfo.CELL) != 0) { 2299 module.error("can not delete variable '"+name+ 2300 "' referenced in nested scope",true,node); 2301 } 2302 code.iconst(syminf.locals_index); 2303 if (mrefs.dellocal2 == 0) { 2304 mrefs.dellocal2 = code.pool.Methodref( 2305 "org/python/core/PyFrame", "dellocal", 2306 "(I)V"); 2307 } 2308 code.invokevirtual(mrefs.dellocal2); 2309 } 2310 } 2311 return null; } 2312 } 2313 return null; 2314 } 2315 2316 public Object visitStr(Str node) throws Exception { 2317 String s = node.s; 2318 if (s.length() > 32767) { 2319 throw new ParseException( 2320 "string constant too large (more than 32767 characters)", 2321 node); 2322 } 2323 module.PyString(s).get(code); 2324 return null; 2325 } 2326 2327 protected Object unhandled_node(SimpleNode node) throws Exception { 2328 throw new Exception ("Unhandled node " + node); 2329 } 2330 2331 2332 class InFinally { 2333 public int retLocal; 2334 public Label[] labels; 2335 public int cnt = 1; 2336 2337 public InFinally(int labelcnt) { 2338 labels = new Label[labelcnt]; 2339 for (int i = 0; i < labelcnt; i++) { 2340 labels[i] = code.getLabel(); 2341 } 2342 } 2343 } 2344} 2345 | Popular Tags |