Skip to content

Commit 8efb570

Browse files
committed
Start a PythonObjectLibrary and implement has/get/setDict with it
1 parent c5c24af commit 8efb570

File tree

13 files changed

+301
-88
lines changed

13 files changed

+301
-88
lines changed

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

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import com.oracle.graal.python.builtins.objects.method.PMethod;
110110
import com.oracle.graal.python.builtins.objects.module.PythonModule;
111111
import com.oracle.graal.python.builtins.objects.object.PythonObject;
112+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
112113
import com.oracle.graal.python.builtins.objects.set.PFrozenSet;
113114
import com.oracle.graal.python.builtins.objects.str.PString;
114115
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
@@ -188,6 +189,8 @@
188189
import com.oracle.truffle.api.frame.FrameDescriptor;
189190
import com.oracle.truffle.api.frame.FrameSlot;
190191
import com.oracle.truffle.api.frame.VirtualFrame;
192+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
193+
import com.oracle.truffle.api.library.CachedLibrary;
191194
import com.oracle.truffle.api.nodes.ExplodeLoop;
192195
import com.oracle.truffle.api.nodes.Node;
193196
import com.oracle.truffle.api.nodes.NodeUtil;
@@ -652,12 +655,17 @@ private static void setCustomLocals(Object[] args, Object locals) {
652655
PArguments.setCustomLocals(args, locals);
653656
}
654657

