Skip to content

Commit 973d006

Browse files
committed
Don't always pass caller frame to indirect calls
1 parent d67c31d commit 973d006

File tree

2 files changed

+24
-24
lines changed

2 files changed

+24
-24
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ static Object doDirect(VirtualFrame frame, Node inliningTarget, RootCallTarget c
167167
IndirectCalleeContext.exit(threadState, state);
168168
}
169169
} else {
170-
callContext.prepareIndirectCall(frame, arguments);
170+
callContext.prepareIndirectCall(frame, arguments, callTarget);
171171
return callNode.call(callTarget, arguments);
172172
}
173173
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,15 @@ public abstract static class CallContext extends Node {
177177
/**
178178
* Prepare an indirect call from a Python frame to a Python function.
179179
*/
180-
public void prepareIndirectCall(VirtualFrame frame, Object[] callArguments) {
181-
executePrepareCall(frame, getActualCallArguments(callArguments), true, true);
180+
public void prepareIndirectCall(VirtualFrame frame, Object[] callArguments, RootCallTarget callTarget) {
181+
PRootNode pRootNode;
182+
RootNode rootNode = callTarget.getRootNode();
183+
if (rootNode instanceof ContinuationRootNode continuationRoot) {
184+
pRootNode = (PRootNode) continuationRoot.getSourceRootNode();
185+
} else {
186+
pRootNode = (PRootNode) rootNode;
187+
}
188+
executePrepareCall(frame, getActualCallArguments(callArguments), pRootNode.needsCallerFrame(), pRootNode.needsExceptionState());
182189
}
183190

184191
private static Object[] getActualCallArguments(Object[] callArguments) {
@@ -216,6 +223,16 @@ public void prepareCall(VirtualFrame frame, Object[] callArguments, RootCallTarg
216223

217224
protected abstract void executePrepareCall(VirtualFrame frame, Object[] callArguments, boolean needsCallerFrame, boolean needsExceptionState);
218225

226+
@Specialization
227+
protected static void prepareCall(VirtualFrame frame, Object[] callArguments, boolean needsCallerFrame, boolean needsExceptionState,
228+
@Bind Node inliningTarget,
229+
@Cached PassCallerFrameNode passCallerFrame,
230+
@Cached PassExceptionStateNode passExceptionState) {
231+
assert PArguments.isPythonFrame(frame) || inliningTarget.getRootNode() instanceof TopLevelExceptionHandler : "calling from non-Python or non-top-level frame";
232+
passCallerFrame.execute(frame, inliningTarget, callArguments, needsCallerFrame);
233+
passExceptionState.execute(frame, inliningTarget, callArguments, needsExceptionState);
234+
}
235+
219236
/**
220237
* Equivalent to PyPy's ExecutionContext.enter `frame.f_backref = self.topframeref` we here
221238
* pass the current top frame reference to the next frame. An optimization we do is to only
@@ -346,16 +363,6 @@ protected static void passNoExceptionState(VirtualFrame frame, Node inliningTarg
346363
PArguments.setException(callArguments, PException.NO_EXCEPTION);
347364
}
348365
}
349-
350-
@Specialization
351-
protected static void prepareCall(VirtualFrame frame, Object[] callArguments, boolean needsCallerFrame, boolean needsExceptionState,
352-
@Bind Node inliningTarget,
353-
@Cached PassCallerFrameNode passCallerFrame,
354-
@Cached PassExceptionStateNode passExceptionState) {
355-
assert PArguments.isPythonFrame(frame) || inliningTarget.getRootNode() instanceof TopLevelExceptionHandler : "calling from non-Python or non-top-level frame";
356-
passCallerFrame.execute(frame, inliningTarget, callArguments, needsCallerFrame);
357-
passExceptionState.execute(frame, inliningTarget, callArguments, needsExceptionState);
358-
}
359366
}
360367

361368
/**
@@ -759,35 +766,28 @@ public abstract static class IndirectCalleeContext {
759766
* {@link PRootNode#needsExceptionState()}.
760767
*/
761768
public static Object enterIndirect(PythonLanguage language, PythonContext context, Object[] pArguments, RootCallTarget callTarget) {
762-
return enter(context.getThreadState(language), unwrapArgumentsArray(callTarget, pArguments), true);
769+
return enter(context.getThreadState(language), pArguments, needsExceptionState(callTarget));
763770
}
764771

765772
/**
766773
* @see #enterIndirect(PythonLanguage, PythonContext, Object[], RootCallTarget)
767774
*/
768775
public static Object enterIndirect(PythonThreadState threadState, Object[] pArguments, RootCallTarget callTarget) {
769-
return enter(threadState, unwrapArgumentsArray(callTarget, pArguments), true);
776+
return enter(threadState, pArguments, needsExceptionState(callTarget));
770777
}
771778

772779
/**
773780
* @see #enter(PythonThreadState, Object[], RootCallTarget)
774781
*/
775782
public static Object enter(PythonLanguage language, PythonContext context, Object[] pArguments, RootCallTarget callTarget) {
776-
return enter(context.getThreadState(language), unwrapArgumentsArray(callTarget, pArguments), needsExceptionState(callTarget));
783+
return enter(context.getThreadState(language), pArguments, needsExceptionState(callTarget));
777784
}
778785

779786
/**
780787
* Prepare a call from a foreign frame to a Python function.
781788
*/
782789
public static Object enter(PythonThreadState threadState, Object[] pArguments, RootCallTarget callTarget) {
783-
return enter(threadState, unwrapArgumentsArray(callTarget, pArguments), needsExceptionState(callTarget));
784-
}
785-
786-
private static Object[] unwrapArgumentsArray(RootCallTarget callTarget, Object[] arguments) {
787-
if (PGenerator.isDSLGeneratorTarget(callTarget)) {
788-
return PGenerator.getDSLGeneratorFrame(arguments).getArguments();
789-
}
790-
return arguments;
790+
return enter(threadState, pArguments, needsExceptionState(callTarget));
791791
}
792792

793793
private static boolean needsExceptionState(RootCallTarget callTarget) {

0 commit comments

Comments
 (0)