Skip to content

Commit 53f49b0

Browse files
author
Adam Hrbac
committed
Implement GET_YIELD_FROM_ITER
1 parent e6d7e8e commit 53f49b0

File tree

7 files changed

+92
-36
lines changed

7 files changed

+92
-36
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
*test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_server_stream_bittype
8383
*test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_create_server_wrong_sock
8484
*test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_getnameinfo
85-
*test.test_asyncio.test_base_events.BaseEventLoopWithSelectorTests.test_log_slow_callbacks
8685
*test.test_asyncio.test_base_events.BaseEventTests.test_ipaddr_info
8786
*test.test_asyncio.test_base_events.BaseEventTests.test_ipaddr_info_no_inet_pton
8887
*test.test_asyncio.test_base_events.BaseEventTests.test_port_parameter_types
@@ -329,7 +328,6 @@
329328
*test.test_asyncio.test_pep492.CoroutineTests.test_function_returning_awaitable
330329
*test.test_asyncio.test_pep492.CoroutineTests.test_iscoroutine
331330
*test.test_asyncio.test_pep492.CoroutineTests.test_iscoroutinefunction
332-
*test.test_asyncio.test_pep492.CoroutineTests.test_task_print_stack
333331
*test.test_asyncio.test_pep492.LockTests.test_context_manager_async_with
334332
*test.test_asyncio.test_pep492.LockTests.test_context_manager_with_await
335333
*test.test_asyncio.test_proactor_events.BaseProactorEventLoopTests.test_close
@@ -1458,7 +1456,6 @@
14581456
*test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_gather_shield
14591457
*test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_generic_alias
14601458
*test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_get_coro
1461-
*test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_get_stack
14621459
*test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_iscoroutinefunction
14631460
*test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_log_traceback
14641461
*test.test_asyncio.test_tasks.PyTask_PyFuture_SubclassTests.test_other_loop_future
@@ -1548,7 +1545,6 @@
15481545
*test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_gather_shield
15491546
*test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_generic_alias
15501547
*test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_get_coro
1551-
*test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_get_stack
15521548
*test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_iscoroutinefunction
15531549
*test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_log_traceback
15541550
*test.test_asyncio.test_tasks.PyTask_PyFuture_Tests.test_other_loop_future

graalpython/com.oracle.graal.python.test/testData/goldenFiles/CompilerTests/testYieldFrom.co

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Disassembly of <module>:
77
Disassembly of gen:
88
Flags: CO_GENERATOR
99
2:15 - 2:16 0 LOAD_FAST 0 (a)
10-
2:4 - 2:16 2 GET_ITER
10+
2:4 - 2:16 2 GET_YIELD_FROM_ITER
1111
2:4 - 2:16 3 LOAD_NONE
1212
2:4 - 2:16 >> 4 SEND 10 (to 14)
1313
2:4 - 2:16 >> 6 YIELD_VALUE

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,6 @@ private static CodeUnit getCodeUnit(RootNode node) {
370370
return null;
371371
}
372372

373-
private static int getFlags(int flags, CodeUnit codeUnit) {
374-
flags |= codeUnit.isCoroutine() ? CO_COROUTINE : 0;
375-
flags |= codeUnit.isGenerator() ? CO_GENERATOR : 0;
376-
flags |= codeUnit.takesVarArgs() ? CO_VARARGS : 0;
377-
flags |= codeUnit.takesVarKeywordArgs() ? CO_VARKEYWORDS : 0;
378-
return flags;
379-
}
380-
381373
RootNode getRootNode() {
382374
return getRootCallTarget().getRootNode();
383375
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Compiler.java

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import static com.oracle.graal.python.compiler.OpCodes.GET_AWAITABLE;
7474
import static com.oracle.graal.python.compiler.OpCodes.GET_ITER;
7575
import static com.oracle.graal.python.compiler.OpCodes.GET_LEN;
76+
import static com.oracle.graal.python.compiler.OpCodes.GET_YIELD_FROM_ITER;
7677
import static com.oracle.graal.python.compiler.OpCodes.IMPORT_FROM;
7778
import static com.oracle.graal.python.compiler.OpCodes.IMPORT_NAME;
7879
import static com.oracle.graal.python.compiler.OpCodes.IMPORT_STAR;
@@ -1000,23 +1001,25 @@ public Void visit(ExprTy.Attribute node) {
10001001

10011002
@Override
10021003
public Void visit(ExprTy.Await node) {
1003-
ensureIsAsync();
1004+
// TODO if !IS_TOP_LEVEL_AWAIT
1005+
if (!unit.scope.isFunction()) {
1006+
errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "'await' outside function");
1007+
}
1008+
if (unit.scopeType != CompilationScope.AsyncFunction && unit.scopeType != CompilationScope.Comprehension) {
1009+
errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "'await' outside async function");
1010+
}
10041011
SourceRange savedLocation = setLocation(node);
10051012
try {
10061013
node.value.accept(this);
1007-
awaitStackTop();
1014+
addOp(GET_AWAITABLE);
1015+
addOp(LOAD_NONE);
1016+
addYieldFrom();
10081017
return null;
10091018
} finally {
10101019
setLocation(savedLocation);
10111020
}
10121021
}
10131022

