Skip to content

Commit ca379fb

Browse files
committed
Allow setting __dict__ of native subclasses
1 parent 9c34e9c commit ca379fb

File tree

4 files changed

+29
-16
lines changed

4 files changed

+29
-16
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,6 +2204,7 @@ Object notNumber(PythonContext context, @SuppressWarnings("unused") TruffleStrin
22042204
* {@code wrap_sq_delitem}, {@code wrap_sq_setitem}, {@code asdf}.
22052205
*/
22062206
@ImportStatic(PGuards.class)
2207+
@GenerateUncached
22072208
public abstract static class CheckPrimitiveFunctionResultNode extends CheckFunctionResultNode {
22082209

22092210
@Specialization(guards = "!isMinusOne(result)")

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ public enum NativeCAPISymbol implements NativeCExtSymbol {
217217
FUN_PY_TRUFFLE_INITIALIZE_STORAGE_ITEM("PyTruffle_InitializeStorageItem"),
218218
FUN_PY_TRUFFLE_NATIVE_TUPLE_ITEMS("PyTruffle_NativeTupleItems"),
219219
FUN_PY_OBJECT_GENERIC_GET_DICT("_PyObject_GenericGetDict"),
220+
FUN_PY_OBJECT_GENERIC_SET_DICT("PyObject_GenericSetDict"),
220221
FUN_PY_OBJECT_NEW("PyTruffle_Object_New"),
221222
FUN_GET_THREAD_STATE_TYPE_ID("get_thread_state_typeid"),
222223
FUN_GET_PY_BUFFER_TYPEID("get_Py_buffer_typeid"),

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

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@
125125
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsOtherBuiltinClassProfile;
126126
import com.oracle.graal.python.nodes.object.DeleteDictNode;
127127
import com.oracle.graal.python.nodes.object.GetClassNode;
128-
import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
129128
import com.oracle.graal.python.nodes.object.GetOrCreateDictNode;
130129
import com.oracle.graal.python.nodes.object.InlinedGetClassNode;
131130
import com.oracle.graal.python.nodes.object.IsNode;
@@ -648,7 +647,7 @@ protected static boolean isAnyBuiltinButModule(Node inliningTarget, IsOtherBuilt
648647

649648
@Specialization(guards = {"!isAnyBuiltinButModule(inliningTarget, otherBuiltinClassProfile, selfClass)", //
650649
"!isExactObject(inliningTarget, isBuiltinClassProfile, selfClass)", "isNoValue(none)"}, limit = "1")
651-
Object dict(VirtualFrame frame, PythonObject self, @SuppressWarnings("unused") PNone none,
650+
Object dict(VirtualFrame frame, Object self, @SuppressWarnings("unused") PNone none,
652651
@Bind("this") Node inliningTarget,
653652
@SuppressWarnings("unused") @Shared("otherBuiltinClassProfile") @Cached IsOtherBuiltinClassProfile otherBuiltinClassProfile,
654653
@SuppressWarnings("unused") @Shared("isBuiltinClassProfile") @Cached InlineIsBuiltinClassProfile isBuiltinClassProfile,
@@ -671,7 +670,7 @@ Object dict(VirtualFrame frame, PythonObject self, @SuppressWarnings("unused") P
671670

672671
@Specialization(guards = {"!isAnyBuiltinButModule(inliningTarget, otherBuiltinClassProfile, selfClass)", //
673672
"!isExactObject(inliningTarget, isBuiltinClassProfile, selfClass)", "!isPythonModule(self)"}, limit = "1")
674-
static Object dict(VirtualFrame frame, PythonObject self, PDict dict,
673+
static Object dict(VirtualFrame frame, Object self, PDict dict,
675674
@Bind("this") Node inliningTarget,
676675
@SuppressWarnings("unused") @Shared("otherBuiltinClassProfile") @Cached IsOtherBuiltinClassProfile otherBuiltinClassProfile,
677676
@SuppressWarnings("unused") @Shared("isBuiltinClassProfile") @Cached InlineIsBuiltinClassProfile isBuiltinClassProfile,
@@ -693,16 +692,6 @@ static Object dict(VirtualFrame frame, PythonObject self, PDict dict,
693692
return PNone.NONE;
694693
}
695694

696-
@Specialization(guards = "isNoValue(none)")
697-
Object dict(PythonAbstractNativeObject self, @SuppressWarnings("unused") PNone none,
698-
@Cached GetDictIfExistsNode getDict) {
699-
PDict dict = getDict.execute(self);
700-
if (dict == null) {
701-
raise(self, none);
702-
}
703-
return dict;
704-
}
705-
706695
@Specialization
707696
static Object dict(VirtualFrame frame, @SuppressWarnings("unused") PythonObject self, @SuppressWarnings("unused") DescriptorDeleteMarker marker,
708697
@Bind("this") Node inliningTarget,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/SetDictNode.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,20 @@
4040
*/
4141
package com.oracle.graal.python.nodes.object;
4242

43+
import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_OBJECT_GENERIC_SET_DICT;
44+
45+
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
46+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
47+
import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.CheckPrimitiveFunctionResultNode;
4348
import com.oracle.graal.python.builtins.objects.dict.PDict;
4449
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4550
import com.oracle.graal.python.builtins.objects.type.PythonClass;
51+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
4652
import com.oracle.graal.python.nodes.PNodeWithContext;
53+
import com.oracle.graal.python.runtime.PythonContext;
4754
import com.oracle.truffle.api.dsl.Bind;
4855
import com.oracle.truffle.api.dsl.Cached;
4956
import com.oracle.truffle.api.dsl.Cached.Shared;
50-
import com.oracle.truffle.api.dsl.Fallback;
5157
import com.oracle.truffle.api.dsl.GenerateUncached;
5258
import com.oracle.truffle.api.dsl.Specialization;
5359
import com.oracle.truffle.api.library.CachedLibrary;
@@ -57,7 +63,7 @@
5763

5864
@GenerateUncached
5965
public abstract class SetDictNode extends PNodeWithContext {
60-
public abstract void execute(PythonObject object, PDict dict);
66+
public abstract void execute(Object object, PDict dict);
6167

6268
@Specialization
6369
static void doPythonClass(PythonClass object, PDict dict,
@@ -67,12 +73,28 @@ static void doPythonClass(PythonClass object, PDict dict,
6773
object.setDictHiddenProp(inliningTarget, dylib, hasMroShapeProfile, dict);
6874
}
6975

70-
@Fallback
76+
@Specialization(guards = "!isPythonClass(object)")
7177
static void doPythonObjectNotClass(PythonObject object, PDict dict,
7278
@Shared("dylib") @CachedLibrary(limit = "4") DynamicObjectLibrary dylib) {
7379
object.setDict(dylib, dict);
7480
}
7581

82+
@Specialization
83+
void doNativeObject(PythonAbstractNativeObject object, PDict dict,
84+
@Cached CExtNodes.ToSulongNode objectToSulong,
85+
@Cached CExtNodes.ToSulongNode dictToSulong,
86+
@Cached CExtNodes.PCallCapiFunction callGetDictNode,
87+
@Cached CheckPrimitiveFunctionResultNode checkResult) {
88+
assert !IsTypeNode.getUncached().execute(object);
89+
PythonContext context = getContext();
90+
Object result = callGetDictNode.call(FUN_PY_OBJECT_GENERIC_SET_DICT, objectToSulong.execute(object), dictToSulong.execute(dict), context.getNativeNull().getPtr());
91+
checkResult.execute(context, FUN_PY_OBJECT_GENERIC_SET_DICT.getTsName(), result);
92+
}
93+
94+
protected static boolean isPythonClass(Object object) {
95+
return object instanceof PythonClass;
96+
}
97+
7698
public static SetDictNode getUncached() {
7799
return SetDictNodeGen.getUncached();
78100
}

0 commit comments

Comments
 (0)