Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd6fbfa2

Browse files
committed
[GR-71679] Fix generator frame sync
PullRequest: graalpython/4127
2 parentsb011695 +e96effc commitd6fbfa2

File tree

17 files changed

+328
-97
lines changed

17 files changed

+328
-97
lines changed

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

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Copyright (C) 1996-2017 Python Software Foundation
33
#
44
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
5+
importitertools
56
importsys
67
importos
78
importunittest
@@ -506,4 +507,130 @@ def b():
506507
assertgen_b.gi_yieldfrom.gi_code.co_name=='q'
507508

508509
gen_b.send(None)
509-
assertgen_b.gi_yieldfromisNone
510+
assertgen_b.gi_yieldfromisNone
511+
512+
513+
def_test_generator_frame(checks):
514+
defgen():
515+
a=1
516+
yield
517+
b=2
518+
yield
519+
c=3
520+
521+
g=gen()
522+
f=None
523+
ifchecks[0]:
524+
f=g.gi_frame
525+
assertf
526+
assertf.f_backisNone
527+
assertf.f_globals==globals()
528+
assertf.f_locals== {}
529+
assertf.f_lineno==gen.__code__.co_firstlineno
530+
next(g)
531+
ifchecks[1]:
532+
ifnotf:
533+
f=g.gi_frame
534+
assertf
535+
assertf.f_backisNone
536+
assertf.f_globals==globals()
537+
assertf.f_locals== {'a':1}
538+
assertf.f_lineno==gen.__code__.co_firstlineno+2
539+
assertfisg.gi_frame
540+
next(g)
541+
ifchecks[2]:
542+
ifnotf:
543+
f=g.gi_frame
544+
assertf
545+
assertf.f_backisNone
546+
assertf.f_globals==globals()
547+
assertf.f_locals== {'a':1,'b':2}
548+
assertf.f_lineno==gen.__code__.co_firstlineno+4
549+
assertfisg.gi_frame
550+
try:
551+
next(g)
552+
assertFalse
553+
exceptStopIteration:
554+
pass
555+
iff:
556+
assertf.f_backissys._getframe()
557+
assertf.f_globalsisglobals()
558+
assertf.f_locals== {'a':1,'b':2,'c':3}
559+
# TODO GR-61955
560+
ifsys.implementation.name!="graalpy"ornot__graalpython__.is_bytecode_dsl_interpreter:
561+
assertf.f_lineno==gen.__code__.co_firstlineno+5
562+
assertnotg.gi_frame
563+
564+
565+
deftest_generator_frame():
566+
# Generte a whole matrix of possibilities of where the frame gets created vs re-synced
567+
forchecksinitertools.product([False,True],repeat=3):
568+
_test_generator_frame(checks)
569+
570+
571+
deftest_generator_frame_from_getframe():
572+
defgen():
573+
a=1
574+
yieldsys._getframe()
575+
b=2
576+
577+
g=gen()
578+
f=next(g)
579+
assertf
580+
assertf.f_backisNone
581+
assertf.f_globals==globals()
582+
assertf.f_locals== {'a':1}
583+
assertf.f_lineno==gen.__code__.co_firstlineno+2
584+
assertfisg.gi_frame
585+
try:
586+
next(g)
587+
assertFalse
588+
exceptStopIteration:
589+
pass
590+
assertf.f_backissys._getframe()
591+
assertf.f_globalsisglobals()
592+
assertf.f_locals== {'a':1,'b':2}
593+
# TODO GR-61955
594+
ifsys.implementation.name!="graalpy"ornot__graalpython__.is_bytecode_dsl_interpreter:
595+
assertf.f_lineno==gen.__code__.co_firstlineno+3
596+
597+
598+
deftest_generator_frame_in_running_generator():
599+
defgen():
600+
self=yield
601+
assertself.gi_running
602+
assertnotself.gi_suspended
603+
assertself.gi_frame.f_lineno==gen.__code__.co_firstlineno+4
604+
assertself.gi_frame.f_globals==globals()
605+
assertself.gi_frame.f_locals.get('self')isself
606+
assertself.gi_frameissys._getframe()
607+
608+
g=gen()
609+
next(g)
610+
try:
611+
g.send(g)
612+
assertFalse
613+
exceptStopIteration:
614+
pass
615+
616+
617+
deftest_generator_frame_in_generator_up_stack():
618+
defvalidate(self):
619+
assertself.gi_running
620+
assertnotself.gi_suspended
621+
assertself.gi_frame.f_lineno==gen.__code__.co_firstlineno+2
622+
assertself.gi_frame.f_globals==globals()
623+
assertself.gi_frame.f_locals.get('self')isself
624+
assertself.gi_frameissys._getframe(1)
625+
626+
defgen():
627+
self=yield
628+
validate(self)
629+
630+
g=gen()
631+
next(g)
632+
try:
633+
g.send(g)
634+
assertFalse
635+
exceptStopIteration:
636+
pass