1014-
private void awaitStackTop() {
1015-
addOp(GET_AWAITABLE);
1016-
addOp(LOAD_NONE);
1017-
addYieldFrom();
1018-
}
1019-
10201023
@Override
10211024
public Void visit(ExprTy.BinOp node) {
10221025
SourceRange savedLocation = setLocation(node);
@@ -1865,7 +1868,7 @@ public Void visit(ExprTy.YieldFrom node) {
18651868
}
18661869
node.value.accept(this);
18671870
// TODO GET_YIELD_FROM_ITER
1868-
addOp(GET_ITER);
1871+
addOp(GET_YIELD_FROM_ITER);
18691872
addOp(LOAD_NONE);
18701873
addYieldFrom();
18711874
return null;
@@ -2089,20 +2092,16 @@ public Void visit(StmtTy.AsyncFunctionDef node) {
20892092
@Override
20902093
public Void visit(StmtTy.AsyncWith node) {
20912094
setLocation(node);
2092-
ensureIsAsync();
2093-
visitAsyncWith(node, 0);
2094-
unit.useNextBlock(new Block());
2095-
return null;
2096-
}
2097-
2098-
private void ensureIsAsync() {
20992095
// TODO if !IS_TOP_LEVEL_AWAIT
21002096
if (!unit.scope.isFunction()) {
2101-
errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "'await' outside function");
2097+
errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "'async with' outside function");
21022098
}
21032099
if (unit.scopeType != CompilationScope.AsyncFunction && unit.scopeType != CompilationScope.Comprehension) {
2104-
errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "'await' outside async function");
2100+
errorCallback.onError(ErrorType.Syntax, unit.currentLocation, "'async with' outside async function");
21052101
}
2102+
visitAsyncWith(node, 0);
2103+
unit.useNextBlock(new Block());
2104+
return null;
21062105
}
21072106

