Skip to content

Commit f0da0e0

Browse files
committed
PFrame: when exiting a function do not override the source location if one is already present
1 parent bc37aad commit f0da0e0

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022, 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
@@ -300,6 +300,10 @@ public void setLocation(Node location) {
300300
this.location = location;
301301
}
302302

303+
public Node getLocation() {
304+
return location;
305+
}
306+
303307
/**
304308
* Last bytecode instruction. Since we don't have bytecode this is -1 by default, but can be set
305309
* to a different value to distinguish started generators from unstarted

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022, 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
@@ -106,21 +106,30 @@ public final PFrame execute(VirtualFrame frame, boolean markAsEscaped, boolean f
106106
PFrame.Reference info = PArguments.getCurrentFrameInfo(frameToMaterialize);
107107
assert info != null && info.getCallNode() != null : "cannot materialize a frame without location information";
108108
Node callNode = info.getCallNode();
109-
return execute(frame, callNode, markAsEscaped, forceSync, frameToMaterialize);
109+
return execute(frame, callNode, markAsEscaped, forceSync, false, frameToMaterialize);
110110
}
111111

112112
public final PFrame execute(VirtualFrame frame, boolean markAsEscaped) {
113113
return execute(frame, markAsEscaped, frame);
114114
}
115115

116116
public final PFrame execute(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync) {
117-
return execute(frame, location, markAsEscaped, forceSync, frame);
117+
return execute(frame, location, markAsEscaped, forceSync, false);
118118
}
119119

120-
public abstract PFrame execute(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize);
120+
public final PFrame execute(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, boolean updateLocationIfMissing) {
121+
return execute(frame, location, markAsEscaped, forceSync, updateLocationIfMissing, frame);
122+
}
123+
124+
public final PFrame execute(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize) {
125+
return execute(frame, location, markAsEscaped, forceSync, false, frameToMaterialize);
126+
}
127+
128+
public abstract PFrame execute(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, boolean updateLocationIfMissing, Frame frameToMaterialize);
121129

122130
@Specialization(guards = {"getPFrame(frameToMaterialize) == null", "isGeneratorFrame(frameToMaterialize)"})
123-
static PFrame freshPFrameForGenerator(Node location, @SuppressWarnings("unused") boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync, Frame frameToMaterialize,
131+
static PFrame freshPFrameForGenerator(Node location, @SuppressWarnings("unused") boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync,
132+
@SuppressWarnings("unused") boolean updateLocationIfMissing, Frame frameToMaterialize,
124133
@Shared("factory") @Cached("createFactory()") PythonObjectFactory factory) {
125134
PFrame escapedFrame = factory.createPFrame(PArguments.getCurrentFrameInfo(frameToMaterialize), location, PArguments.getGeneratorFrameLocals(frameToMaterialize));
126135
PArguments.synchronizeArgs(frameToMaterialize, escapedFrame);
@@ -130,7 +139,8 @@ static PFrame freshPFrameForGenerator(Node location, @SuppressWarnings("unused")
130139
}
131140

132141
@Specialization(guards = {"cachedFD == frameToMaterialize.getFrameDescriptor()", "getPFrame(frameToMaterialize) == null", "!isGeneratorFrame(frameToMaterialize)"}, limit = "1")
133-
static PFrame freshPFrameCachedFD(VirtualFrame frame, Node location, boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync, Frame frameToMaterialize,
142+
static PFrame freshPFrameCachedFD(VirtualFrame frame, Node location, boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync,
143+
@SuppressWarnings("unused") boolean updateLocationIfMissing, Frame frameToMaterialize,
134144
@Cached("frameToMaterialize.getFrameDescriptor()") FrameDescriptor cachedFD,
135145
@Shared("factory") @Cached("createFactory()") PythonObjectFactory factory,
136146
@Shared("syncValuesNode") @Cached("createSyncNode()") SyncFrameValuesNode syncValuesNode) {
@@ -140,7 +150,8 @@ static PFrame freshPFrameCachedFD(VirtualFrame frame, Node location, boolean mar
140150
}
141151

142152
@Specialization(guards = {"getPFrame(frameToMaterialize) == null", "!isGeneratorFrame(frameToMaterialize)"}, replaces = "freshPFrameCachedFD")
143-
static PFrame freshPFrame(VirtualFrame frame, Node location, boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync, Frame frameToMaterialize,
153+
static PFrame freshPFrame(VirtualFrame frame, Node location, boolean markAsEscaped, @SuppressWarnings("unused") boolean forceSync, @SuppressWarnings("unused") boolean updateLocationIfMissing,
154+
Frame frameToMaterialize,
144155
@Shared("factory") @Cached("createFactory()") PythonObjectFactory factory,
145156
@Shared("syncValuesNode") @Cached("createSyncNode()") SyncFrameValuesNode syncValuesNode) {
146157
PDict locals = factory.createDictLocals(frameToMaterialize.getFrameDescriptor());
@@ -156,7 +167,7 @@ static PFrame freshPFrame(VirtualFrame frame, Node location, boolean markAsEscap
156167
* @see PFrame#isIncomplete
157168
**/
158169
@Specialization(guards = {"getPFrame(frameToMaterialize) != null", "!getPFrame(frameToMaterialize).isAssociated()"})
159-
static PFrame incompleteFrame(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize,
170+
static PFrame incompleteFrame(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, @SuppressWarnings("unused") boolean updateLocationIfMissing, Frame frameToMaterialize,
160171
@Shared("factory") @Cached("createFactory()") PythonObjectFactory factory,
161172
@Shared("syncValuesNode") @Cached("createSyncNode()") SyncFrameValuesNode syncValuesNode) {
162173
Object locals = getPFrame(frameToMaterialize).getLocalsDict();
@@ -165,7 +176,7 @@ static PFrame incompleteFrame(VirtualFrame frame, Node location, boolean markAsE
165176
}
166177

167178
@Specialization(guards = {"getPFrame(frameToMaterialize) != null", "getPFrame(frameToMaterialize).isAssociated()"})
168-
static PFrame alreadyEscapedFrame(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize,
179+
static PFrame alreadyEscapedFrame(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, boolean updateLocationIfMissing, Frame frameToMaterialize,
169180
@Shared("syncValuesNode") @Cached("createSyncNode()") SyncFrameValuesNode syncValuesNode,
170181
@Cached ConditionProfile syncProfile) {
171182
PFrame pyFrame = getPFrame(frameToMaterialize);
@@ -175,28 +186,30 @@ static PFrame alreadyEscapedFrame(VirtualFrame frame, Node location, boolean mar
175186
if (markAsEscaped) {
176187
pyFrame.getRef().markAsEscaped();
177188
}
178-
// update the location so the line number is correct
179-
pyFrame.setLocation(location);
189+
if (!updateLocationIfMissing || pyFrame.getLocation() == null) {
190+
// update the location so the line number is correct
191+
pyFrame.setLocation(location);
192+
}
180193
return pyFrame;
181194
}
182195

183196
@Specialization(replaces = {"freshPFrame", "alreadyEscapedFrame", "incompleteFrame"})
184-
static PFrame generic(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize,
197+
static PFrame generic(VirtualFrame frame, Node location, boolean markAsEscaped, boolean forceSync, boolean updateLocationIfMissing, Frame frameToMaterialize,
185198
@Shared("factory") @Cached("createFactory()") PythonObjectFactory factory,
186199
@Shared("syncValuesNode") @Cached("createSyncNode()") SyncFrameValuesNode syncValuesNode,
187200
@Cached ConditionProfile syncProfile) {
188201
PFrame pyFrame = getPFrame(frameToMaterialize);
189202
if (pyFrame != null) {
190203
if (pyFrame.isAssociated()) {
191-
return alreadyEscapedFrame(frame, location, markAsEscaped, forceSync, frameToMaterialize, syncValuesNode, syncProfile);
204+
return alreadyEscapedFrame(frame, location, markAsEscaped, forceSync, updateLocationIfMissing, frameToMaterialize, syncValuesNode, syncProfile);
192205
} else {
193-
return incompleteFrame(frame, location, markAsEscaped, forceSync, frameToMaterialize, factory, syncValuesNode);
206+
return incompleteFrame(frame, location, markAsEscaped, forceSync, updateLocationIfMissing, frameToMaterialize, factory, syncValuesNode);
194207
}
195208
} else {
196209
if (isGeneratorFrame(frameToMaterialize)) {
197-
return freshPFrameForGenerator(location, markAsEscaped, forceSync, frameToMaterialize, factory);
210+
return freshPFrameForGenerator(location, markAsEscaped, forceSync, updateLocationIfMissing, frameToMaterialize, factory);
198211
} else {
199-
return freshPFrame(frame, location, markAsEscaped, forceSync, frameToMaterialize, factory, syncValuesNode);
212+
return freshPFrame(frame, location, markAsEscaped, forceSync, updateLocationIfMissing, frameToMaterialize, factory, syncValuesNode);
200213
}
201214
}
202215
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022, 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
@@ -271,7 +271,7 @@ public void exit(VirtualFrame frame, PRootNode node) {
271271
}
272272

273273
// force the frame so that it can be accessed later
274-
ensureMaterializeNode().execute(frame, node, false, true);
274+
ensureMaterializeNode().execute(frame, node, false, true, true);
275275
info.materialize(PythonLanguage.get(this), frame, node);
276276
// if this frame escaped we must ensure that also f_back does
277277
callerInfo.markAsEscaped();

0 commit comments

Comments
 (0)