Skip to content

Commit 097d8b5

Browse files
committed
[GR-23234] Fix generator invocation
PullRequest: graalpython/1078
2 parents c4cb66f + 62cd349 commit 097d8b5

File tree

19 files changed

+222
-232
lines changed

19 files changed

+222
-232
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_generators.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,36 @@ def f():
256256
# self.assertTrue(isinstance(cm.exception.value, StopIteration))
257257
# self.assertEqual(cm.exception.value.value, 2)
258258

259+
def test_generator_caller_frame(self):
260+
def gen():
261+
yield sys._getframe(1)
262+
yield sys._getframe(1)
263+
264+
def callnext(g):
265+
next(g)
266+
return next(g)
267+
268+
def callsend(g):
269+
next(g)
270+
return g.send(1)
271+
272+
self.assertEqual(callnext(gen()).f_code.co_name, 'callnext')
273+
self.assertEqual(callsend(gen()).f_code.co_name, 'callsend')
274+
275+
# Force a megamorphic call to the genrator function
276+
def genfn(i):
277+
l = {}
278+
exec(f"def f{i}(): yield {i}", l)
279+
return l[f'f{i}']
280+
281+
fns = [genfn(i) for i in range(100)]
282+
fns.append(gen)
283+
for fn in fns:
284+
g = fn()
285+
self.assertEqual(callnext(g).f_code.co_name, 'callnext')
286+
for fn in fns:
287+
g = fn()
288+
self.assertEqual(callsend(g).f_code.co_name, 'callsend')
259289

260290
if sys.version_info.minor == 4 and sys.version_info.micro < 3:
261291
del ExceptionTest

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_generators.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*graalpython.lib-python.3.test.test_generators.ExceptionTest.test_tutorial_stopiteration
99
*graalpython.lib-python.3.test.test_generators.FinalizationTest.test_lambda_generator
1010
*graalpython.lib-python.3.test.test_generators.GeneratorTest.test_copy
11+
*graalpython.lib-python.3.test.test_generators.GeneratorTest.test_name
1112
*graalpython.lib-python.3.test.test_generators.GeneratorTest.test_pickle
1213
*graalpython.lib-python.3.test.test_generators.SignalAndYieldFromTest.test_raise_and_yield_from
1314
*graalpython.lib-python.3.test.test_generators.YieldFromTests.test_generator_gi_yieldfrom

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,28 +1476,31 @@ public abstract static class MinNode extends MinMaxNode {
14761476
public abstract static class NextNode extends PythonBinaryBuiltinNode {
14771477
@Specialization(guards = "isNoValue(defaultObject)")
14781478
public Object next(VirtualFrame frame, Object iterator, PNone defaultObject,
1479-
@Cached("create()") GetNextNode next,
1480-
@Cached("create()") IsBuiltinClassProfile errorProfile) {
1481-
try {
1482-
return next.execute(frame, iterator);
1483-
} catch (PException e) {
1484-
e.expectAttributeError(errorProfile);
1485-
throw raise(TypeError, e.setCatchingFrameAndGetEscapedException(frame), ErrorMessages.OBJ_ISNT_ITERATOR, iterator);
1486-
}
1479+
@Cached("createNextCall()") LookupAndCallUnaryNode callNode) {
1480+
return callNode.executeObject(frame, iterator);
14871481
}
14881482

14891483
@Specialization(guards = "!isNoValue(defaultObject)")
14901484
public Object next(VirtualFrame frame, Object iterator, Object defaultObject,
1491-
@Cached("create()") NextNode next,
1485+
@Cached("createNextCall()") LookupAndCallUnaryNode callNode,
14921486
@Cached("create()") IsBuiltinClassProfile errorProfile) {
14931487
try {
1494-
return next.execute(frame, iterator, PNone.NO_VALUE);
1488+
return callNode.executeObject(frame, iterator);
14951489
} catch (PException e) {
14961490
e.expectStopIteration(errorProfile);
14971491
return defaultObject;
14981492
}
14991493
}
15001494

1495+
protected LookupAndCallUnaryNode createNextCall() {
1496+
return LookupAndCallUnaryNode.create(__NEXT__, () -> new LookupAndCallUnaryNode.NoAttributeHandler() {
1497+
@Override
1498+
public Object execute(Object iterator) {
1499+
throw raise(TypeError, ErrorMessages.OBJ_ISNT_ITERATOR, iterator);
1500+
}
1501+
});
1502+
}
1503+
15011504
protected static NextNode create() {
15021505
return BuiltinFunctionsFactory.NextNodeFactory.create();
15031506
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyTruffleObjectAlloc.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444

4545
import com.oracle.graal.python.PythonLanguage;
4646
import com.oracle.graal.python.builtins.objects.frame.PFrame;
47-
import com.oracle.graal.python.nodes.call.CallTargetInvokeNode;
4847
import com.oracle.graal.python.nodes.call.GenericInvokeNode;
4948
import com.oracle.graal.python.nodes.frame.GetCurrentFrameRef;
5049
import com.oracle.graal.python.nodes.util.CannotCastException;
@@ -125,11 +124,6 @@ Object execute(Object[] arguments,
125124
return -2;
126125
}
127126

128-
static CallTargetInvokeNode createInvokeNode(ContextReference<PythonContext> contextRef) {
129-
CApiContext cApiContext = contextRef.get().getCApiContext();
130-
return CallTargetInvokeNode.create(cApiContext.getTriggerAsyncActionsCallTarget(), false, false);
131-
}
132-
133127
static AllocationReporter getAllocationReporter(ContextReference<PythonContext> contextRef) {
134128
return contextRef.get().getEnv().lookup(AllocationReporter.class);
135129
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,18 @@ public static void setGeneratorFrame(Object[] arguments, MaterializedFrame gener
325325
arguments[INDEX_GENERATOR_FRAME] = generatorFrame;
326326
}
327327

328+
/**
329+
* This should be used only in GeneratorFunctionRootNode, later the slot is overwritten with
330+
* generator frame
331+
*/
332+
public static PFunction getGeneratorFunction(Object[] arguments) {
333+
return (PFunction) arguments[INDEX_GENERATOR_FRAME];
334+
}
335+
336+
public static void setGeneratorFunction(Object[] arguments, PFunction generatorFunction) {
337+
arguments[INDEX_GENERATOR_FRAME] = generatorFunction;
338+
}
339+
328340
public static void setControlData(Object[] arguments, GeneratorControlData generatorArguments) {
329341
MaterializedFrame generatorFrame = (MaterializedFrame) arguments[INDEX_GENERATOR_FRAME];
330342
generatorFrame.getArguments()[INDEX_GENERATOR_FRAME] = generatorArguments;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,7 @@ public PCell[] getClosure() {
128128
}
129129

130130
public boolean isGeneratorFunction() {
131-
return false;
132-
}
133-
134-
public PGeneratorFunction asGeneratorFunction() {
135-
return null;
131+
return code.getRootCallTarget().getRootNode() instanceof GeneratorFunctionRootNode;
136132
}
137133

138134
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PGeneratorFunction.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)