655-
private void setBuiltinsInGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, PythonModule builtins) {
658+
private void setBuiltinsInGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, PythonModule builtins, PythonObjectLibrary lib) {
656659
if (builtins != null) {
657-
PHashingCollection builtinsDict = builtins.getDict();
660+
PHashingCollection builtinsDict = lib.getDict(builtins);
658661
if (builtinsDict == null) {
659662
builtinsDict = factory().createDictFixedStorage(builtins);
660-
builtins.setDict(builtinsDict);
663+
try {
664+
lib.setDict(builtins, builtinsDict);
665+
} catch (UnsupportedMessageException e) {
666+
CompilerDirectives.transferToInterpreter();
667+
throw new IllegalStateException(e);
668+
}
661669
}
662670
setBuiltins.execute(frame, globals, BuiltinNames.__BUILTINS__, builtinsDict);
663671
} else {
@@ -666,9 +674,9 @@ private void setBuiltinsInGlobals(VirtualFrame frame, PDict globals, HashingColl
666674
}
667675
}
668676

669-
private void setCustomGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, Object[] args) {
677+
private void setCustomGlobals(VirtualFrame frame, PDict globals, HashingCollectionNodes.SetItemNode setBuiltins, Object[] args, PythonObjectLibrary lib) {
670678
PythonModule builtins = getContext().getBuiltins();
671-
setBuiltinsInGlobals(frame, globals, setBuiltins, builtins);
679+
setBuiltinsInGlobals(frame, globals, setBuiltins, builtins, lib);
672680
PArguments.setGlobals(args, globals);
673681
}
674682

@@ -687,10 +695,11 @@ Object execInheritGlobalsInheritLocals(VirtualFrame frame, Object source, @Suppr
687695

688696
@Specialization
689697
Object execCustomGlobalsGlobalLocals(VirtualFrame frame, Object source, PDict globals, @SuppressWarnings("unused") PNone locals,
698+
@CachedLibrary(limit = "1") PythonObjectLibrary lib,
690699
@Cached("create()") HashingCollectionNodes.SetItemNode setBuiltins) {
691700
PCode code = createAndCheckCode(frame, source);
692701
Object[] args = PArguments.create();
693-
setCustomGlobals(frame, globals, setBuiltins, args);
702+
setCustomGlobals(frame, globals, setBuiltins, args, lib);
694703
// here, we don't need to set any locals, since the {Write,Read,Delete}NameNodes will
695704
// fall back (like their CPython counterparts) to writing to the globals. We only need
696705
// to ensure that the `locals()` call still gives us the globals dict
@@ -717,10 +726,11 @@ Object execInheritGlobalsCustomLocals(VirtualFrame frame, Object source, @Suppre
717726

718727
@Specialization(guards = {"isMapping(locals)"})
719728
Object execCustomGlobalsCustomLocals(VirtualFrame frame, Object source, PDict globals, Object locals,
729+
@CachedLibrary(limit = "1") PythonObjectLibrary lib,
720730
@Cached("create()") HashingCollectionNodes.SetItemNode setBuiltins) {
721731
PCode code = createAndCheckCode(frame, source);
722732
Object[] args = PArguments.create();
723-
setCustomGlobals(frame, globals, setBuiltins, args);
733+
setCustomGlobals(frame, globals, setBuiltins, args, lib);
724734
setCustomLocals(args, locals);
725735

726736
return invokeNode.execute(frame, code.getRootCallTarget(), args);
@@ -1927,14 +1937,21 @@ abstract static class GlobalsNode extends PythonBuiltinNode {
19271937
private final ConditionProfile condProfile = ConditionProfile.createBinaryProfile();
19281938

19291939
@Specialization
1930-
public Object globals(VirtualFrame frame) {
1940+
public Object globals(VirtualFrame frame,
1941+
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
19311942
PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0);
19321943
PythonObject globals = callerFrame.getGlobals();
19331944
if (condProfile.profile(globals instanceof PythonModule)) {
1934-
PHashingCollection dict = globals.getDict();
1945+
PHashingCollection dict = lib.getDict(globals);
19351946
if (dict == null) {
19361947
CompilerDirectives.transferToInterpreter();
1937-
globals.setDict(dict = factory().createDictFixedStorage(globals));
1948+
dict = factory().createDictFixedStorage(globals);
1949+
try {
1950+
lib.setDict(globals, dict);
1951+
} catch (UnsupportedMessageException e) {
1952+
CompilerDirectives.transferToInterpreter();
1953+
throw new IllegalStateException(e);
1954+
}
19381955
}
19391956
return dict;
19401957
} else {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/DynamicObjectNativeWrapper.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
import com.oracle.graal.python.builtins.objects.method.PMethod;
102102
import com.oracle.graal.python.builtins.objects.mmap.PMMap;
103103
import com.oracle.graal.python.builtins.objects.object.PythonObject;
104+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
104105
import com.oracle.graal.python.builtins.objects.set.PSet;
105106
import com.oracle.graal.python.builtins.objects.slice.PSlice;
106107
import com.oracle.graal.python.builtins.objects.str.PString;
@@ -676,19 +677,20 @@ Object doMdDict(Object object, @SuppressWarnings("unused") String key,
676677
return toSulongNode.execute(getDictNode.execute(object, SpecialAttributeNames.__DICT__));
677678
}
678679

679-
@Specialization(guards = "eq(TP_DICT, key)")
680+
@Specialization(guards = "eq(TP_DICT, key)", limit = "1")
680681
Object doTpDict(PythonClass object, @SuppressWarnings("unused") String key,
681682
@Cached PythonObjectFactory factory,
682-
@Shared("toSulongNode") @Cached CExtNodes.ToSulongNode toSulongNode) {
683-
PHashingCollection dict = object.getDict();
683+
@CachedLibrary("object") PythonObjectLibrary lib,
684+
@Shared("toSulongNode") @Cached CExtNodes.ToSulongNode toSulongNode) throws UnsupportedMessageException {
685+
PHashingCollection dict = lib.getDict(object);
684686
if (!(dict instanceof PDict)) {
685687
assert dict instanceof PMappingproxy || dict == null;
686688
// If 'dict instanceof PMappingproxy', it seems that someone already used
687689
// '__dict__'
688690
// on this type and created a mappingproxy object. We need to replace it by a
689691
// dict.
690692
dict = factory.createDictFixedStorage(object);
691-
object.setDict(dict);
693+
lib.setDict(object, dict);
692694
}
693695
assert dict instanceof PDict;
694696
return toSulongNode.execute(dict);
@@ -937,26 +939,27 @@ Object doMdDef(PythonObject object, @SuppressWarnings("unused") String key, Obje
937939
return value;
938940
}
939941

940-
@Specialization(guards = "eq(TP_DICT, key)")
942+
@Specialization(guards = "eq(TP_DICT, key)", limit = "1")
941943
Object doTpDict(PythonManagedClass object, @SuppressWarnings("unused") String key, Object nativeValue,
944+
@CachedLibrary("object") PythonObjectLibrary lib,
942945
@Cached CExtNodes.AsPythonObjectNode asPythonObjectNode,
943946
@Cached HashingStorageNodes.GetItemInteropNode getItem,
944947
@Cached WriteAttributeToObjectNode writeAttrNode,
945-
@Cached IsBuiltinClassProfile isPrimitiveDictProfile) {
948+
@Cached IsBuiltinClassProfile isPrimitiveDictProfile) throws UnsupportedMessageException {
946949
Object value = asPythonObjectNode.execute(nativeValue);
947950
if (value instanceof PDict && isPrimitiveDictProfile.profileObject((PDict) value, PythonBuiltinClassType.PDict)) {
948951
// special and fast case: commit items and change store
949952
PDict d = (PDict) value;
950953
for (Object k : d.keys()) {
951954
writeAttrNode.execute(object, k, getItem.passState().execute(d.getDictStorage(), k));
952955
}
953-
PHashingCollection existing = object.getDict();
956+
PHashingCollection existing = lib.getDict(object);
954957
if (existing != null) {
955958
d.setDictStorage(existing.getDictStorage());
956959
} else {
957960
d.setDictStorage(new DynamicObjectStorage.PythonObjectDictStorage(object.getStorage()));
958961
}
959-
object.setDict(d);
962+
lib.setDict(object, d);
960963
} else {
961964
// TODO custom mapping object
962965
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import com.oracle.graal.python.builtins.objects.method.PMethod;
5050
import com.oracle.graal.python.builtins.objects.module.PythonModule;
5151
import com.oracle.graal.python.builtins.objects.object.PythonObject;
52+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
5253
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode;
5354
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
5455
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
@@ -67,6 +68,8 @@
6768
import com.oracle.truffle.api.dsl.NodeFactory;
6869
import com.oracle.truffle.api.dsl.Specialization;
6970
import com.oracle.truffle.api.frame.VirtualFrame;
71+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
72+
import com.oracle.truffle.api.library.CachedLibrary;
7073

7174
@CoreFunctions(extendClasses = {PythonBuiltinClassType.PFunction, PythonBuiltinClassType.PBuiltinFunction})
7275
public class AbstractFunctionBuiltins extends PythonBuiltins {
@@ -231,18 +234,30 @@ Object getModule(PBuiltinFunction self, Object value) {
231234
@Builtin(name = __DICT__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
232235
@GenerateNodeFactory
233236
abstract static class DictNode extends PythonBinaryBuiltinNode {
234-
@Specialization
235-
PNone dict(PFunction self, PHashingCollection mapping) {
236-
self.setDict(mapping);
237+
@Specialization(limit = "1")
238+
PNone dict(PFunction self, PHashingCollection mapping,
239+
@CachedLibrary("self") PythonObjectLibrary lib) {
240+
try {
241+
lib.setDict(self, mapping);
242+
} catch (UnsupportedMessageException e) {
243+
CompilerDirectives.transferToInterpreter();
244+
throw new IllegalStateException(e);
245+
}
237246
return PNone.NONE;
238247
}
239248

240-
@Specialization(guards = "isNoValue(mapping)")
241-
Object dict(PFunction self, @SuppressWarnings("unused") PNone mapping) {
242-
PHashingCollection dict = self.getDict();
249+
@Specialization(guards = "isNoValue(mapping)", limit = "1")
250+
Object dict(PFunction self, @SuppressWarnings("unused") PNone mapping,
251+
@CachedLibrary("self") PythonObjectLibrary lib) {
252+
PHashingCollection dict = lib.getDict(self);
243253
if (dict == null) {
244254
dict = factory().createDictFixedStorage(self);
245-
self.setDict(dict);
255+
try {
256+
lib.setDict(self, dict);
257+
} catch (UnsupportedMessageException e) {
258+
CompilerDirectives.transferToInterpreter();
259+
throw new IllegalStateException(e);
260+
}
246261
}
247262
return dict;
248263
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@
103103
import com.oracle.truffle.api.dsl.NodeFactory;
104104
import com.oracle.truffle.api.dsl.Specialization;
105105
import com.oracle.truffle.api.frame.VirtualFrame;
106+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
107+
import com.oracle.truffle.api.library.CachedLibrary;
106108
import com.oracle.truffle.api.nodes.UnexpectedResultException;
107109
import com.oracle.truffle.api.profiles.BranchProfile;
108110
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -569,19 +571,31 @@ protected boolean isBuiltinObjectExact(PythonObject self) {
569571
return exactBuiltinInstanceProfile.profileIsOtherBuiltinObject(self, PythonBuiltinClassType.PythonModule);
570572
}
571573

572-
@Specialization(guards = {"!isBuiltinObjectExact(self)", "!isClass(self)", "!isExactObjectInstance(self)", "isNoValue(none)"})
573-
Object dict(PythonObject self, @SuppressWarnings("unused") PNone none) {
574-
PHashingCollection dict = self.getDict();
574+
@Specialization(guards = {"!isBuiltinObjectExact(self)", "!isClass(self)", "!isExactObjectInstance(self)", "isNoValue(none)"}, limit = "1")
575+
Object dict(PythonObject self, @SuppressWarnings("unused") PNone none,
576+
@CachedLibrary("self") PythonObjectLibrary lib) {
577+
PHashingCollection dict = lib.getDict(self);
575578
if (dict == null) {
576579
dict = factory().createDictFixedStorage(self);
577-
self.setDict(dict);
580+
try {
581+
lib.setDict(self, dict);
582+
} catch (UnsupportedMessageException e) {
583+
CompilerDirectives.transferToInterpreter();
584+
throw new IllegalStateException(e);
585+
}
578586
}
579587
return dict;
580588
}
581589

582-
@Specialization(guards = {"!isBuiltinObjectExact(self)", "!isClass(self)", "!isExactObjectInstance(self)"})
583-
Object dict(PythonObject self, PDict dict) {
584-
self.setDict(dict);
590+
@Specialization(guards = {"!isBuiltinObjectExact(self)", "!isClass(self)", "!isExactObjectInstance(self)"}, limit = "1")
591+
Object dict(PythonObject self, PDict dict,
592+
@CachedLibrary("self") PythonObjectLibrary lib) {
593+
try {
594+
lib.setDict(self, dict);
595+
} catch (UnsupportedMessageException e) {
596+
CompilerDirectives.transferToInterpreter();
597+
throw new IllegalStateException(e);
598+
}
585599
return PNone.NONE;
586600
}
587601

0 commit comments

Comments
 (0)