|
65 | 65 | import com.oracle.graal.python.builtins.objects.function.PArguments;
|
66 | 66 | import com.oracle.graal.python.builtins.objects.function.PKeyword;
|
67 | 67 | import com.oracle.graal.python.builtins.objects.function.Signature;
|
| 68 | +import com.oracle.graal.python.builtins.objects.generator.GeneratorControlData; |
68 | 69 | import com.oracle.graal.python.builtins.objects.generator.ThrowData;
|
69 | 70 | import com.oracle.graal.python.builtins.objects.list.ListBuiltins;
|
70 | 71 | import com.oracle.graal.python.builtins.objects.list.PList;
|
|
127 | 128 | import com.oracle.graal.python.nodes.subscript.DeleteItemNode;
|
128 | 129 | import com.oracle.graal.python.nodes.subscript.GetItemNode;
|
129 | 130 | import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
|
| 131 | +import com.oracle.graal.python.parser.GeneratorInfo; |
130 | 132 | import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext;
|
131 | 133 | import com.oracle.graal.python.runtime.PythonContext;
|
132 | 134 | import com.oracle.graal.python.runtime.PythonOptions;
|
@@ -343,6 +345,12 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
|
343 | 345 | }
|
344 | 346 | };
|
345 | 347 |
|
| 348 | + /* |
| 349 | + * Create fake GeneratorControlData just to maintain the same generator frame layout as AST |
| 350 | + * interpreter. TODO remove |
| 351 | + */ |
| 352 | + public static final GeneratorControlData GENERATOR_CONTROL_DATA = new GeneratorControlData(new GeneratorInfo(new GeneratorInfo.Mutable())); |
| 353 | + |
346 | 354 | private final Signature signature;
|
347 | 355 | private final String name;
|
348 | 356 | private boolean pythonInternal;
|
@@ -398,19 +406,21 @@ public int bciToLine(int bci) {
|
398 | 406 | }
|
399 | 407 |
|
400 | 408 | public int getBci(Frame frame) {
|
401 |
| - /* |
402 |
| - * Integer values throw FrameSlotTypeException when accessed before being set. The bci |
403 |
| - * value is set upon exception or in generators, but not on normal return, which is the |
404 |
| - * most common case, so we use getValue to avoid the exception. |
405 |
| - * |
406 |
| - * TODO when the static slot API is merged, we should use that, the static slots should |
407 |
| - * be initialized to 0 |
408 |
| - */ |
409 |
| - Integer bci = (Integer) frame.getValue(rootNode.bcioffset); |
410 |
| - if (bci == null) { |
411 |
| - return -1; |
| 409 | + if (frame.isInt(rootNode.bcioffset)) { |
| 410 | + return frame.getInt(rootNode.bcioffset); |
| 411 | + } |
| 412 | + return -1; |
| 413 | + } |
| 414 | + |
| 415 | + public Object getYieldFrom(Frame generatorFrame) { |
| 416 | + int bci = getBci(generatorFrame); |
| 417 | + /* Match the `yield from` bytecode pattern and get the object from stack */ |
| 418 | + if (bci > 3 && rootNode.bytecode[bci - 3] == OpCodesConstants.SEND && rootNode.bytecode[bci - 1] == OpCodesConstants.YIELD_VALUE && |
| 419 | + rootNode.bytecode[bci] == OpCodesConstants.RESUME_YIELD) { |
| 420 | + int stackTop = generatorFrame.getInt(rootNode.generatorStackTopOffset); |
| 421 | + return generatorFrame.getObject(stackTop); |
412 | 422 | }
|
413 |
| - return bci; |
| 423 | + return null; |
414 | 424 | }
|
415 | 425 |
|
416 | 426 | public Object getGeneratorReturnValue(Frame frame) {
|
@@ -746,6 +756,8 @@ public void createGeneratorFrame(Object[] arguments) {
|
746 | 756 | // it, otherwise they stay at the initial value, which we must set to null here
|
747 | 757 | PArguments.setException(arguments, null);
|
748 | 758 | PArguments.setCallerFrameInfo(arguments, null);
|
| 759 | + PArguments.setControlData(arguments, GENERATOR_CONTROL_DATA); |
| 760 | + PArguments.setGeneratorFrameLocals(generatorFrameArguments, factory.createDictLocals(generatorFrame)); |
749 | 761 | generatorFrame.setInt(bcioffset, 0);
|
750 | 762 | generatorFrame.setInt(generatorStackTopOffset, stackoffset - 1);
|
751 | 763 | copyArgsAndCells(generatorFrame, arguments);
|
|
0 commit comments