11/*
2- * Copyright (c) 2018, 2024 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2018, 2025 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * The Universal Permissive License (UPL), Version 1.0
4242
4343import java .util .Objects ;
4444
45- import com .oracle .graal .python .PythonLanguage ;
4645import com .oracle .graal .python .builtins .objects .frame .PFrame ;
4746import com .oracle .graal .python .builtins .objects .function .PArguments ;
4847import com .oracle .graal .python .nodes .PRootNode ;
4948import com .oracle .graal .python .runtime .IndirectCallData ;
50- import com .oracle .graal .python .runtime .PythonContext ;
5149import com .oracle .truffle .api .CompilerDirectives ;
5250import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
5351import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
@@ -275,26 +273,22 @@ public static Frame getCallerFrame(PFrame.Reference startFrame, FrameInstance.Fr
275273
276274 @ TruffleBoundary
277275 private static Frame getFrame (Node requestingNode , PFrame .Reference startFrame , FrameInstance .FrameAccess frameAccess , FrameSelector selector , int level ) {
278- final Frame [] outputFrame = new Frame [1 ];
279- Truffle .getRuntime ().iterateFrames (new FrameInstanceVisitor <Frame >() {
276+ Frame [] outputFrame = new Frame [1 ];
277+ Truffle .getRuntime ().iterateFrames (new FrameInstanceVisitor <>() {
280278 int i = -1 ;
281279
282280 /**
283281 * We may find the Python frame at the level we desire, but the {@link PRootNode}
284- * associated with it may have been called from a different language, and thus not have
285- * Python {@link IndirectCallData} . That means that we cannot immediately return when we
282+ * associated with it may have been called from a different language, and thus not be
283+ * able to pass the caller frame . That means that we cannot immediately return when we
286284 * find the correct level frame, but instead we need to remember the frame in
287285 * {@code outputFrame} and then keep going until we find the previous Python caller on
288- * the stack (or not). That last Python caller before the Python frame we need must push
289- * the info.
290- *
291- * This can easily be seen when this is used to
292- * {@link PythonContext#peekTopFrameInfo(PythonLanguage)} , because in that case, that
293- * info must be set by the caller that is somewhere up the stack.
286+ * the stack (or not). That last Python caller should have {@link IndirectCallData} that
287+ * will be marked to pass the frame through the context.
294288 *
295289 * <pre>
296290 * ================
297- * ,>| PythonCallNode |
291+ * ,>| IndirectCallData |
298292 * | ================
299293 * | | LLVMRootNode |
300294 * | | LLVMCallNode |
@@ -312,8 +306,11 @@ public Frame visitFrame(FrameInstance frameInstance) {
312306 RootNode rootNode = getRootNode (frameInstance );
313307 Node callNode = frameInstance .getCallNode ();
314308 boolean didMark = IndirectCallData .setEncapsulatingNeedsToPassCallerFrame (callNode != null ? callNode : requestingNode );
315- if (outputFrame [0 ] == null && rootNode instanceof PRootNode pRootNode && pRootNode .setsUpCalleeContext ()) {
316- pRootNode .setNeedsCallerFrame ();
309+ if (rootNode instanceof PRootNode pRootNode && pRootNode .setsUpCalleeContext ()) {
310+ if (outputFrame [0 ] != null ) {
311+ return outputFrame [0 ];
312+ }
313+ boolean needsCallerFrame = true ;
317314 if (i < 0 && startFrame != null ) {
318315 Frame roFrame = getFrame (frameInstance , FrameInstance .FrameAccess .READ_ONLY );
319316 if (PArguments .getCurrentFrameInfo (roFrame ) == startFrame ) {
@@ -340,10 +337,14 @@ public Frame visitFrame(FrameInstance frameInstance) {
340337 // cannot materialize it.
341338 assert info .getCallNode () != null : "tried to read frame without location (root: " + pRootNode + ")" ;
342339 outputFrame [0 ] = frame ;
340+ needsCallerFrame = false ;
343341 }
344342 i += 1 ;
345343 }
346344 }
345+ if (needsCallerFrame ) {
346+ pRootNode .setNeedsCallerFrame ();
347+ }
347348 }
348349 if (didMark ) {
349350 return outputFrame [0 ];
0 commit comments