21082107
private void visitAsyncWith(StmtTy.AsyncWith node, int itemIndex) {
@@ -2115,7 +2114,10 @@ private void visitAsyncWith(StmtTy.AsyncWith node, int itemIndex) {
21152114
unit.pushBlock(new BlockInfo.AsyncWith(body, handler, node));
21162115

21172116
unit.useNextBlock(body);
2118-
awaitStackTop(); // SETUP_AWITH leaves 2 awaitables rather than a function and a result
2117+
// SETUP_AWITH leaves 2 awaitables rather than a function and a result
2118+
addOp(GET_AWAITABLE);
2119+
addOp(LOAD_NONE);
2120+
addYieldFrom();
21192121
/*
21202122
* Unwind one more stack item than it normally would to get rid of the context manager that
21212123
* is not needed in the finally block
@@ -2137,7 +2139,9 @@ private void visitAsyncWith(StmtTy.AsyncWith node, int itemIndex) {
21372139
unit.useNextBlock(handler);
21382140
setLocation(node);
21392141
addOp(GET_AEXIT_CORO);
2140-
awaitStackTop();
2142+
addOp(GET_AWAITABLE);
2143+
addOp(LOAD_NONE);
2144+
addYieldFrom();
21412145
addOp(EXIT_AWITH);
21422146
}
21432147

@@ -3627,7 +3631,9 @@ private BlockInfo.Loop unwindBlockStack(UnwindType type) {
36273631
}
36283632
addOp(LOAD_NONE);
36293633
addOp(GET_AEXIT_CORO);
3630-
awaitStackTop();
3634+
addOp(GET_AWAITABLE);
3635+
addOp(LOAD_NONE);
3636+
addYieldFrom();
36313637
addOp(EXIT_AWITH);
36323638

36333639
} else if (info instanceof BlockInfo.TryFinally) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/OpCodes.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ public enum OpCodes {
112112
* Pushes: iterator
113113
*/
114114
GET_ITER(0, 1, 1),
115+
/**
116+
* Gets an iterator of an object, does nothing for a generator iterator or a coroutine
117+
*
118+
* Pops: object
119+
*
120+
* Pushes: iterator
121+
*/
122+
GET_YIELD_FROM_ITER(0, 1, 1),
115123
/**
116124
* Gets an awaitable of an object
117125
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.oracle.graal.python.nodes.bytecode;
2+
3+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4+
import com.oracle.graal.python.builtins.objects.generator.PGenerator;
5+
import com.oracle.graal.python.lib.PyObjectGetIter;
6+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
7+
import com.oracle.truffle.api.dsl.Cached;
8+
import com.oracle.truffle.api.dsl.GenerateUncached;
9+
import com.oracle.truffle.api.dsl.Specialization;
10+
import com.oracle.truffle.api.frame.Frame;
11+
import com.oracle.truffle.api.nodes.Node;
12+
13+
@GenerateUncached
14+
public abstract class GetYieldFromIterNode extends Node {
15+
public abstract Object execute(Frame frame, Object receiver);
16+
17+
@Specialization
18+
public Object getGeneratorOrCoroutine(PGenerator arg) {
19+
// TODO check if the generator in which the yield from is an iterable or normal coroutine
20+
return arg;
21+
}
22+
23+
@Specialization
24+
public Object getGeneric(Frame frame, Object arg,
25+
@Cached PyObjectGetIter getIter,
26+
@Cached IsBuiltinClassProfile isCoro) {
27+
if (isCoro.profileObject(arg, PythonBuiltinClassType.PCoroutine)) {
28+
return arg;
29+
} else {
30+
return getIter.execute(frame, arg);
31+
}
32+
}
33+
34+
public static GetYieldFromIterNode create() {
35+
return GetYieldFromIterNodeGen.create();
36+
}
37+
38+
public static GetYieldFromIterNode getUncached() {
39+
return GetYieldFromIterNodeGen.getUncached();
40+
}
41+
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
import com.oracle.graal.python.builtins.modules.BuiltinFunctionsFactory.FormatNodeFactory.FormatNodeGen;
6363
import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins;
6464
import com.oracle.graal.python.builtins.objects.PNone;
65+
import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNode;
66+
import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNodeGen;
6567
import com.oracle.graal.python.builtins.objects.cell.PCell;
6668
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
6769
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes.SetItemNode;
@@ -82,8 +84,6 @@
8284
import com.oracle.graal.python.builtins.objects.function.PFunction;
8385
import com.oracle.graal.python.builtins.objects.function.PKeyword;
8486
import com.oracle.graal.python.builtins.objects.function.Signature;
85-
import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNode;
86-
import com.oracle.graal.python.builtins.objects.asyncio.GetAwaitableNodeGen;
8787
import com.oracle.graal.python.builtins.objects.ints.IntBuiltins;
8888
import com.oracle.graal.python.builtins.objects.ints.IntBuiltinsFactory;
8989
import com.oracle.graal.python.builtins.objects.list.ListBuiltins;
@@ -280,6 +280,8 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
280280
private static final NodeSupplier<ForIterINode> NODE_FOR_ITER_I = ForIterINode::create;
281281
private static final NodeSupplier<PyObjectGetIter> NODE_OBJECT_GET_ITER = PyObjectGetIter::create;
282282
private static final PyObjectGetIter UNCACHED_OBJECT_GET_ITER = PyObjectGetIter.getUncached();
283+
private static final NodeSupplier<GetYieldFromIterNode> NODE_OBJECT_GET_YIELD_FROM_ITER = GetYieldFromIterNode::create;
284+
private static final GetYieldFromIterNode UNCACHED_OBJECT_GET_YIELD_FROM_ITER = GetYieldFromIterNode.getUncached();
283285

284286
private static final NodeSupplier<GetAwaitableNode> NODE_OBJECT_GET_AWAITABLE = GetAwaitableNode::create;
285287
private static final GetAwaitableNode UNCACHED_OBJECT_GET_AWAITABLE = GetAwaitableNode.getUncached();
@@ -2030,6 +2032,11 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
20302032
bytecodeGetIter(virtualFrame, useCachedNodes, stackTop, localNodes, beginBci);
20312033
break;
20322034
}
2035+
case OpCodesConstants.GET_YIELD_FROM_ITER: {
2036+
setCurrentBci(virtualFrame, bciSlot, bci);
2037+
bytecodeGetYieldFromIter(virtualFrame, useCachedNodes, stackTop, localNodes, beginBci);
2038+
break;
2039+
}
20332040
case OpCodesConstants.FOR_ITER: {
20342041
bytecodeForIterAdaptive(bci);
20352042
continue;
@@ -2405,6 +2412,12 @@ private void bytecodeGetIter(VirtualFrame virtualFrame, boolean useCachedNodes,
24052412
virtualFrame.setObject(stackTop, getIter.execute(virtualFrame, virtualFrame.getObject(stackTop)));
24062413
}
24072414

2415+
@BytecodeInterpreterSwitch
2416+
private void bytecodeGetYieldFromIter(VirtualFrame virtualFrame, boolean useCachedNodes, int stackTop, Node[] localNodes, int beginBci) {
2417+
GetYieldFromIterNode getIter = insertChildNode(localNodes, beginBci, UNCACHED_OBJECT_GET_YIELD_FROM_ITER, GetYieldFromIterNodeGen.class, NODE_OBJECT_GET_YIELD_FROM_ITER, useCachedNodes);
2418+
virtualFrame.setObject(stackTop, getIter.execute(virtualFrame, virtualFrame.getObject(stackTop)));
2419+
}
2420+
24082421
@BytecodeInterpreterSwitch
24092422
private boolean bytecodeForIterO(VirtualFrame virtualFrame, boolean useCachedNodes, int stackTop, Node[] localNodes, int beginBci) {
24102423
ForIterONode node = insertChildNode(localNodes, beginBci, UNCACHED_FOR_ITER_O, ForIterONodeGen.class, NODE_FOR_ITER_O, useCachedNodes);

0 commit comments

Comments
 (0)