Skip to content

Commit 5f043a5

Browse files
committed
Resolve cell values when refreshing frame values.
1 parent 92b66d8 commit 5f043a5

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
package com.oracle.graal.python.nodes.frame;
4242

4343
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
44+
import com.oracle.graal.python.builtins.objects.cell.PCell;
4445
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes.SetItemNode;
4546
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
4647
import com.oracle.graal.python.builtins.objects.common.LocalsStorage;
@@ -62,6 +63,7 @@
6263
import com.oracle.truffle.api.frame.VirtualFrame;
6364
import com.oracle.truffle.api.nodes.ExplodeLoop;
6465
import com.oracle.truffle.api.nodes.Node;
66+
import com.oracle.truffle.api.profiles.ConditionProfile;
6567

6668
/**
6769
* This node makes sure that the current frame has a filled-in PFrame object with a backref
@@ -311,6 +313,7 @@ static void doLocalsStorageUncached(PFrame pyFrame, Frame frameToSync) {
311313
static void doGenericDictCached(VirtualFrame frame, PFrame pyFrame, Frame frameToSync,
312314
@Cached("frameToSync.getFrameDescriptor()") @SuppressWarnings("unused") FrameDescriptor cachedFd,
313315
@Cached(value = "getSlots(cachedFd)", dimensions = 1) FrameSlot[] cachedSlots,
316+
@Cached(value = "getProfiles(cachedSlots.length)", dimensions = 1) ConditionProfile[] profiles,
314317
@Cached SetItemNode setItemNode) {
315318
// This can happen if someone received the locals dict using 'locals()' or similar and
316319
// then assigned to the dictionary. Assigning will switch the storage. But we still must
@@ -324,7 +327,11 @@ static void doGenericDictCached(VirtualFrame frame, PFrame pyFrame, Frame frameT
324327
if (FrameSlotIDs.isUserFrameSlot(slot.getIdentifier())) {
325328
Object value = frameToSync.getValue(slot);
326329
if (value != null) {
327-
setItemNode.execute(frame, localsDict, slot.getIdentifier(), value);
330+
if (profiles[i].profile(value instanceof PCell)) {
331+
setItemNode.execute(frame, localsDict, slot.getIdentifier(), ((PCell) value).getRef());
332+
} else {
333+
setItemNode.execute(frame, localsDict, slot.getIdentifier(), value);
334+
}
328335
}
329336
}
330337
}
@@ -346,7 +353,9 @@ static void doGenericDict(VirtualFrame frame, PFrame pyFrame, Frame frameToSync,
346353
FrameSlot slot = slots[i];
347354
if (FrameSlotIDs.isUserFrameSlot(slot.getIdentifier())) {
348355
Object value = frameToSync.getValue(slot);
349-
if (value != null) {
356+
if (value instanceof PCell) {
357+
setItemNode.execute(frame, localsDict, slot.getIdentifier(), ((PCell) value).getRef());
358+
} else {
350359
setItemNode.execute(frame, localsDict, slot.getIdentifier(), value);
351360
}
352361
}
@@ -363,6 +372,14 @@ protected static FrameSlot[] getSlots(FrameDescriptor fd) {
363372
return fd.getSlots().toArray(new FrameSlot[0]);
364373
}
365374

375+
protected static ConditionProfile[] getProfiles(int n) {
376+
ConditionProfile[] profiles = new ConditionProfile[n];
377+
for (int i = 0; i < profiles.length; i++) {
378+
profiles[i] = ConditionProfile.createBinaryProfile();
379+
}
380+
return profiles;
381+
}
382+
366383
/**
367384
* Guard that tests if the locals object is a dict having a {@link LocalsStorage} using the
368385
* same frame descriptor as the frame to synchronize. That means, the dict represents

0 commit comments

Comments
 (0)