Skip to content

Commit 31a301d

Browse files
committed
create an "incomplete" PFrame to make locals modifications work
1 parent 6ea4491 commit 31a301d

File tree

4 files changed

+27
-12
lines changed

4 files changed

+27
-12
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@
139139
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
140140
import com.oracle.graal.python.nodes.expression.TernaryArithmetic;
141141
import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode;
142-
import com.oracle.graal.python.nodes.function.ClassBodyRootNode;
143142
import com.oracle.graal.python.nodes.function.FunctionRootNode;
144143
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
145144
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -1613,22 +1612,16 @@ public Object globals(VirtualFrame frame) {
16131612
abstract static class LocalsNode extends PythonBuiltinNode {
16141613
@Child ReadCallerFrameNode readCallerFrameNode = ReadCallerFrameNode.create();
16151614
private final ConditionProfile condProfile = ConditionProfile.createBinaryProfile();
1616-
private final ConditionProfile inClassProfile = ConditionProfile.createBinaryProfile();
16171615

16181616
@Specialization
16191617
public Object locals(VirtualFrame frame) {
16201618
Frame callerFrame = readCallerFrameNode.executeWith(frame);
16211619
PFrame pFrame = PArguments.getPFrame(callerFrame);
1622-
if (condProfile.profile(pFrame != null)) {
1623-
return pFrame.getLocals(factory());
1624-
} else {
1625-
Object specialArgument = PArguments.getSpecialArgument(callerFrame);
1626-
if (inClassProfile.profile(specialArgument instanceof ClassBodyRootNode)) {
1627-
return factory().createDictLocals(callerFrame, true);
1628-
} else {
1629-
return factory().createDictLocals(callerFrame, false);
1630-
}
1620+
if (condProfile.profile(pFrame == null)) {
1621+
pFrame = factory().createPFrame(callerFrame);
1622+
PArguments.setPFrame(callerFrame, pFrame);
16311623
}
1624+
return pFrame.getLocals(factory());
16321625
}
16331626
}
16341627
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PBaseException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ public PFrame getPFrame(PythonObjectFactory factory, int index) {
209209
if (frame != null) {
210210
// we have a frame, try to get the pFrame from the magic arguments first
211211
pFrame = PArguments.getPFrame(frame);
212-
if (pFrame == null) {
212+
if (pFrame == null || pFrame.isIncomplete()) {
213213
pFrame = factory.createPFrame(this, index);
214214
PArguments.setPFrame(frame, pFrame);
215215
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ public final class PFrame extends PythonBuiltinObject {
6767
private final Node location;
6868
private int line = -2;
6969

70+
public PFrame(LazyPythonClass cls, Frame frame) {
71+
super(cls);
72+
this.exception = null;
73+
this.index = -1;
74+
this.frame = frame;
75+
this.location = null;
76+
this.inClassScope = PArguments.getSpecialArgument(frame) instanceof ClassBodyRootNode;
77+
}
78+
7079
public PFrame(LazyPythonClass cls, PBaseException exception, int index) {
7180
super(cls);
7281
this.exception = exception;
@@ -145,4 +154,13 @@ public PDict getLocals(PythonObjectFactory factory) {
145154
}
146155
return factory.createDict();
147156
}
157+
158+
/**
159+
* Checks if this frame is complete in the sense that all frame accessors would work, e.g.
160+
* locals, backref etc. We optimize locals access to create a lightweight PFrame that has no
161+
* stack attached to it, which is where we check this.
162+
*/
163+
public boolean isIncomplete() {
164+
return location == null;
165+
}
148166
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,10 @@ public PReferenceType createReferenceType(PythonObject object, PFunction callbac
541541
* Frames, traces and exceptions
542542
*/
543543

544+
public PFrame createPFrame(Frame frame) {
545+
return trace(new PFrame(PythonBuiltinClassType.PFrame, frame));
546+
}
547+
544548
public PFrame createPFrame(PBaseException exception, int index) {
545549
return trace(new PFrame(PythonBuiltinClassType.PFrame, exception, index));
546550
}

0 commit comments

Comments
 (0)