‎graalpython/com.oracle.graal.python.test/src/tests/test_sysconfig.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,18 @@
3636
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
39+
importsys
40+
importunittest
3941

4042

4143
deftest_sysconfig():
4244
importos,sysconfig
43-
os.environ["PATH"]+=os.pathsep+r" : \ "+os.pathsep;
45+
os.environ["PATH"]+=os.pathsep+r" : \ "+os.pathsep
4446
sysconfig.get_config_vars()
4547
# must not fail
48+
49+
50+
@unittest.skipIf(sys.implementation.name!='graalpy',"GraalPy-only test")
51+
deftest_sysconfigdata():
52+
# Maturin loads this directly, make sure the import works
53+
import_sysconfigdata

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
importcom.oracle.graal.python.builtins.modules.StringModuleBuiltins;
112112
importcom.oracle.graal.python.builtins.modules.StructModuleBuiltins;
113113
importcom.oracle.graal.python.builtins.modules.SysModuleBuiltins;
114+
importcom.oracle.graal.python.builtins.modules.SysconfigModuleBuiltins;
114115
importcom.oracle.graal.python.builtins.modules.ThreadModuleBuiltins;
115116
importcom.oracle.graal.python.builtins.modules.TimeModuleBuiltins;
116117
importcom.oracle.graal.python.builtins.modules.TokenizeModuleBuiltins;
@@ -566,6 +567,7 @@ private static PythonBuiltins[] initializeBuiltins(TruffleLanguage.Env env) {
566567
newWeakRefModuleBuiltins(),
567568
newReferenceTypeBuiltins(),
568569
newTracemallocModuleBuiltins(),
570+
newSysconfigModuleBuiltins(),
569571
// contextvars
570572
newContextVarBuiltins(),
571573
newContextBuiltins(),
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
packagecom.oracle.graal.python.builtins.modules;
42+
43+
importstaticcom.oracle.graal.python.nodes.BuiltinNames.J__SYSCONFIG;
44+
45+
importjava.util.Collections;
46+
importjava.util.List;
47+
48+
importcom.oracle.graal.python.builtins.CoreFunctions;
49+
importcom.oracle.graal.python.builtins.PythonBuiltins;
50+
importcom.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
51+
importcom.oracle.truffle.api.dsl.NodeFactory;
52+
53+
@CoreFunctions(defineModule =J__SYSCONFIG,isEager =true)
54+
publicfinalclassSysconfigModuleBuiltinsextendsPythonBuiltins {
55+
@Override
56+
protectedList<?extendsNodeFactory<?extendsPythonBuiltinBaseNode>>getNodeFactories() {
57+
returnCollections.emptyList();
58+
}
59+
}

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java‎

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public static final class Reference {
163163
// by a callee frame to inform the caller that it should materialize itself when it returns.
164164
privatebooleanescaped =false;
165165

166-
privatefinalReferencecallerInfo;
166+
privateReferencecallerInfo;
167167

168168
publicReference(RootNoderootNode,ReferencecallerInfo) {
169169
this.rootNode =rootNode;
@@ -174,9 +174,8 @@ public RootNode getRootNode() {
174174
returnrootNode;
175175
}
176176

177-
publicvoidsetBackref(PFrame.Referencebackref) {
178-
assertpyFrame !=null :"setBackref should only be called when the PFrame escaped";
179-
pyFrame.setBackref(backref);
177+
publicvoidsetCallerInfo(ReferencecallerInfo) {
178+
this.callerInfo =callerInfo;
180179
}
181180

182181
publicvoidmarkAsEscaped() {
@@ -307,25 +306,20 @@ public Thread getThread() {
307306
returnthread;
308307
}
309308

310-
publicPFrame.ReferencegetBackref() {
311-
returnbackref;
312-
}
313-
314-
publicvoidsetBackref(PFrame.Referencebackref) {
315-
// GR-41914
316-
// @formatter:off
317-
// assert this.backref == null || this.backref == backref : "setBackref tried to set a backref different to the one that was previously attached";
318-
// @formatter:on
319-
this.backref =backref;
320-
}
321-
322309
publicvoidsetLine(intline) {
323310
if (lockLine) {
324311
return;
325312
}
326313
this.line =line;
327314
}
328315

316+
publicvoidresetLine() {
317+
if (lockLine) {
318+
return;
319+
}
320+
this.line =UNINITIALIZED_LINE;
321+
}
322+
329323
publicvoidsetLineLock(intline) {
330324
this.line =line;
331325
this.lockLine =true;

‎graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/CommonGeneratorBuiltins.java‎

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
importcom.oracle.graal.python.builtins.objects.exception.PBaseException;
6262
importcom.oracle.graal.python.builtins.objects.exception.PrepareExceptionNode;
6363
importcom.oracle.graal.python.builtins.objects.frame.PFrame;
64+
importcom.oracle.graal.python.builtins.objects.function.PArguments;
6465
importcom.oracle.graal.python.builtins.objects.traceback.PTraceback;
6566
importcom.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
6667
importcom.oracle.graal.python.lib.IteratorExhausted;
@@ -103,6 +104,7 @@
103104
importcom.oracle.truffle.api.nodes.DirectCallNode;
104105
importcom.oracle.truffle.api.nodes.IndirectCallNode;
105106
importcom.oracle.truffle.api.nodes.Node;
107+
importcom.oracle.truffle.api.nodes.RootNode;
106108
importcom.oracle.truffle.api.profiles.InlinedBranchProfile;
107109
importcom.oracle.truffle.api.profiles.InlinedConditionProfile;
108110

@@ -183,19 +185,24 @@ static Object cachedBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGenera
183185
* generator root.
184186
*/
185187
MaterializedFramegeneratorFrame =self.getGeneratorFrame();
186-
Object[]arguments =newObject[]{generatorFrame,sendValue};
188+
Object[]callArguments =newObject[]{generatorFrame,sendValue};
189+
Object[]generatorArguments =generatorFrame.getArguments();
187190
if (frame ==null) {
188191
PythonContextcontext =PythonContext.get(inliningTarget);
189192
PythonThreadStatethreadState =context.getThreadState(context.getLanguage(inliningTarget));
190-
Objectstate =IndirectCalleeContext.enter(threadState,generatorFrame.getArguments());
193+
Objectstate =IndirectCalleeContext.enter(threadState,generatorArguments);
194+
PFrame.Referenceref =PArguments.getCurrentFrameInfo(generatorArguments);
195+
ref.setCallerInfo(PArguments.getCallerFrameInfo(generatorArguments));
191196
try {
192-
generatorResult =callNode.call(arguments);
197+
generatorResult =callNode.call(callArguments);
193198
}finally {
194199
IndirectCalleeContext.exit(threadState,state);
195200
}
196201
}else {
197-
callContext.executePrepareCall(frame,generatorFrame.getArguments(),rootNode.getCallerFlags());
198-
generatorResult =callNode.call(arguments);
202+
callContext.executePrepareCall(frame,generatorArguments,rootNode.getCallerFlags());
203+
PFrame.Referenceref =PArguments.getCurrentFrameInfo(generatorArguments);
204+
ref.setCallerInfo(PArguments.getCallerFrameInfo(generatorArguments));
205+
generatorResult =callNode.call(callArguments);
199206
}
200207
}catch (PExceptione) {
201208
throwhandleException(self,inliningTarget,errorProfile,raiseNode,e);
@@ -250,19 +257,24 @@ static Object genericBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGener
250257
// See the cached specialization for notes about the arguments handling
251258
PRootNoderootNode =PGenerator.unwrapContinuationRoot((ContinuationRootNode)callTarget.getRootNode());
252259
MaterializedFramegeneratorFrame =self.getGeneratorFrame();
253-
Object[]arguments =newObject[]{generatorFrame,sendValue};
260+
Object[]callArguments =newObject[]{generatorFrame,sendValue};
261+
Object[]generatorArguments =generatorFrame.getArguments();
254262
if (frame ==null) {
255263
PythonContextcontext =PythonContext.get(inliningTarget);
256264
PythonThreadStatethreadState =context.getThreadState(context.getLanguage(inliningTarget));
257-
Objectstate =IndirectCalleeContext.enter(threadState,generatorFrame.getArguments());
265+
Objectstate =IndirectCalleeContext.enter(threadState,generatorArguments);
266+
PFrame.Referenceref =PArguments.getCurrentFrameInfo(generatorArguments);
267+
ref.setCallerInfo(PArguments.getCallerFrameInfo(generatorArguments));
258268
try {
259-
generatorResult =callNode.call(callTarget,arguments);
269+
generatorResult =callNode.call(callTarget,callArguments);
260270
}finally {
261271
IndirectCalleeContext.exit(threadState,state);
262272
}
263273
}else {
264-
callContext.executePrepareCall(frame,generatorFrame.getArguments(),rootNode.getCallerFlags());
265-
generatorResult =callNode.call(callTarget,arguments);
274+
callContext.executePrepareCall(frame,generatorArguments,rootNode.getCallerFlags());
275+
PFrame.Referenceref =PArguments.getCurrentFrameInfo(generatorArguments);
276+
ref.setCallerInfo(PArguments.getCallerFrameInfo(generatorArguments));
277+
generatorResult =callNode.call(callTarget,callArguments);
266278
}
267279
}catch (PExceptione) {
268280
throwhandleException(self,inliningTarget,errorProfile,raiseNode,e);
@@ -388,9 +400,16 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object
388400
// Instead, we throw the exception here and fake entering the generator by adding
389401
// its frame to the traceback manually.
390402
self.markAsFinished();
391-
Nodelocation =self.getCurrentCallTarget().getRootNode();
403+
Nodelocation;
404+
RootNoderootNode =self.getCurrentCallTarget().getRootNode();
405+
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
406+
location =self.getBytecodeNode();
407+
}else {
408+
location =rootNode;
409+
}
392410
MaterializedFramegeneratorFrame =self.getGeneratorFrame();
393-
PFramepFrame =MaterializeFrameNode.materializeGeneratorFrame(location,generatorFrame,PFrame.Reference.EMPTY);
411+
PFrame.Referenceref =newPFrame.Reference(rootNode,PFrame.Reference.EMPTY);
412+
PFramepFrame =MaterializeFrameNode.materializeGeneratorFrame(location,generatorFrame,self.getGlobals(),ref);
394413
FrameInfoinfo = (FrameInfo)generatorFrame.getFrameDescriptor().getInfo();
395414
pFrame.setLine(info.getFirstLineNumber());
396415
ObjectexistingTracebackObj =getTracebackNode.execute(inliningTarget,instance);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp