PageRenderTime 52ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 1ms

/src/org/python/compiler/CodeCompiler.java

http://github.com/nriley/jython
Java | 2443 lines | 1949 code | 366 blank | 128 comment | 370 complexity | 1397420fd7ba05d3a2c32bdaecccbfe2 MD5 | raw file
  1. // Copyright (c) Corporation for National Research Initiatives
  2. package org.python.compiler;
  3. import java.io.IOException;
  4. import java.util.ArrayList;
  5. import java.util.Collection;
  6. import java.util.Map;
  7. import java.util.Stack;
  8. import java.util.Vector;
  9. import org.python.antlr.ParseException;
  10. import org.python.antlr.PythonTree;
  11. import org.python.antlr.Visitor;
  12. import org.python.antlr.ast.Assert;
  13. import org.python.antlr.ast.Assign;
  14. import org.python.antlr.ast.Attribute;
  15. import org.python.antlr.ast.AugAssign;
  16. import org.python.antlr.ast.BinOp;
  17. import org.python.antlr.ast.BoolOp;
  18. import org.python.antlr.ast.Break;
  19. import org.python.antlr.ast.Call;
  20. import org.python.antlr.ast.ClassDef;
  21. import org.python.antlr.ast.Compare;
  22. import org.python.antlr.ast.Continue;
  23. import org.python.antlr.ast.Delete;
  24. import org.python.antlr.ast.Dict;
  25. import org.python.antlr.ast.Ellipsis;
  26. import org.python.antlr.ast.ExceptHandler;
  27. import org.python.antlr.ast.Exec;
  28. import org.python.antlr.ast.Expr;
  29. import org.python.antlr.ast.Expression;
  30. import org.python.antlr.ast.ExtSlice;
  31. import org.python.antlr.ast.For;
  32. import org.python.antlr.ast.FunctionDef;
  33. import org.python.antlr.ast.GeneratorExp;
  34. import org.python.antlr.ast.Global;
  35. import org.python.antlr.ast.If;
  36. import org.python.antlr.ast.IfExp;
  37. import org.python.antlr.ast.Import;
  38. import org.python.antlr.ast.ImportFrom;
  39. import org.python.antlr.ast.Index;
  40. import org.python.antlr.ast.Interactive;
  41. import org.python.antlr.ast.Lambda;
  42. import org.python.antlr.ast.List;
  43. import org.python.antlr.ast.ListComp;
  44. import org.python.antlr.ast.Name;
  45. import org.python.antlr.ast.Num;
  46. import org.python.antlr.ast.Pass;
  47. import org.python.antlr.ast.Print;
  48. import org.python.antlr.ast.Raise;
  49. import org.python.antlr.ast.Repr;
  50. import org.python.antlr.ast.Return;
  51. import org.python.antlr.ast.Slice;
  52. import org.python.antlr.ast.Str;
  53. import org.python.antlr.ast.Subscript;
  54. import org.python.antlr.ast.Suite;
  55. import org.python.antlr.ast.TryExcept;
  56. import org.python.antlr.ast.TryFinally;
  57. import org.python.antlr.ast.Tuple;
  58. import org.python.antlr.ast.UnaryOp;
  59. import org.python.antlr.ast.While;
  60. import org.python.antlr.ast.With;
  61. import org.python.antlr.ast.Yield;
  62. import org.python.antlr.ast.alias;
  63. import org.python.antlr.ast.cmpopType;
  64. import org.python.antlr.ast.comprehension;
  65. import org.python.antlr.ast.expr_contextType;
  66. import org.python.antlr.ast.keyword;
  67. import org.python.antlr.ast.operatorType;
  68. import org.python.antlr.base.expr;
  69. import org.python.antlr.base.mod;
  70. import org.python.antlr.base.stmt;
  71. import org.python.core.CompilerFlags;
  72. import org.python.core.ContextGuard;
  73. import org.python.core.ContextManager;
  74. import org.python.core.PyComplex;
  75. import org.python.core.PyFloat;
  76. import org.python.core.PyInteger;
  77. import org.python.core.PyLong;
  78. import org.python.core.PyObject;
  79. import org.python.core.PyString;
  80. import org.python.core.PyUnicode;
  81. import org.objectweb.asm.ClassWriter;
  82. import org.objectweb.asm.Label;
  83. import org.objectweb.asm.Opcodes;
  84. import org.objectweb.asm.Type;
  85. import org.objectweb.asm.commons.Method;
  86. public class CodeCompiler extends Visitor implements Opcodes, ClassConstants //, PythonGrammarTreeConstants
  87. {
  88. public static final Object Exit=new Integer(1);
  89. public static final Object NoExit=null;
  90. public static final int GET=0;
  91. public static final int SET=1;
  92. public static final int DEL=2;
  93. public static final int AUGGET=3;
  94. public static final int AUGSET=4;
  95. public Module module;
  96. public ClassWriter cw;
  97. public Code code;
  98. public CodeCompiler mrefs;
  99. public CompilerFlags cflags;
  100. int temporary;
  101. expr_contextType augmode;
  102. int augtmp1;
  103. int augtmp2;
  104. int augtmp3;
  105. int augtmp4;
  106. public boolean fast_locals, print_results;
  107. public Map<String, SymInfo> tbl;
  108. public ScopeInfo my_scope;
  109. boolean optimizeGlobals = true;
  110. public Vector names;
  111. public String className;
  112. public Stack continueLabels, breakLabels;
  113. public Stack exceptionHandlers;
  114. public Vector yields = new Vector();
  115. /* break/continue finally's level.
  116. * This is the lowest level in the exceptionHandlers which should
  117. * be executed at break or continue.
  118. * It is saved/updated/restored when compiling loops.
  119. * A similar level for returns is not needed because a new CodeCompiler
  120. * is used for each PyCode, ie. each 'function'.
  121. * When returning through finally's all the exceptionHandlers are executed.
  122. */
  123. public int bcfLevel = 0;
  124. int yield_count = 0;
  125. private Stack<String> stack = new Stack<String>();
  126. public CodeCompiler(Module module, boolean print_results) {
  127. this.module = module;
  128. this.print_results = print_results;
  129. mrefs = this;
  130. cw = module.classfile.cw;
  131. continueLabels = new Stack();
  132. breakLabels = new Stack();
  133. exceptionHandlers = new Stack();
  134. }
  135. public void getNone() throws IOException {
  136. code.getstatic("org/python/core/Py", "None", $pyObj);
  137. }
  138. public void loadFrame() throws Exception {
  139. code.aload(1);
  140. }
  141. public void loadThreadState() throws Exception {
  142. code.aload(2);
  143. }
  144. public void setLastI(int idx) throws Exception {
  145. loadFrame();
  146. code.iconst(idx);
  147. code.putfield("org/python/core/PyFrame", "f_lasti", "I");
  148. }
  149. private void loadf_back() throws Exception {
  150. code.getfield("org/python/core/PyFrame", "f_back", $pyFrame);
  151. }
  152. public int storeTop() throws Exception {
  153. int tmp = code.getLocal("org/python/core/PyObject");
  154. code.astore(tmp);
  155. return tmp;
  156. }
  157. public void setline(int line) throws Exception {
  158. if (module.linenumbers) {
  159. code.setline(line);
  160. loadFrame();
  161. code.iconst(line);
  162. code.invokevirtual("org/python/core/PyFrame", "setline", "(I)V");
  163. }
  164. }
  165. public void setline(PythonTree node) throws Exception {
  166. setline(node.getLine());
  167. }
  168. public void set(PythonTree node) throws Exception {
  169. int tmp = storeTop();
  170. set(node, tmp);
  171. code.aconst_null();
  172. code.astore(tmp);
  173. code.freeLocal(tmp);
  174. }
  175. public void set(PythonTree node, int tmp) throws Exception {
  176. temporary = tmp;
  177. visit(node);
  178. }
  179. private void saveAugTmps(PythonTree node, int count) throws Exception {
  180. if (count >= 4) {
  181. augtmp4 = code.getLocal("Lorg/python/core/PyObject;");
  182. code.astore(augtmp4);
  183. }
  184. if (count >= 3) {
  185. augtmp3 = code.getLocal("Lorg/python/core/PyObject;");
  186. code.astore(augtmp3);
  187. }
  188. if (count >= 2) {
  189. augtmp2 = code.getLocal("Lorg/python/core/PyObject;");
  190. code.astore(augtmp2);
  191. }
  192. augtmp1 = code.getLocal("Lorg/python/core/PyObject;");
  193. code.astore(augtmp1);
  194. code.aload(augtmp1);
  195. if (count >= 2)
  196. code.aload(augtmp2);
  197. if (count >= 3)
  198. code.aload(augtmp3);
  199. if (count >= 4)
  200. code.aload(augtmp4);
  201. }
  202. private void restoreAugTmps(PythonTree node, int count) throws Exception {
  203. code.aload(augtmp1);
  204. code.freeLocal(augtmp1);
  205. if (count == 1)
  206. return;
  207. code.aload(augtmp2);
  208. code.freeLocal(augtmp2);
  209. if (count == 2)
  210. return;
  211. code.aload(augtmp3);
  212. code.freeLocal(augtmp3);
  213. if (count == 3)
  214. return;
  215. code.aload(augtmp4);
  216. code.freeLocal(augtmp4);
  217. }
  218. public void parse(mod node, Code code,
  219. boolean fast_locals, String className,
  220. boolean classBody, ScopeInfo scope, CompilerFlags cflags)
  221. throws Exception
  222. {
  223. this.fast_locals = fast_locals;
  224. this.className = className;
  225. this.code = code;
  226. this.cflags = cflags;
  227. my_scope = scope;
  228. names = scope.names;
  229. tbl = scope.tbl;
  230. optimizeGlobals = fast_locals&&!scope.exec&&!scope.from_import_star;
  231. if (scope.max_with_count > 0) {
  232. // allocate for all the with-exits we will have in the frame;
  233. // this allows yield and with to happily co-exist
  234. loadFrame();
  235. code.iconst(scope.max_with_count);
  236. code.anewarray("org/python/core/PyObject");
  237. code.putfield("org/python/core/PyFrame", "f_exits", $pyObjArr);
  238. }
  239. Object exit = visit(node);
  240. if (classBody) {
  241. loadFrame();
  242. code.invokevirtual("org/python/core/PyFrame", "getf_locals", "()" + $pyObj);
  243. code.areturn();
  244. } else {
  245. if (exit == null) {
  246. setLastI(-1);
  247. getNone();
  248. code.areturn();
  249. }
  250. }
  251. }
  252. @Override
  253. public Object visitInteractive(Interactive node) throws Exception {
  254. traverse(node);
  255. return null;
  256. }
  257. @Override
  258. public Object visitModule(org.python.antlr.ast.Module suite)
  259. throws Exception
  260. {
  261. if (suite.getInternalBody().size() > 0 &&
  262. suite.getInternalBody().get(0) instanceof Expr &&
  263. ((Expr) suite.getInternalBody().get(0)).getInternalValue() instanceof Str)
  264. {
  265. loadFrame();
  266. code.ldc("__doc__");
  267. visit(((Expr) suite.getInternalBody().get(0)).getInternalValue());
  268. code.invokevirtual("org/python/core/PyFrame", "setglobal", "(" +$str + $pyObj + ")V");
  269. }
  270. traverse(suite);
  271. return null;
  272. }
  273. @Override
  274. public Object visitExpression(Expression node) throws Exception {
  275. if (my_scope.generator && node.getInternalBody() != null) {
  276. module.error("'return' with argument inside generator",
  277. true, node);
  278. }
  279. return visitReturn(new Return(node,node.getInternalBody()), true);
  280. }
  281. public int makeArray(java.util.List<? extends PythonTree> nodes) throws Exception {
  282. // XXX: This should produce an array on the stack (if possible) instead of a local
  283. // the caller is responsible for freeing.
  284. int n;
  285. if (nodes == null)
  286. n = 0;
  287. else
  288. n = nodes.size();
  289. int array = code.getLocal("[Lorg/python/core/PyObject;");
  290. if (n == 0) {
  291. code.getstatic("org/python/core/Py", "EmptyObjects", $pyObjArr);
  292. code.astore(array);
  293. } else {
  294. code.iconst(n);
  295. code.anewarray("org/python/core/PyObject");
  296. code.astore(array);
  297. for(int i=0; i<n; i++) {
  298. visit(nodes.get(i));
  299. code.aload(array);
  300. code.swap();
  301. code.iconst(i);
  302. code.swap();
  303. code.aastore();
  304. }
  305. }
  306. return array;
  307. }
  308. // nulls out an array of references
  309. public void freeArray(int array) {
  310. code.aload(array);
  311. code.aconst_null();
  312. code.invokestatic("java/util/Arrays", "fill", "(" + $objArr + $obj + ")V");
  313. code.freeLocal(array);
  314. }
  315. public void getDocString(java.util.List<stmt> suite) throws Exception {
  316. if (suite.size() > 0 && suite.get(0) instanceof Expr &&
  317. ((Expr) suite.get(0)).getInternalValue() instanceof Str)
  318. {
  319. visit(((Expr) suite.get(0)).getInternalValue());
  320. } else {
  321. code.aconst_null();
  322. }
  323. }
  324. public boolean makeClosure(ScopeInfo scope) throws Exception {
  325. if (scope == null || scope.freevars == null) return false;
  326. int n = scope.freevars.size();
  327. if (n == 0) return false;
  328. int tmp = code.getLocal("[Lorg/python/core/PyObject;");
  329. code.iconst(n);
  330. code.anewarray("org/python/core/PyObject");
  331. code.astore(tmp);
  332. Map<String, SymInfo> upTbl = scope.up.tbl;
  333. for(int i=0; i<n; i++) {
  334. code.aload(tmp);
  335. code.iconst(i);
  336. loadFrame();
  337. for(int j = 1; j < scope.distance; j++) {
  338. loadf_back();
  339. }
  340. SymInfo symInfo = upTbl.get(scope.freevars.elementAt(i));
  341. code.iconst(symInfo.env_index);
  342. code.invokevirtual("org/python/core/PyFrame", "getclosure", "(I)" + $pyObj);
  343. code.aastore();
  344. }
  345. code.aload(tmp);
  346. code.freeLocal(tmp);
  347. return true;
  348. }
  349. @Override
  350. public Object visitFunctionDef(FunctionDef node) throws Exception {
  351. String name = getName(node.getInternalName());
  352. setline(node);
  353. ScopeInfo scope = module.getScopeInfo(node);
  354. // NOTE: this is attached to the constructed PyFunction, so it cannot be nulled out
  355. // with freeArray, unlike other usages of makeArray here
  356. int defaults = makeArray(scope.ac.getDefaults());
  357. code.new_("org/python/core/PyFunction");
  358. code.dup();
  359. loadFrame();
  360. code.getfield("org/python/core/PyFrame", "f_globals", $pyObj);
  361. code.aload(defaults);
  362. code.freeLocal(defaults);
  363. scope.setup_closure();
  364. scope.dump();
  365. module.PyCode(new Suite(node,node.getInternalBody()), name, true,
  366. className, false, false,
  367. node.getLine(), scope, cflags).get(code);
  368. getDocString(node.getInternalBody());
  369. if (!makeClosure(scope)) {
  370. code.invokespecial("org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + ")V");
  371. } else {
  372. code.invokespecial( "org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")V");
  373. }
  374. applyDecorators(node.getInternalDecorator_list());
  375. set(new Name(node,node.getInternalName(), expr_contextType.Store));
  376. return null;
  377. }
  378. private void applyDecorators(java.util.List<expr> decorators) throws Exception {
  379. if (decorators != null && !decorators.isEmpty()) {
  380. int res = storeTop();
  381. for (expr decorator : decorators) {
  382. visit(decorator); stackProduce();
  383. }
  384. for (int i = decorators.size(); i > 0; i--) {
  385. stackConsume();
  386. loadThreadState();
  387. code.aload(res);
  388. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + ")" + $pyObj);
  389. code.astore(res);
  390. }
  391. code.aload(res);
  392. code.freeLocal(res);
  393. }
  394. }
  395. @Override
  396. public Object visitExpr(Expr node) throws Exception {
  397. setline(node);
  398. visit(node.getInternalValue());
  399. if (print_results) {
  400. code.invokestatic("org/python/core/Py", "printResult", "(" + $pyObj + ")V");
  401. } else {
  402. code.pop();
  403. }
  404. return null;
  405. }
  406. @Override
  407. public Object visitAssign(Assign node) throws Exception {
  408. setline(node);
  409. visit(node.getInternalValue());
  410. if (node.getInternalTargets().size() == 1) {
  411. set(node.getInternalTargets().get(0));
  412. } else {
  413. int tmp = storeTop();
  414. for (expr target : node.getInternalTargets()) {
  415. set(target, tmp);
  416. }
  417. code.freeLocal(tmp);
  418. }
  419. return null;
  420. }
  421. @Override
  422. public Object visitPrint(Print node) throws Exception {
  423. setline(node);
  424. int tmp = -1;
  425. if (node.getInternalDest() != null) {
  426. visit(node.getInternalDest());
  427. tmp = storeTop();
  428. }
  429. if (node.getInternalValues() == null || node.getInternalValues().size() == 0) {
  430. if (node.getInternalDest() != null) {
  431. code.aload(tmp);
  432. code.invokestatic("org/python/core/Py", "printlnv", "(" + $pyObj + ")V");
  433. } else {
  434. code.invokestatic("org/python/core/Py", "println", "()V");
  435. }
  436. } else {
  437. for (int i = 0; i < node.getInternalValues().size(); i++) {
  438. if (node.getInternalDest() != null) {
  439. code.aload(tmp);
  440. visit(node.getInternalValues().get(i));
  441. if (node.getInternalNl() && i == node.getInternalValues().size() - 1) {
  442. code.invokestatic("org/python/core/Py", "println", "(" + $pyObj + $pyObj + ")V");
  443. } else {
  444. code.invokestatic("org/python/core/Py", "printComma", "(" + $pyObj + $pyObj + ")V");
  445. }
  446. } else {
  447. visit(node.getInternalValues().get(i));
  448. if (node.getInternalNl() && i == node.getInternalValues().size() - 1) {
  449. code.invokestatic("org/python/core/Py", "println", "(" + $pyObj + ")V");
  450. } else {
  451. code.invokestatic("org/python/core/Py", "printComma", "(" + $pyObj + ")V");
  452. }
  453. }
  454. }
  455. }
  456. if (node.getInternalDest() != null) {
  457. code.freeLocal(tmp);
  458. }
  459. return null;
  460. }
  461. @Override
  462. public Object visitDelete(Delete node) throws Exception {
  463. setline(node);
  464. traverse(node);
  465. return null;
  466. }
  467. @Override
  468. public Object visitPass(Pass node) throws Exception {
  469. setline(node);
  470. return null;
  471. }
  472. @Override
  473. public Object visitBreak(Break node) throws Exception {
  474. //setline(node); Not needed here...
  475. if (breakLabels.empty()) {
  476. throw new ParseException("'break' outside loop", node);
  477. }
  478. doFinallysDownTo(bcfLevel);
  479. code.goto_((Label)breakLabels.peek());
  480. return null;
  481. }
  482. @Override
  483. public Object visitContinue(Continue node) throws Exception {
  484. //setline(node); Not needed here...
  485. if (continueLabels.empty()) {
  486. throw new ParseException("'continue' not properly in loop", node);
  487. }
  488. doFinallysDownTo(bcfLevel);
  489. code.goto_((Label)continueLabels.peek());
  490. return Exit;
  491. }
  492. @Override
  493. public Object visitYield(Yield node) throws Exception {
  494. setline(node);
  495. if (!fast_locals) {
  496. throw new ParseException("'yield' outside function", node);
  497. }
  498. int stackState = saveStack();
  499. if (node.getInternalValue() != null) {
  500. visit(node.getInternalValue());
  501. } else {
  502. getNone();
  503. }
  504. setLastI(++yield_count);
  505. saveLocals();
  506. code.areturn();
  507. Label restart = new Label();
  508. yields.addElement(restart);
  509. code.label(restart);
  510. restoreLocals();
  511. restoreStack(stackState);
  512. loadFrame();
  513. code.invokevirtual("org/python/core/PyFrame", "getGeneratorInput", "()" + $obj);
  514. code.dup();
  515. code.instanceof_("org/python/core/PyException");
  516. Label done2 = new Label();
  517. code.ifeq(done2);
  518. code.checkcast("java/lang/Throwable");
  519. code.athrow();
  520. code.label(done2);
  521. code.checkcast("org/python/core/PyObject");
  522. return null;
  523. }
  524. private void stackProduce() {
  525. stackProduce("org/python/core/PyObject");
  526. }
  527. private void stackProduce(String signature) {
  528. stack.push(signature);
  529. }
  530. private void stackConsume() {
  531. stackConsume(1);
  532. }
  533. private void stackConsume(int numItems) {
  534. for (int i = 0; i < numItems; i++) {
  535. stack.pop();
  536. }
  537. }
  538. private int saveStack() throws Exception {
  539. if (stack.size() > 0) {
  540. int array = code.getLocal("[Ljava/lang/Object;");
  541. code.iconst(stack.size());
  542. code.anewarray("java/lang/Object");
  543. code.astore(array);
  544. for (int i = 0; i < stack.size(); i++) {
  545. code.aload(array);
  546. // Stack: |- ... value array
  547. code.swap();
  548. code.iconst(i);
  549. code.swap();
  550. // Stack: |- ... array index value
  551. code.aastore();
  552. // Stack: |- ...
  553. }
  554. return array;
  555. } else {
  556. return -1;
  557. }
  558. }
  559. private void restoreStack(int array) throws Exception {
  560. if (stack.size() > 0) {
  561. int i = stack.size() -1;
  562. for (String signature : stack) {
  563. code.aload(array);
  564. // Stack: |- ... array
  565. code.iconst(i);
  566. code.aaload();
  567. // Stack: |- ... value
  568. code.checkcast(signature);
  569. }
  570. code.freeLocal(array);
  571. }
  572. }
  573. private void restoreLocals() throws Exception {
  574. endExceptionHandlers();
  575. Vector v = code.getActiveLocals();
  576. loadFrame();
  577. code.getfield("org/python/core/PyFrame", "f_savedlocals", "[Ljava/lang/Object;");
  578. int locals = code.getLocal("[Ljava/lang/Object;");
  579. code.astore(locals);
  580. for (int i = 0; i < v.size(); i++) {
  581. String type = (String) v.elementAt(i);
  582. if (type == null)
  583. continue;
  584. code.aload(locals);
  585. code.iconst(i);
  586. code.aaload();
  587. code.checkcast(type);
  588. code.astore(i);
  589. }
  590. code.freeLocal(locals);
  591. restartExceptionHandlers();
  592. }
  593. /**
  594. * Close all the open exception handler ranges. This should be paired
  595. * with restartExceptionHandlers to delimit internal code that
  596. * shouldn't be handled by user handlers. This allows us to set
  597. * variables without the verifier thinking we might jump out of our
  598. * handling with an exception.
  599. */
  600. private void endExceptionHandlers()
  601. {
  602. Label end = new Label();
  603. code.label(end);
  604. for (int i = 0; i < exceptionHandlers.size(); ++i) {
  605. ExceptionHandler handler =
  606. (ExceptionHandler)exceptionHandlers.elementAt(i);
  607. handler.exceptionEnds.addElement(end);
  608. }
  609. }
  610. private void restartExceptionHandlers()
  611. {
  612. Label start = new Label();
  613. code.label(start);
  614. for (int i = 0; i < exceptionHandlers.size(); ++i) {
  615. ExceptionHandler handler =
  616. (ExceptionHandler)exceptionHandlers.elementAt(i);
  617. handler.exceptionStarts.addElement(start);
  618. }
  619. }
  620. private void saveLocals() throws Exception {
  621. Vector v = code.getActiveLocals();
  622. code.iconst(v.size());
  623. code.anewarray("java/lang/Object");
  624. int locals = code.getLocal("[Ljava/lang/Object;");
  625. code.astore(locals);
  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. //code.checkcast(code.pool.Class("java/lang/Object"));
  633. if (i == 2222) {
  634. code.aconst_null();
  635. } else
  636. code.aload(i);
  637. code.aastore();
  638. }
  639. loadFrame();
  640. code.aload(locals);
  641. code.putfield("org/python/core/PyFrame", "f_savedlocals", "[Ljava/lang/Object;");
  642. code.freeLocal(locals);
  643. }
  644. @Override
  645. public Object visitReturn(Return node) throws Exception {
  646. return visitReturn(node, false);
  647. }
  648. public Object visitReturn(Return node, boolean inEval) throws Exception {
  649. setline(node);
  650. if (!inEval && !fast_locals) {
  651. throw new ParseException("'return' outside function", node);
  652. }
  653. int tmp = 0;
  654. if (node.getInternalValue() != null) {
  655. if (my_scope.generator)
  656. throw new ParseException("'return' with argument " +
  657. "inside generator", node);
  658. visit(node.getInternalValue());
  659. tmp = code.getReturnLocal();
  660. code.astore(tmp);
  661. }
  662. doFinallysDownTo(0);
  663. setLastI(-1);
  664. if (node.getInternalValue() != null) {
  665. code.aload(tmp);
  666. } else {
  667. getNone();
  668. }
  669. code.areturn();
  670. return Exit;
  671. }
  672. @Override
  673. public Object visitRaise(Raise node) throws Exception {
  674. setline(node);
  675. if (node.getInternalType() != null) { visit(node.getInternalType()); stackProduce(); }
  676. if (node.getInternalInst() != null) { visit(node.getInternalInst()); stackProduce(); }
  677. if (node.getInternalTback() != null) { visit(node.getInternalTback()); stackProduce(); }
  678. if (node.getInternalType() == null) {
  679. code.invokestatic("org/python/core/Py", "makeException", "()" + $pyExc);
  680. } else if (node.getInternalInst() == null) {
  681. stackConsume();
  682. code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + ")" + $pyExc);
  683. } else if (node.getInternalTback() == null) {
  684. stackConsume(2);
  685. code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + $pyObj + ")" + $pyExc);
  686. } else {
  687. stackConsume(3);
  688. code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + $pyObj + $pyObj + ")" + $pyExc);
  689. }
  690. code.athrow();
  691. return Exit;
  692. }
  693. @Override
  694. public Object visitImport(Import node) throws Exception {
  695. setline(node);
  696. for (alias a : node.getInternalNames()) {
  697. String asname = null;
  698. if (a.getInternalAsname() != null) {
  699. String name = a.getInternalName();
  700. asname = a.getInternalAsname();
  701. code.ldc(name);
  702. loadFrame();
  703. code.invokestatic("org/python/core/imp", "importOneAs", "(" + $str + $pyFrame + ")" + $pyObj);
  704. } else {
  705. String name = a.getInternalName();
  706. asname = name;
  707. if (asname.indexOf('.') > 0)
  708. asname = asname.substring(0, asname.indexOf('.'));
  709. code.ldc(name);
  710. loadFrame();
  711. code.invokestatic("org/python/core/imp", "importOne", "(" + $str + $pyFrame + ")" + $pyObj);
  712. }
  713. set(new Name(a, asname, expr_contextType.Store));
  714. }
  715. return null;
  716. }
  717. @Override
  718. public Object visitImportFrom(ImportFrom node) throws Exception {
  719. Future.checkFromFuture(node); // future stmt support
  720. setline(node);
  721. code.ldc(node.getInternalModule());
  722. java.util.List<alias> names = node.getInternalNames();
  723. if (names == null || names.size() == 0) {
  724. throw new ParseException("Internel parser error", node);
  725. } else if (names.size() == 1 && names.get(0).getInternalName().equals("*")) {
  726. if (node.getInternalLevel() > 0) {
  727. throw new ParseException("'import *' not allowed with 'from .'", node);
  728. }
  729. if (my_scope.func_level > 0) {
  730. module.error("import * only allowed at module level", false, node);
  731. if (my_scope.contains_ns_free_vars) {
  732. module.error("import * is not allowed in function '" +
  733. my_scope.scope_name +
  734. "' because it contains a nested function with free variables",
  735. true, node);
  736. }
  737. }
  738. if (my_scope.func_level > 1) {
  739. module.error("import * is not allowed in function '" +
  740. my_scope.scope_name +
  741. "' because it is a nested function",
  742. true, node);
  743. }
  744. loadFrame();
  745. code.invokestatic("org/python/core/imp", "importAll", "(" + $str + $pyFrame + ")V");
  746. } else {
  747. java.util.List<String> fromNames = new ArrayList<String>();//[names.size()];
  748. java.util.List<String> asnames = new ArrayList<String>();//[names.size()];
  749. for (int i = 0; i < names.size(); i++) {
  750. fromNames.add(names.get(i).getInternalName());
  751. asnames.add(names.get(i).getInternalAsname());
  752. if (asnames.get(i) == null)
  753. asnames.set(i, fromNames.get(i));
  754. }
  755. int strArray = makeStrings(code, fromNames);
  756. code.aload(strArray);
  757. code.freeLocal(strArray);
  758. loadFrame();
  759. if (node.getInternalLevel() == 0) {
  760. if (module.getFutures().isAbsoluteImportOn()) {
  761. code.iconst_0();
  762. } else {
  763. code.iconst_m1();
  764. }
  765. } else {
  766. code.iconst(node.getInternalLevel());
  767. }
  768. code.invokestatic("org/python/core/imp", "importFrom", "(" + $str + $strArr + $pyFrame + "I" + ")" + $pyObjArr);
  769. int tmp = storeTop();
  770. for (int i = 0; i < names.size(); i++) {
  771. code.aload(tmp);
  772. code.iconst(i);
  773. code.aaload();
  774. set(new Name(names.get(i), asnames.get(i), expr_contextType.Store));
  775. }
  776. code.freeLocal(tmp);
  777. }
  778. return null;
  779. }
  780. @Override
  781. public Object visitGlobal(Global node) throws Exception {
  782. return null;
  783. }
  784. @Override
  785. public Object visitExec(Exec node) throws Exception {
  786. setline(node);
  787. visit(node.getInternalBody());
  788. stackProduce();
  789. if (node.getInternalGlobals() != null) {
  790. visit(node.getInternalGlobals());
  791. } else {
  792. code.aconst_null();
  793. }
  794. stackProduce();
  795. if (node.getInternalLocals() != null) {
  796. visit(node.getInternalLocals());
  797. } else {
  798. code.aconst_null();
  799. }
  800. stackProduce();
  801. //do the real work here
  802. stackConsume(3);
  803. code.invokestatic("org/python/core/Py", "exec", "(" + $pyObj + $pyObj + $pyObj + ")V");
  804. return null;
  805. }
  806. @Override
  807. public Object visitAssert(Assert node) throws Exception {
  808. setline(node);
  809. Label end_of_assert = new Label();
  810. /* First do an if __debug__: */
  811. loadFrame();
  812. emitGetGlobal("__debug__");
  813. code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z");
  814. code.ifeq(end_of_assert);
  815. /* Now do the body of the assert. If PyObject.__nonzero__ is true,
  816. then the assertion succeeded, the message portion should not be
  817. processed. Otherwise, the message will be processed. */
  818. visit(node.getInternalTest());
  819. code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z");
  820. /* If evaluation is false, then branch to end of method */
  821. code.ifne(end_of_assert);
  822. /* Visit the message part of the assertion, or pass Py.None */
  823. if( node.getInternalMsg() != null ) {
  824. visit(node.getInternalMsg());
  825. } else {
  826. getNone();
  827. }
  828. /* Push exception type onto stack(Py.AssertionError) */
  829. code.getstatic("org/python/core/Py", "AssertionError", "Lorg/python/core/PyObject;");
  830. code.swap(); // The type is the first argument, but the message could be a yield
  831. code.invokestatic("org/python/core/Py", "makeException", "(" + $pyObj + $pyObj + ")" + $pyExc);
  832. /* Raise assertion error. Only executes this logic if assertion
  833. failed */
  834. code.athrow();
  835. /* And finally set the label for the end of it all */
  836. code.label(end_of_assert);
  837. return null;
  838. }
  839. public Object doTest(Label end_of_if, If node, int index)
  840. throws Exception
  841. {
  842. Label end_of_suite = new Label();
  843. setline(node.getInternalTest());
  844. visit(node.getInternalTest());
  845. code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z");
  846. code.ifeq(end_of_suite);
  847. Object exit = suite(node.getInternalBody());
  848. if (end_of_if != null && exit == null)
  849. code.goto_(end_of_if);
  850. code.label(end_of_suite);
  851. if (node.getInternalOrelse() != null) {
  852. return suite(node.getInternalOrelse()) != null ? exit : null;
  853. } else {
  854. return null;
  855. }
  856. }
  857. @Override
  858. public Object visitIf(If node) throws Exception {
  859. Label end_of_if = null;
  860. if (node.getInternalOrelse() != null)
  861. end_of_if = new Label();
  862. Object exit = doTest(end_of_if, node, 0);
  863. if (end_of_if != null)
  864. code.label(end_of_if);
  865. return exit;
  866. }
  867. @Override
  868. public Object visitIfExp(IfExp node) throws Exception {
  869. setline(node.getInternalTest());
  870. Label end = new Label();
  871. Label end_of_else = new Label();
  872. visit(node.getInternalTest());
  873. code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z");
  874. code.ifeq(end_of_else);
  875. visit(node.getInternalBody());
  876. code.goto_(end);
  877. code.label(end_of_else);
  878. visit(node.getInternalOrelse());
  879. code.label(end);
  880. return null;
  881. }
  882. public int beginLoop() {
  883. continueLabels.push(new Label());
  884. breakLabels.push(new Label());
  885. int savebcf = bcfLevel;
  886. bcfLevel = exceptionHandlers.size();
  887. return savebcf;
  888. }
  889. public void finishLoop(int savebcf) {
  890. continueLabels.pop();
  891. breakLabels.pop();
  892. bcfLevel = savebcf;
  893. }
  894. @Override
  895. public Object visitWhile(While node) throws Exception {
  896. int savebcf = beginLoop();
  897. Label continue_loop = (Label)continueLabels.peek();
  898. Label break_loop = (Label)breakLabels.peek();
  899. Label start_loop = new Label();
  900. code.goto_(continue_loop);
  901. code.label(start_loop);
  902. //Do suite
  903. suite(node.getInternalBody());
  904. code.label(continue_loop);
  905. setline(node);
  906. //Do test
  907. visit(node.getInternalTest());
  908. code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z");
  909. code.ifne(start_loop);
  910. finishLoop(savebcf);
  911. if (node.getInternalOrelse() != null) {
  912. //Do else
  913. suite(node.getInternalOrelse());
  914. }
  915. code.label(break_loop);
  916. // Probably need to detect "guaranteed exits"
  917. return null;
  918. }
  919. @Override
  920. public Object visitFor(For node) throws Exception {
  921. int savebcf = beginLoop();
  922. Label continue_loop = (Label)continueLabels.peek();
  923. Label break_loop = (Label)breakLabels.peek();
  924. Label start_loop = new Label();
  925. Label next_loop = new Label();
  926. int iter_tmp = code.getLocal("org/python/core/PyObject");
  927. int expr_tmp = code.getLocal("org/python/core/PyObject");
  928. setline(node);
  929. //parse the list
  930. visit(node.getInternalIter());
  931. //set up the loop iterator
  932. code.invokevirtual("org/python/core/PyObject", "__iter__", "()Lorg/python/core/PyObject;");
  933. code.astore(iter_tmp);
  934. //do check at end of loop. Saves one opcode ;-)
  935. code.goto_(next_loop);
  936. code.label(start_loop);
  937. //set iter variable to current entry in list
  938. set(node.getInternalTarget(), expr_tmp);
  939. //evaluate for body
  940. suite(node.getInternalBody());
  941. code.label(continue_loop);
  942. code.label(next_loop);
  943. setline(node);
  944. //get the next element from the list
  945. code.aload(iter_tmp);
  946. code.invokevirtual("org/python/core/PyObject", "__iternext__", "()" + $pyObj);
  947. code.astore(expr_tmp);
  948. code.aload(expr_tmp);
  949. //if no more elements then fall through
  950. code.ifnonnull(start_loop);
  951. finishLoop(savebcf);
  952. if (node.getInternalOrelse() != null) {
  953. //Do else clause if provided
  954. suite(node.getInternalOrelse());
  955. }
  956. code.label(break_loop);
  957. code.freeLocal(iter_tmp);
  958. code.freeLocal(expr_tmp);
  959. // Probably need to detect "guaranteed exits"
  960. return null;
  961. }
  962. public void exceptionTest(int exc, Label end_of_exceptions,
  963. TryExcept node, int index)
  964. throws Exception
  965. {
  966. for (int i = 0; i < node.getInternalHandlers().size(); i++) {
  967. ExceptHandler handler = (ExceptHandler)node.getInternalHandlers().get(i);
  968. //setline(name);
  969. Label end_of_self = new Label();
  970. if (handler.getInternalType() != null) {
  971. code.aload(exc);
  972. //get specific exception
  973. visit(handler.getInternalType());
  974. code.invokevirtual("org/python/core/PyException", "match", "(" + $pyObj + ")Z");
  975. code.ifeq(end_of_self);
  976. } else {
  977. if (i != node.getInternalHandlers().size()-1) {
  978. throw new ParseException(
  979. "default 'except:' must be last", handler);
  980. }
  981. }
  982. if (handler.getInternalName() != null) {
  983. code.aload(exc);
  984. code.getfield("org/python/core/PyException", "value", "Lorg/python/core/PyObject;");
  985. set(handler.getInternalName());
  986. }
  987. //do exception body
  988. suite(handler.getInternalBody());
  989. code.goto_(end_of_exceptions);
  990. code.label(end_of_self);
  991. }
  992. code.aload(exc);
  993. code.athrow();
  994. }
  995. @Override
  996. public Object visitTryFinally(TryFinally node) throws Exception
  997. {
  998. Label start = new Label();
  999. Label end = new Label();
  1000. Label handlerStart = new Label();
  1001. Label finallyEnd = new Label();
  1002. Object ret;
  1003. ExceptionHandler inFinally = new ExceptionHandler(node);
  1004. // Do protected suite
  1005. exceptionHandlers.push(inFinally);
  1006. int excLocal = code.getLocal("java/lang/Throwable");
  1007. code.aconst_null();
  1008. code.astore(excLocal);
  1009. code.label(start);
  1010. inFinally.exceptionStarts.addElement(start);
  1011. ret = suite(node.getInternalBody());
  1012. code.label(end);
  1013. inFinally.exceptionEnds.addElement(end);
  1014. inFinally.bodyDone = true;
  1015. exceptionHandlers.pop();
  1016. if (ret == NoExit) {
  1017. inlineFinally(inFinally);
  1018. code.goto_(finallyEnd);
  1019. }
  1020. // Handle any exceptions that get thrown in suite
  1021. code.label(handlerStart);
  1022. code.astore(excLocal);
  1023. code.aload(excLocal);
  1024. loadFrame();
  1025. code.invokestatic("org/python/core/Py", "addTraceback", "(" + $throwable + $pyFrame + ")V");
  1026. inlineFinally(inFinally);
  1027. code.aload(excLocal);
  1028. code.checkcast("java/lang/Throwable");
  1029. code.athrow();
  1030. code.label(finallyEnd);
  1031. code.freeLocal(excLocal);
  1032. inFinally.addExceptionHandlers(handlerStart);
  1033. // According to any JVM verifiers, this code block might not return
  1034. return null;
  1035. }
  1036. private void inlineFinally(ExceptionHandler handler) throws Exception {
  1037. if (!handler.bodyDone) {
  1038. // end the previous exception block so inlined finally code doesn't
  1039. // get covered by our exception handler.
  1040. Label end = new Label();
  1041. code.label(end);
  1042. handler.exceptionEnds.addElement(end);
  1043. // also exiting the try: portion of this particular finally
  1044. }
  1045. if (handler.isFinallyHandler()) {
  1046. handler.finalBody(this);
  1047. }
  1048. }
  1049. private void reenterProtectedBody(ExceptionHandler handler) throws Exception {
  1050. // restart exception coverage
  1051. Label restart = new Label();
  1052. code.label(restart);
  1053. handler.exceptionStarts.addElement(restart);
  1054. }
  1055. /**
  1056. * Inline the finally handling code for levels down to the levelth parent
  1057. * (0 means all). This takes care to avoid having more nested finallys
  1058. * catch exceptions throw by the parent finally code. This also pops off
  1059. * all the handlers above level temporarily.
  1060. */
  1061. private void doFinallysDownTo(int level) throws Exception {
  1062. Stack poppedHandlers = new Stack();
  1063. while (exceptionHandlers.size() > level) {
  1064. ExceptionHandler handler =
  1065. (ExceptionHandler)exceptionHandlers.pop();
  1066. inlineFinally(handler);
  1067. poppedHandlers.push(handler);
  1068. }
  1069. while (poppedHandlers.size() > 0) {
  1070. ExceptionHandler handler =
  1071. (ExceptionHandler)poppedHandlers.pop();
  1072. reenterProtectedBody(handler);
  1073. exceptionHandlers.push(handler);
  1074. }
  1075. }
  1076. @Override
  1077. public Object visitTryExcept(TryExcept node) throws Exception {
  1078. Label start = new Label();
  1079. Label end = new Label();
  1080. Label handler_start = new Label();
  1081. Label handler_end = new Label();
  1082. ExceptionHandler handler = new ExceptionHandler();
  1083. code.label(start);
  1084. handler.exceptionStarts.addElement(start);
  1085. exceptionHandlers.push(handler);
  1086. //Do suite
  1087. Object exit = suite(node.getInternalBody());
  1088. exceptionHandlers.pop();
  1089. code.label(end);
  1090. handler.exceptionEnds.addElement(end);
  1091. if (exit == null)
  1092. code.goto_(handler_end);
  1093. code.label(handler_start);
  1094. loadFrame();
  1095. code.invokestatic("org/python/core/Py", "setException", "(" + $throwable + $pyFrame + ")" + $pyExc);
  1096. int exc = code.getFinallyLocal("java/lang/Throwable");
  1097. code.astore(exc);
  1098. if (node.getInternalOrelse() == null) {
  1099. //No else clause to worry about
  1100. exceptionTest(exc, handler_end, node, 1);
  1101. code.label(handler_end);
  1102. } else {
  1103. //Have else clause
  1104. Label else_end = new Label();
  1105. exceptionTest(exc, else_end, node, 1);
  1106. code.label(handler_end);
  1107. //do else clause
  1108. suite(node.getInternalOrelse());
  1109. code.label(else_end);
  1110. }
  1111. code.freeFinallyLocal(exc);
  1112. handler.addExceptionHandlers(handler_start);
  1113. return null;
  1114. }
  1115. @Override
  1116. public Object visitSuite(Suite node) throws Exception {
  1117. return suite(node.getInternalBody());
  1118. }
  1119. public Object suite(java.util.List<stmt> stmts) throws Exception {
  1120. for(stmt s: stmts) {
  1121. Object exit = visit(s);
  1122. if (exit != null)
  1123. return Exit;
  1124. }
  1125. return null;
  1126. }
  1127. @Override
  1128. public Object visitBoolOp(BoolOp node) throws Exception {
  1129. Label end = new Label();
  1130. visit(node.getInternalValues().get(0));
  1131. for (int i = 1; i < node.getInternalValues().size(); i++) {
  1132. code.dup();
  1133. code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z");
  1134. switch (node.getInternalOp()) {
  1135. case Or :
  1136. code.ifne(end);
  1137. break;
  1138. case And :
  1139. code.ifeq(end);
  1140. break;
  1141. }
  1142. code.pop();
  1143. visit(node.getInternalValues().get(i));
  1144. }
  1145. code.label(end);
  1146. return null;
  1147. }
  1148. @Override
  1149. public Object visitCompare(Compare node) throws Exception {
  1150. int last = code.getLocal("org/python/core/PyObject");
  1151. int result = code.getLocal("org/python/core/PyObject");
  1152. Label end = new Label();
  1153. visit(node.getInternalLeft());
  1154. code.astore(last);
  1155. int n = node.getInternalOps().size();
  1156. for(int i = 0; i < n - 1; i++) {
  1157. visit(node.getInternalComparators().get(i));
  1158. code.aload(last);
  1159. code.swap();
  1160. code.dup();
  1161. code.astore(last);
  1162. visitCmpop(node.getInternalOps().get(i));
  1163. code.dup();
  1164. code.astore(result);
  1165. code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z");
  1166. code.ifeq(end);
  1167. }
  1168. visit(node.getInternalComparators().get(n-1));
  1169. code.aload(last);
  1170. code.swap();
  1171. visitCmpop(node.getInternalOps().get(n-1));
  1172. if (n > 1) {
  1173. code.astore(result);
  1174. code.label(end);
  1175. code.aload(result);
  1176. }
  1177. code.aconst_null();
  1178. code.astore(last);
  1179. code.freeLocal(last);
  1180. code.freeLocal(result);
  1181. return null;
  1182. }
  1183. public void visitCmpop(cmpopType op) throws Exception {
  1184. String name = null;
  1185. switch (op) {
  1186. case Eq: name = "_eq"; break;
  1187. case NotEq: name = "_ne"; break;
  1188. case Lt: name = "_lt"; break;
  1189. case LtE: name = "_le"; break;
  1190. case Gt: name = "_gt"; break;
  1191. case GtE: name = "_ge"; break;
  1192. case Is: name = "_is"; break;
  1193. case IsNot: name = "_isnot"; break;
  1194. case In: name = "_in"; break;
  1195. case NotIn: name = "_notin"; break;
  1196. }
  1197. code.invokevirtual("org/python/core/PyObject", name, "(" + $pyObj + ")" + $pyObj);
  1198. }
  1199. @Override
  1200. public Object visitBinOp(BinOp node) throws Exception {
  1201. visit(node.getInternalLeft());
  1202. stackProduce();
  1203. visit(node.getInternalRight());
  1204. stackConsume();
  1205. String name = null;
  1206. switch (node.getInternalOp()) {
  1207. case Add: name = "_add"; break;
  1208. case Sub: name = "_sub"; break;
  1209. case Mult: name = "_mul"; break;
  1210. case Div: name = "_div"; break;
  1211. case Mod: name = "_mod"; break;
  1212. case Pow: name = "_pow"; break;
  1213. case LShift: name = "_lshift"; break;
  1214. case RShift: name = "_rshift"; break;
  1215. case BitOr: name = "_or"; break;
  1216. case BitXor: name = "_xor"; break;
  1217. case BitAnd: name = "_and"; break;
  1218. case FloorDiv: name = "_floordiv"; break;
  1219. }
  1220. if (node.getInternalOp() == operatorType.Div && module.getFutures().areDivisionOn()) {
  1221. name = "_truediv";
  1222. }
  1223. code.invokevirtual("org/python/core/PyObject", name, "(" + $pyObj + ")" + $pyObj);
  1224. return null;
  1225. }
  1226. @Override
  1227. public Object visitUnaryOp(UnaryOp node) throws Exception {
  1228. visit(node.getInternalOperand());
  1229. String name = null;
  1230. switch (node.getInternalOp()) {
  1231. case Invert: name = "__invert__"; break;
  1232. case Not: name = "__not__"; break;
  1233. case UAdd: name = "__pos__"; break;
  1234. case USub: name = "__neg__"; break;
  1235. }
  1236. code.invokevirtual("org/python/core/PyObject", name, "()" + $pyObj);
  1237. return null;
  1238. }
  1239. @Override
  1240. public Object visitAugAssign(AugAssign node) throws Exception {
  1241. setline(node);
  1242. augmode = expr_contextType.Load;
  1243. visit(node.getInternalTarget());
  1244. int target = storeTop();
  1245. visit(node.getInternalValue());
  1246. code.aload(target);
  1247. code.swap();
  1248. String name = null;
  1249. switch (node.getInternalOp()) {
  1250. case Add: name = "_iadd"; break;
  1251. case Sub: name = "_isub"; break;
  1252. case Mult: name = "_imul"; break;
  1253. case Div: name = "_idiv"; break;
  1254. case Mod: name = "_imod"; break;
  1255. case Pow: name = "_ipow"; break;
  1256. case LShift: name = "_ilshift"; break;
  1257. case RShift: name = "_irshift"; break;
  1258. case BitOr: name = "_ior"; break;
  1259. case BitXor: name = "_ixor"; break;
  1260. case BitAnd: name = "_iand"; break;
  1261. case FloorDiv: name = "_ifloordiv"; break;
  1262. }
  1263. if (node.getInternalOp() == operatorType.Div && module.getFutures().areDivisionOn()) {
  1264. name = "_itruediv";
  1265. }
  1266. code.invokevirtual("org/python/core/PyObject", name, "(" + $pyObj + ")" + $pyObj);
  1267. code.freeLocal(target);
  1268. temporary = storeTop();
  1269. augmode = expr_contextType.Store;
  1270. visit(node.getInternalTarget());
  1271. code.freeLocal(temporary);
  1272. return null;
  1273. }
  1274. public static int makeStrings(Code c, Collection<String> names)
  1275. throws IOException
  1276. {
  1277. if (names != null) {
  1278. c.iconst(names.size());
  1279. } else {
  1280. c.iconst_0();
  1281. }
  1282. c.anewarray("java/lang/String");
  1283. int strings = c.getLocal("[Ljava/lang/String;");
  1284. c.astore(strings);
  1285. if (names != null) {
  1286. int i = 0;
  1287. for (String name : names) {
  1288. c.aload(strings);
  1289. c.iconst(i);
  1290. c.ldc(name);
  1291. c.aastore();
  1292. i++;
  1293. }
  1294. }
  1295. return strings;
  1296. }
  1297. public Object invokeNoKeywords(Attribute node, java.util.List<expr> values)
  1298. throws Exception
  1299. {
  1300. String name = getName(node.getInternalAttr());
  1301. visit(node.getInternalValue()); stackProduce();
  1302. code.ldc(name);
  1303. code.invokevirtual("org/python/core/PyObject", "__getattr__", "(" + $str + ")" + $pyObj);
  1304. loadThreadState(); stackProduce("org/python/core/ThreadState");
  1305. switch (values.size()) {
  1306. case 0:
  1307. stackConsume(2); // target + ts
  1308. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + ")" + $pyObj);
  1309. break;
  1310. case 1:
  1311. visit(values.get(0));
  1312. stackConsume(2); // target + ts
  1313. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + ")" + $pyObj);
  1314. break;
  1315. case 2:
  1316. visit(values.get(0)); stackProduce();
  1317. visit(values.get(1));
  1318. stackConsume(3); // target + ts + arguments
  1319. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + $pyObj + ")" + $pyObj);
  1320. break;
  1321. case 3:
  1322. visit(values.get(0)); stackProduce();
  1323. visit(values.get(1)); stackProduce();
  1324. visit(values.get(2));
  1325. stackConsume(4); // target + ts + arguments
  1326. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + $pyObj + $pyObj + ")" + $pyObj);
  1327. break;
  1328. case 4:
  1329. visit(values.get(0)); stackProduce();
  1330. visit(values.get(1)); stackProduce();
  1331. visit(values.get(2)); stackProduce();
  1332. visit(values.get(3));
  1333. stackConsume(5); // target + ts + arguments
  1334. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + $pyObj + $pyObj + $pyObj + ")" + $pyObj);
  1335. break;
  1336. default:
  1337. int argArray = makeArray(values);
  1338. code.aload(argArray);
  1339. code.freeLocal(argArray);
  1340. stackConsume(2); // target + ts
  1341. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObjArr + ")" + $pyObj);
  1342. break;
  1343. }
  1344. return null;
  1345. }
  1346. @Override
  1347. public Object visitCall(Call node) throws Exception {
  1348. java.util.List<String> keys = new ArrayList<String>();//[node.keywords.size()];
  1349. java.util.List<expr> values = new ArrayList<expr>();//[node.args.size() + keys.size()];
  1350. for (int i = 0; i < node.getInternalArgs().size(); i++) {
  1351. values.add(node.getInternalArgs().get(i));
  1352. }
  1353. for (int i = 0; i < node.getInternalKeywords().size(); i++) {
  1354. keys.add(node.getInternalKeywords().get(i).getInternalArg());
  1355. values.add(node.getInternalKeywords().get(i).getInternalValue());
  1356. }
  1357. if ((node.getInternalKeywords() == null || node.getInternalKeywords().size() == 0)&& node.getInternalStarargs() == null &&
  1358. node.getInternalKwargs() == null && node.getInternalFunc() instanceof Attribute)
  1359. {
  1360. return invokeNoKeywords((Attribute) node.getInternalFunc(), values);
  1361. }
  1362. visit(node.getInternalFunc()); stackProduce();
  1363. if (node.getInternalStarargs() != null || node.getInternalKwargs() != null) {
  1364. int argArray = makeArray(values);
  1365. int strArray = makeStrings(code, keys);
  1366. if (node.getInternalStarargs() == null)
  1367. code.aconst_null();
  1368. else
  1369. visit(node.getInternalStarargs());
  1370. stackProduce();
  1371. if (node.getInternalKwargs() == null)
  1372. code.aconst_null();
  1373. else
  1374. visit(node.getInternalKwargs());
  1375. stackProduce();
  1376. code.aload(argArray);
  1377. code.aload(strArray);
  1378. code.freeLocal(argArray);
  1379. code.freeLocal(strArray);
  1380. code.dup2_x2();
  1381. code.pop2();
  1382. stackConsume(3); // target + starargs + kwargs
  1383. code.invokevirtual("org/python/core/PyObject", "_callextra", "(" + $pyObjArr + $strArr + $pyObj + $pyObj + ")" + $pyObj);
  1384. } else if (keys.size() > 0) {
  1385. loadThreadState(); stackProduce("org/python/core/ThreadState");
  1386. int argArray = makeArray(values);
  1387. int strArray = makeStrings(code, keys);
  1388. code.aload(argArray);
  1389. code.aload(strArray);
  1390. code.freeLocal(argArray);
  1391. code.freeLocal(strArray);
  1392. stackConsume(2); // target + ts
  1393. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObjArr + $strArr + ")" + $pyObj);
  1394. } else {
  1395. loadThreadState(); stackProduce("org/python/core/ThreadState");
  1396. switch (values.size()) {
  1397. case 0:
  1398. stackConsume(2); // target + ts
  1399. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + ")" + $pyObj);
  1400. break;
  1401. case 1:
  1402. visit(values.get(0));
  1403. stackConsume(2); // target + ts
  1404. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + ")" + $pyObj);
  1405. break;
  1406. case 2:
  1407. visit(values.get(0)); stackProduce();
  1408. visit(values.get(1));
  1409. stackConsume(3); // target + ts + arguments
  1410. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + $pyObj + ")" + $pyObj);
  1411. break;
  1412. case 3:
  1413. visit(values.get(0)); stackProduce();
  1414. visit(values.get(1)); stackProduce();
  1415. visit(values.get(2));
  1416. stackConsume(4); // target + ts + arguments
  1417. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + $pyObj + $pyObj + ")" + $pyObj);
  1418. break;
  1419. case 4:
  1420. visit(values.get(0)); stackProduce();
  1421. visit(values.get(1)); stackProduce();
  1422. visit(values.get(2)); stackProduce();
  1423. visit(values.get(3));
  1424. stackConsume(5); // target + ts + arguments
  1425. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + $pyObj + $pyObj + $pyObj + ")" + $pyObj);
  1426. break;
  1427. default:
  1428. int argArray = makeArray(values);
  1429. code.aload(argArray);
  1430. code.freeLocal(argArray);
  1431. stackConsume(2); // target + ts
  1432. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObjArr + ")" + $pyObj);// freeArray(argArray);
  1433. break;
  1434. }
  1435. }
  1436. return null;
  1437. }
  1438. public Object Slice(Subscript node, Slice slice) throws Exception {
  1439. expr_contextType ctx = node.getInternalCtx();
  1440. if (ctx == expr_contextType.AugStore && augmode == expr_contextType.Store) {
  1441. restoreAugTmps(node, 4);
  1442. ctx = expr_contextType.Store;
  1443. } else {
  1444. visit(node.getInternalValue());
  1445. stackProduce();
  1446. if (slice.getInternalLower() != null)
  1447. visit(slice.getInternalLower());
  1448. else
  1449. code.aconst_null();
  1450. stackProduce();
  1451. if (slice.getInternalUpper() != null)
  1452. visit(slice.getInternalUpper());
  1453. else
  1454. code.aconst_null();
  1455. stackProduce();
  1456. if (slice.getInternalStep() != null)
  1457. visit(slice.getInternalStep());
  1458. else
  1459. code.aconst_null();
  1460. stackProduce();
  1461. if (node.getInternalCtx() == expr_contextType.AugStore && augmode == expr_contextType.Load) {
  1462. saveAugTmps(node, 4);
  1463. ctx = expr_contextType.Load;
  1464. }
  1465. stackConsume(4);
  1466. }
  1467. switch (ctx) {
  1468. case Del:
  1469. code.invokevirtual("org/python/core/PyObject", "__delslice__", "(" + $pyObj + $pyObj + $pyObj + ")V");
  1470. return null;
  1471. case Load:
  1472. code.invokevirtual("org/python/core/PyObject", "__getslice__", "(" + $pyObj + $pyObj + $pyObj + ")" + $pyObj);
  1473. return null;
  1474. case Param:
  1475. case Store:
  1476. code.aload(temporary);
  1477. code.invokevirtual("org/python/core/PyObject", "__setslice__", "(" + $pyObj + $pyObj + $pyObj + $pyObj + ")V");
  1478. return null;
  1479. }
  1480. return null;
  1481. }
  1482. @Override
  1483. public Object visitSubscript(Subscript node) throws Exception {
  1484. if (node.getInternalSlice() instanceof Slice) {
  1485. return Slice(node, (Slice) node.getInternalSlice());
  1486. }
  1487. int value = temporary;
  1488. expr_contextType ctx = node.getInternalCtx();
  1489. if (node.getInternalCtx() == expr_contextType.AugStore && augmode == expr_contextType.Store) {
  1490. restoreAugTmps(node, 2);
  1491. ctx = expr_contextType.Store;
  1492. } else {
  1493. visit(node.getInternalValue()); stackProduce();
  1494. visit(node.getInternalSlice());
  1495. stackConsume();
  1496. if (node.getInternalCtx() == expr_contextType.AugStore && augmode == expr_contextType.Load) {
  1497. saveAugTmps(node, 2);
  1498. ctx = expr_contextType.Load;
  1499. }
  1500. }
  1501. switch (ctx) {
  1502. case Del:
  1503. code.invokevirtual("org/python/core/PyObject", "__delitem__", "(" + $pyObj + ")V");
  1504. return null;
  1505. case Load:
  1506. code.invokevirtual("org/python/core/PyObject", "__getitem__", "(" + $pyObj + ")" + $pyObj);
  1507. return null;
  1508. case Param:
  1509. case Store:
  1510. code.aload(value);
  1511. code.invokevirtual("org/python/core/PyObject", "__setitem__", "(" + $pyObj + $pyObj + ")V");
  1512. return null;
  1513. }
  1514. return null;
  1515. }
  1516. @Override
  1517. public Object visitIndex(Index node) throws Exception {
  1518. traverse(node);
  1519. return null;
  1520. }
  1521. @Override
  1522. public Object visitExtSlice(ExtSlice node) throws Exception {
  1523. int dims = makeArray(node.getInternalDims());
  1524. code.new_("org/python/core/PyTuple");
  1525. code.dup();
  1526. code.aload(dims);
  1527. code.invokespecial("org/python/core/PyTuple", "<init>", "(" + $pyObjArr + ")V");
  1528. freeArray(dims);
  1529. return null;
  1530. }
  1531. @Override
  1532. public Object visitAttribute(Attribute node) throws Exception {
  1533. expr_contextType ctx = node.getInternalCtx();
  1534. if (node.getInternalCtx() == expr_contextType.AugStore && augmode == expr_contextType.Store) {
  1535. restoreAugTmps(node, 2);
  1536. ctx = expr_contextType.Store;
  1537. } else {
  1538. visit(node.getInternalValue());
  1539. code.ldc(getName(node.getInternalAttr()));
  1540. if (node.getInternalCtx() == expr_contextType.AugStore && augmode == expr_contextType.Load) {
  1541. saveAugTmps(node, 2);
  1542. ctx = expr_contextType.Load;
  1543. }
  1544. }
  1545. switch (ctx) {
  1546. case Del:
  1547. code.invokevirtual("org/python/core/PyObject", "__delattr__", "(" + $str + ")V");
  1548. return null;
  1549. case Load:
  1550. code.invokevirtual("org/python/core/PyObject", "__getattr__", "(" + $str + ")" + $pyObj);
  1551. return null;
  1552. case Param:
  1553. case Store:
  1554. code.aload(temporary);
  1555. code.invokevirtual("org/python/core/PyObject", "__setattr__", "(" + $str + $pyObj + ")V");
  1556. return null;
  1557. }
  1558. return null;
  1559. }
  1560. public Object seqSet(java.util.List<expr> nodes) throws Exception {
  1561. code.aload(temporary);
  1562. code.iconst(nodes.size());
  1563. code.invokestatic("org/python/core/Py", "unpackSequence", "(" + $pyObj + "I)" + $pyObjArr);
  1564. int tmp = code.getLocal("[org/python/core/PyObject");
  1565. code.astore(tmp);
  1566. for (int i = 0; i < nodes.size(); i++) {
  1567. code.aload(tmp);
  1568. code.iconst(i);
  1569. code.aaload();
  1570. set(nodes.get(i));
  1571. }
  1572. code.freeLocal(tmp);
  1573. return null;
  1574. }
  1575. public Object seqDel(java.util.List<expr> nodes) throws Exception {
  1576. for (expr e: nodes) {
  1577. visit(e);
  1578. }
  1579. return null;
  1580. }
  1581. @Override
  1582. public Object visitTuple(Tuple node) throws Exception {
  1583. /* if (mode ==AUGSET)
  1584. throw new ParseException(
  1585. "augmented assign to tuple not possible", node); */
  1586. if (node.getInternalCtx() == expr_contextType.Store) return seqSet(node.getInternalElts());
  1587. if (node.getInternalCtx() == expr_contextType.Del) return seqDel(node.getInternalElts());
  1588. int content = makeArray(node.getInternalElts());
  1589. code.new_("org/python/core/PyTuple");
  1590. code.dup();
  1591. code.aload(content);
  1592. code.invokespecial("org/python/core/PyTuple", "<init>", "(" + $pyObjArr + ")V");
  1593. freeArray(content);
  1594. return null;
  1595. }
  1596. @Override
  1597. public Object visitList(List node) throws Exception {
  1598. if (node.getInternalCtx() == expr_contextType.Store) return seqSet(node.getInternalElts());
  1599. if (node.getInternalCtx() == expr_contextType.Del) return seqDel(node.getInternalElts());
  1600. int content = makeArray(node.getInternalElts());
  1601. code.new_("org/python/core/PyList");
  1602. code.dup();
  1603. code.aload(content);
  1604. code.invokespecial("org/python/core/PyList", "<init>", "(" + $pyObjArr + ")V");
  1605. freeArray(content);
  1606. return null;
  1607. }
  1608. @Override
  1609. public Object visitListComp(ListComp node) throws Exception {
  1610. code.new_("org/python/core/PyList");
  1611. code.dup();
  1612. code.invokespecial("org/python/core/PyList", "<init>", "()V");
  1613. code.dup();
  1614. code.ldc("append");
  1615. code.invokevirtual("org/python/core/PyObject", "__getattr__", "(" + $str + ")" + $pyObj);
  1616. String tmp_append ="_[" + node.getLine() + "_" + node.getCharPositionInLine() + "]";
  1617. set(new Name(node, tmp_append, expr_contextType.Store));
  1618. java.util.List<expr> args = new ArrayList<expr>();
  1619. args.add(node.getInternalElt());
  1620. stmt n = new Expr(node, new Call(node, new Name(node, tmp_append, expr_contextType.Load),
  1621. args,
  1622. new ArrayList<keyword>(), null, null));
  1623. for (int i = node.getInternalGenerators().size() - 1; i >= 0; i--) {
  1624. comprehension lc = node.getInternalGenerators().get(i);
  1625. for (int j = lc.getInternalIfs().size() - 1; j >= 0; j--) {
  1626. java.util.List<stmt> body = new ArrayList<stmt>();
  1627. body.add(n);
  1628. n = new If(lc.getInternalIfs().get(j), lc.getInternalIfs().get(j), body, new ArrayList<stmt>());
  1629. }
  1630. java.util.List<stmt> body = new ArrayList<stmt>();
  1631. body.add(n);
  1632. n = new For(lc,lc.getInternalTarget(), lc.getInternalIter(), body, new ArrayList<stmt>());
  1633. }
  1634. visit(n);
  1635. java.util.List<expr> targets = new ArrayList<expr>();
  1636. targets.add(new Name(n, tmp_append, expr_contextType.Del));
  1637. visit(new Delete(n, targets));
  1638. return null;
  1639. }
  1640. @Override
  1641. public Object visitDict(Dict node) throws Exception {
  1642. java.util.List<PythonTree> elts = new ArrayList<PythonTree>();
  1643. for (int i = 0; i < node.getInternalKeys().size(); i++) {
  1644. elts.add(node.getInternalKeys().get(i));
  1645. elts.add(node.getInternalValues().get(i));
  1646. }
  1647. int content = makeArray(elts);
  1648. code.new_("org/python/core/PyDictionary");
  1649. code.dup();
  1650. code.aload(content);
  1651. code.invokespecial("org/python/core/PyDictionary", "<init>", "(" + $pyObjArr + ")V");
  1652. freeArray(content);
  1653. return null;
  1654. }
  1655. @Override
  1656. public Object visitRepr(Repr node) throws Exception {
  1657. visit(node.getInternalValue());
  1658. code.invokevirtual("org/python/core/PyObject", "__repr__", "()" + $pyStr);
  1659. return null;
  1660. }
  1661. @Override
  1662. public Object visitLambda(Lambda node) throws Exception {
  1663. String name = "<lambda>";
  1664. //Add a return node onto the outside of suite;
  1665. java.util.List<stmt> bod = new ArrayList<stmt>();
  1666. bod.add(new Return(node,node.getInternalBody()));
  1667. mod retSuite = new Suite(node, bod);
  1668. setline(node);
  1669. ScopeInfo scope = module.getScopeInfo(node);
  1670. int defaultsArray = makeArray(scope.ac.getDefaults());
  1671. code.new_("org/python/core/PyFunction");
  1672. code.dup();
  1673. code.aload(defaultsArray);
  1674. code.freeLocal(defaultsArray);
  1675. loadFrame();
  1676. code.getfield("org/python/core/PyFrame", "f_globals", $pyObj);
  1677. code.swap();
  1678. scope.setup_closure();
  1679. scope.dump();
  1680. module.PyCode(retSuite, name, true, className,
  1681. false, false, node.getLine(), scope, cflags).get(code);
  1682. if (!makeClosure(scope)) {
  1683. code.invokespecial("org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + ")V");
  1684. } else {
  1685. code.invokespecial("org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObjArr + ")V");
  1686. }
  1687. return null;
  1688. }
  1689. @Override
  1690. public Object visitEllipsis(Ellipsis node) throws Exception {
  1691. code.getstatic("org/python/core/Py", "Ellipsis", "Lorg/python/core/PyObject;");
  1692. return null;
  1693. }
  1694. @Override
  1695. public Object visitSlice(Slice node) throws Exception {
  1696. if (node.getInternalLower() == null) getNone(); else visit(node.getInternalLower()); stackProduce();
  1697. if (node.getInternalUpper() == null) getNone(); else visit(node.getInternalUpper()); stackProduce();
  1698. if (node.getInternalStep() == null) getNone(); else visit(node.getInternalStep());
  1699. int step = storeTop();
  1700. stackConsume(2);
  1701. code.new_("org/python/core/PySlice");
  1702. code.dup();
  1703. code.dup2_x2();
  1704. code.pop2();
  1705. code.aload(step);
  1706. code.freeLocal(step);
  1707. code.invokespecial("org/python/core/PySlice", "<init>", "(" + $pyObj + $pyObj + $pyObj + ")V");
  1708. return null;
  1709. }
  1710. @Override
  1711. public Object visitClassDef(ClassDef node) throws Exception {
  1712. setline(node);
  1713. int baseArray = makeArray(node.getInternalBases());
  1714. //Get class name
  1715. String name = getName(node.getInternalName());
  1716. code.ldc(name);
  1717. code.aload(baseArray);
  1718. ScopeInfo scope = module.getScopeInfo(node);
  1719. scope.setup_closure();
  1720. scope.dump();
  1721. //Make code object out of suite
  1722. module.PyCode(new Suite(node,node.getInternalBody()), name, false, name,
  1723. true, false, node.getLine(), scope, cflags).get(code);
  1724. //Get doc string (if there)
  1725. getDocString(node.getInternalBody());
  1726. //Make class out of name, bases, and code
  1727. if (!makeClosure(scope)) {
  1728. code.invokestatic("org/python/core/Py", "makeClass", "(" + $str + $pyObjArr + $pyCode + $pyObj + ")" + $pyObj);
  1729. } else {
  1730. code.invokestatic("org/python/core/Py", "makeClass", "(" + $str + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")" + $pyObj);
  1731. }
  1732. applyDecorators(node.getInternalDecorator_list());
  1733. //Assign this new class to the given name
  1734. set(new Name(node,node.getInternalName(), expr_contextType.Store));
  1735. //doDecorators(node,node.getInternalDecorator_list(), node.getInternalName());
  1736. freeArray(baseArray);
  1737. return null;
  1738. }
  1739. @Override
  1740. public Object visitNum(Num node) throws Exception {
  1741. if (node.getInternalN() instanceof PyInteger) {
  1742. module.PyInteger(((PyInteger) node.getInternalN()).getValue()).get(code);
  1743. } else if (node.getInternalN() instanceof PyLong) {
  1744. module.PyLong(((PyObject)node.getInternalN()).__str__().toString()).get(code);
  1745. } else if (node.getInternalN() instanceof PyFloat) {
  1746. module.PyFloat(((PyFloat) node.getInternalN()).getValue()).get(code);
  1747. } else if (node.getInternalN() instanceof PyComplex) {
  1748. module.PyComplex(((PyComplex) node.getInternalN()).imag).get(code);
  1749. }
  1750. return null;
  1751. }
  1752. private String getName(String name) {
  1753. if (className != null && name.startsWith("__") &&
  1754. !name.endsWith("__"))
  1755. {
  1756. //remove leading '_' from classname
  1757. int i = 0;
  1758. while (className.charAt(i) == '_')
  1759. i++;
  1760. return "_"+className.substring(i)+name;
  1761. }
  1762. return name;
  1763. }
  1764. void emitGetGlobal(String name) throws Exception {
  1765. code.ldc(name);
  1766. code.invokevirtual("org/python/core/PyFrame", "getglobal", "(" + $str + ")" + $pyObj);
  1767. }
  1768. @Override
  1769. public Object visitName(Name node) throws Exception {
  1770. String name;
  1771. if (fast_locals)
  1772. name = node.getInternalId();
  1773. else
  1774. name = getName(node.getInternalId());
  1775. SymInfo syminf = tbl.get(name);
  1776. expr_contextType ctx = node.getInternalCtx();
  1777. if (ctx == expr_contextType.AugStore) {
  1778. ctx = augmode;
  1779. }
  1780. switch (ctx) {
  1781. case Load:
  1782. loadFrame();
  1783. if (syminf != null) {
  1784. int flags = syminf.flags;
  1785. if ((flags&ScopeInfo.GLOBAL) !=0 || optimizeGlobals&&
  1786. (flags&(ScopeInfo.BOUND|ScopeInfo.CELL|
  1787. ScopeInfo.FREE))==0) {
  1788. emitGetGlobal(name);
  1789. return null;
  1790. }
  1791. if (fast_locals) {
  1792. if ((flags&ScopeInfo.CELL) != 0) {
  1793. code.iconst(syminf.env_index);
  1794. code.invokevirtual("org/python/core/PyFrame", "getderef", "(I)" + $pyObj);
  1795. return null;
  1796. }
  1797. if ((flags&ScopeInfo.BOUND) != 0) {
  1798. code.iconst(syminf.locals_index);
  1799. code.invokevirtual("org/python/core/PyFrame", "getlocal", "(I)" + $pyObj);
  1800. return null;
  1801. }
  1802. }
  1803. if ((flags&ScopeInfo.FREE) != 0 &&
  1804. (flags&ScopeInfo.BOUND) == 0) {
  1805. code.iconst(syminf.env_index);
  1806. code.invokevirtual("org/python/core/PyFrame", "getderef", "(I)" + $pyObj);
  1807. return null;
  1808. }
  1809. }
  1810. code.ldc(name);
  1811. code.invokevirtual("org/python/core/PyFrame", "getname", "(" + $str + ")" + $pyObj);
  1812. return null;
  1813. case Param:
  1814. case Store:
  1815. loadFrame();
  1816. if (syminf != null && (syminf.flags&ScopeInfo.GLOBAL) != 0) {
  1817. code.ldc(name);
  1818. code.aload(temporary);
  1819. code.invokevirtual("org/python/core/PyFrame", "setglobal", "(" + $str + $pyObj + ")V");
  1820. } else {
  1821. if (!fast_locals) {
  1822. code.ldc(name);
  1823. code.aload(temporary);
  1824. code.invokevirtual("org/python/core/PyFrame", "setlocal", "(" + $str + $pyObj + ")V");
  1825. } else {
  1826. if (syminf == null) {
  1827. throw new ParseException("internal compiler error", node);
  1828. }
  1829. if ((syminf.flags&ScopeInfo.CELL) != 0) {
  1830. code.iconst(syminf.env_index);
  1831. code.aload(temporary);
  1832. code.invokevirtual("org/python/core/PyFrame", "setderef", "(I" + $pyObj + ")V");
  1833. } else {
  1834. code.iconst(syminf.locals_index);
  1835. code.aload(temporary);
  1836. code.invokevirtual("org/python/core/PyFrame", "setlocal", "(I" + $pyObj + ")V");
  1837. }
  1838. }
  1839. }
  1840. return null;
  1841. case Del: {
  1842. loadFrame();
  1843. if (syminf != null && (syminf.flags&ScopeInfo.GLOBAL) != 0) {
  1844. code.ldc(name);
  1845. code.invokevirtual("org/python/core/PyFrame", "delglobal", "(" + $str + ")V");
  1846. } else {
  1847. if (!fast_locals) {
  1848. code.ldc(name);
  1849. code.invokevirtual("org/python/core/PyFrame", "dellocal", "(" + $str + ")V");
  1850. } else {
  1851. if (syminf == null) {
  1852. throw new ParseException("internal compiler error", node);
  1853. }
  1854. if ((syminf.flags&ScopeInfo.CELL) != 0) {
  1855. module.error("can not delete variable '"+name+
  1856. "' referenced in nested scope",true,node);
  1857. }
  1858. code.iconst(syminf.locals_index);
  1859. code.invokevirtual("org/python/core/PyFrame", "dellocal", "(I)V");
  1860. }
  1861. }
  1862. return null; }
  1863. }
  1864. return null;
  1865. }
  1866. @Override
  1867. public Object visitStr(Str node) throws Exception {
  1868. PyString s = (PyString)node.getInternalS();
  1869. if (s instanceof PyUnicode) {
  1870. module.PyUnicode(s.asString()).get(code);
  1871. } else {
  1872. module.PyString(s.asString()).get(code);
  1873. }
  1874. return null;
  1875. }
  1876. @Override
  1877. public Object visitGeneratorExp(GeneratorExp node) throws Exception {
  1878. String bound_exp = "_(x)";
  1879. setline(node);
  1880. code.new_("org/python/core/PyFunction");
  1881. code.dup();
  1882. loadFrame();
  1883. code.getfield("org/python/core/PyFrame", "f_globals", $pyObj);
  1884. ScopeInfo scope = module.getScopeInfo(node);
  1885. int emptyArray = makeArray(new ArrayList<expr>());
  1886. code.aload(emptyArray);
  1887. scope.setup_closure();
  1888. scope.dump();
  1889. stmt n = new Expr(node, new Yield(node,node.getInternalElt()));
  1890. expr iter = null;
  1891. for (int i = node.getInternalGenerators().size() - 1; i >= 0; i--) {
  1892. comprehension comp = node.getInternalGenerators().get(i);
  1893. for (int j = comp.getInternalIfs().size() - 1; j >= 0; j--) {
  1894. java.util.List<stmt> bod = new ArrayList<stmt>();
  1895. bod.add(n);
  1896. n = new If(comp.getInternalIfs().get(j), comp.getInternalIfs().get(j), bod, new ArrayList<stmt>());
  1897. }
  1898. java.util.List<stmt> bod = new ArrayList<stmt>();
  1899. bod.add(n);
  1900. if (i != 0) {
  1901. n = new For(comp,comp.getInternalTarget(), comp.getInternalIter(), bod, new ArrayList<stmt>());
  1902. } else {
  1903. n = new For(comp,comp.getInternalTarget(), new Name(node, bound_exp, expr_contextType.Load), bod, new ArrayList<stmt>());
  1904. iter = comp.getInternalIter();
  1905. }
  1906. }
  1907. java.util.List<stmt> bod = new ArrayList<stmt>();
  1908. bod.add(n);
  1909. module.PyCode(new Suite(node, bod), "<genexpr>", true,
  1910. className, false, false,
  1911. node.getLine(), scope, cflags).get(code);
  1912. code.aconst_null();
  1913. if (!makeClosure(scope)) {
  1914. code.invokespecial("org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + ")V");
  1915. } else {
  1916. code.invokespecial( "org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")V");
  1917. }
  1918. int genExp = storeTop();
  1919. visit(iter);
  1920. code.aload(genExp);
  1921. code.freeLocal(genExp);
  1922. code.swap();
  1923. code.invokevirtual("org/python/core/PyObject", "__iter__", "()Lorg/python/core/PyObject;");
  1924. loadThreadState();
  1925. code.swap();
  1926. code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + ")" + $pyObj);
  1927. freeArray(emptyArray);
  1928. return null;
  1929. }
  1930. @Override
  1931. public Object visitWith(With node) throws Exception {
  1932. if (!module.getFutures().withStatementSupported()) {
  1933. throw new ParseException("'with' will become a reserved keyword in Python 2.6", node);
  1934. }
  1935. final Label label_body_start = new Label();
  1936. final Label label_body_end = new Label();
  1937. final Label label_catch = new Label();
  1938. final Label label_end = new Label();
  1939. final Method contextGuard_getManager = Method.getMethod("org.python.core.ContextManager getManager (org.python.core.PyObject)");
  1940. final Method __enter__ = Method.getMethod("org.python.core.PyObject __enter__ (org.python.core.ThreadState)");
  1941. final Method __exit__ = Method.getMethod("boolean __exit__ (org.python.core.ThreadState,org.python.core.PyException)");
  1942. // mgr = (EXPR)
  1943. visit(node.getInternalContext_expr());
  1944. // wrap the manager with the ContextGuard (or get it directly if it supports the ContextManager interface)
  1945. code.invokestatic(Type.getType(ContextGuard.class).getInternalName(), contextGuard_getManager.getName(), contextGuard_getManager.getDescriptor());
  1946. code.dup();
  1947. final int mgr_tmp = code.getLocal(Type.getType(ContextManager.class).getInternalName());
  1948. code.astore(mgr_tmp);
  1949. // value = mgr.__enter__()
  1950. loadThreadState();
  1951. code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __enter__.getName(), __enter__.getDescriptor());
  1952. int value_tmp = code.getLocal("org/python/core/PyObject");
  1953. code.astore(value_tmp);
  1954. // exc = True # not necessary, since we don't exec finally if exception
  1955. // FINALLY (preparation)
  1956. // ordinarily with a finally, we need to duplicate the code. that's not the case
  1957. // here
  1958. // # The normal and non-local-goto cases are handled here
  1959. // if exc: # implicit
  1960. // exit(None, None, None)
  1961. ExceptionHandler normalExit = new ExceptionHandler() {
  1962. @Override
  1963. public boolean isFinallyHandler() { return true; }
  1964. @Override
  1965. public void finalBody(CodeCompiler compiler) throws Exception {
  1966. compiler.code.aload(mgr_tmp);
  1967. loadThreadState();
  1968. compiler.code.aconst_null();
  1969. compiler.code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __exit__.getName(), __exit__.getDescriptor());
  1970. compiler.code.pop();
  1971. }
  1972. };
  1973. exceptionHandlers.push(normalExit);
  1974. // try-catch block here
  1975. ExceptionHandler handler = new ExceptionHandler();
  1976. exceptionHandlers.push(handler);
  1977. handler.exceptionStarts.addElement(label_body_start);
  1978. // VAR = value # Only if "as VAR" is present
  1979. code.label(label_body_start);
  1980. if (node.getInternalOptional_vars() != null) {
  1981. set(node.getInternalOptional_vars(), value_tmp);
  1982. }
  1983. code.freeLocal(value_tmp);
  1984. // BLOCK + FINALLY if non-local-goto
  1985. Object blockResult = suite(node.getInternalBody());
  1986. normalExit.bodyDone = true;
  1987. exceptionHandlers.pop();
  1988. exceptionHandlers.pop();
  1989. code.label(label_body_end);
  1990. handler.exceptionEnds.addElement(label_body_end);
  1991. // FINALLY if *not* non-local-goto
  1992. if (blockResult == NoExit) {
  1993. // BLOCK would have generated FINALLY for us if it exited (due to a break,
  1994. // continue or return)
  1995. inlineFinally(normalExit);
  1996. code.goto_(label_end);
  1997. }
  1998. // CATCH
  1999. code.label(label_catch);
  2000. loadFrame();
  2001. code.invokestatic("org/python/core/Py", "setException", "(" + $throwable + $pyFrame + ")" + $pyExc);
  2002. code.aload(mgr_tmp);
  2003. code.swap();
  2004. loadThreadState();
  2005. code.swap();
  2006. code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __exit__.getName(), __exit__.getDescriptor());
  2007. // # The exceptional case is handled here
  2008. // exc = False # implicit
  2009. // if not exit(*sys.exc_info()):
  2010. code.ifne(label_end);
  2011. // raise
  2012. // # The exception is swallowed if exit() returns true
  2013. code.invokestatic("org/python/core/Py", "makeException", "()Lorg/python/core/PyException;");
  2014. code.checkcast("java/lang/Throwable");
  2015. code.athrow();
  2016. code.label(label_end);
  2017. code.freeLocal(mgr_tmp);
  2018. handler.addExceptionHandlers(label_catch);
  2019. return null;
  2020. }
  2021. @Override
  2022. protected Object unhandled_node(PythonTree node) throws Exception {
  2023. throw new Exception("Unhandled node " + node);
  2024. }
  2025. /**
  2026. * Data about a given exception range whether a try:finally: or a
  2027. * try:except:. The finally needs to inline the finally block for
  2028. * each exit of the try: section, so we carry around that data for it.
  2029. *
  2030. * Both of these need to stop exception coverage of an area that is either
  2031. * the inlined fin ally of a parent try:finally: or the reentry block after
  2032. * a yield. Thus we keep around a set of exception ranges that the
  2033. * catch block will eventually handle.
  2034. */
  2035. class ExceptionHandler {
  2036. /**
  2037. * Each handler gets several exception ranges, this is because inlined
  2038. * finally exit code shouldn't be covered by the exception handler of
  2039. * that finally block. Thus each time we inline the finally code, we
  2040. * stop one range and then enter a new one.
  2041. *
  2042. * We also need to stop coverage for the recovery of the locals after
  2043. * a yield.
  2044. */
  2045. public Vector exceptionStarts = new Vector();
  2046. public Vector exceptionEnds = new Vector();
  2047. public boolean bodyDone = false;
  2048. public PythonTree node = null;
  2049. public ExceptionHandler() {
  2050. }
  2051. public ExceptionHandler(PythonTree n) {
  2052. node = n;
  2053. }
  2054. public boolean isFinallyHandler() {
  2055. return node != null;
  2056. }
  2057. public void addExceptionHandlers(Label handlerStart) throws Exception {
  2058. for (int i = 0; i < exceptionStarts.size(); ++i) {
  2059. Label start = (Label)exceptionStarts.elementAt(i);
  2060. Label end = (Label)exceptionEnds.elementAt(i);
  2061. //FIXME: not at all sure that getOffset() test is correct or necessary.
  2062. if (start.getOffset() != end.getOffset()) {
  2063. code.trycatch(
  2064. (Label)exceptionStarts.elementAt(i),
  2065. (Label)exceptionEnds.elementAt(i),
  2066. handlerStart,
  2067. "java/lang/Throwable");
  2068. }
  2069. }
  2070. }
  2071. public void finalBody(CodeCompiler compiler) throws Exception {
  2072. if (node instanceof TryFinally) {
  2073. suite(((TryFinally)node).getInternalFinalbody());
  2074. }
  2075. }
  2076. }
  2077. }