Skip to content

Commit 63b6055

Browse files
committed
Support 'tp_weaklistoffset'.
1 parent e198a5e commit 63b6055

File tree

4 files changed

+59
-13
lines changed

4 files changed

+59
-13
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ PyObject* get_tp_mro(PyTypeObject* obj) {
279279
return native_to_java(obj->tp_mro);
280280
}
281281

282+
/** to be used from Java code only; reads native 'tp_subclasses' field */
283+
PyObject* get_tp_subclasses(PyTypeObject* obj) {
284+
return native_to_java(obj->tp_subclasses);
285+
}
286+
282287
/** to be used from Java code only; returns the type ID for a byte array */
283288
polyglot_typeid get_byte_array_typeid(uint64_t len) {
284289
return polyglot_array_typeid(polyglot_i8_typeid(), len);

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

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,38 @@
4949
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5050
import com.oracle.graal.python.builtins.PythonBuiltins;
5151
import com.oracle.graal.python.builtins.objects.PNone;
52+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes;
53+
import com.oracle.graal.python.builtins.objects.cext.NativeMemberNames;
54+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.GetTypeMemberNode;
55+
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
5256
import com.oracle.graal.python.builtins.objects.dict.PDict;
5357
import com.oracle.graal.python.builtins.objects.module.PythonModule;
5458
import com.oracle.graal.python.builtins.objects.object.PythonObject;
5559
import com.oracle.graal.python.builtins.objects.referencetype.PReferenceType;
5660
import com.oracle.graal.python.builtins.objects.referencetype.PReferenceType.WeakRefStorage;
5761
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
5862
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
63+
import com.oracle.graal.python.nodes.PGuards;
5964
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6065
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
6166
import com.oracle.graal.python.runtime.AsyncHandler;
6267
import com.oracle.graal.python.runtime.PythonCore;
6368
import com.oracle.graal.python.runtime.exception.PythonErrorType;
6469
import com.oracle.truffle.api.CompilerDirectives;
6570
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
71+
import com.oracle.graal.python.nodes.object.GetLazyClassNode;
72+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
73+
import com.oracle.graal.python.nodes.truffle.PythonTypes;
74+
import com.oracle.truffle.api.dsl.Cached;
6675
import com.oracle.truffle.api.dsl.Fallback;
6776
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
6877
import com.oracle.truffle.api.dsl.NodeFactory;
6978
import com.oracle.truffle.api.dsl.Specialization;
7079
import com.oracle.truffle.api.frame.VirtualFrame;
7180
import com.oracle.truffle.api.interop.TruffleObject;
7281
import com.oracle.truffle.api.object.HiddenKey;
82+
import com.oracle.truffle.api.dsl.TypeSystemReference;
7383

74-
@SuppressWarnings("unused")
7584
@CoreFunctions(defineModule = "_weakref")
7685
public class WeakRefModuleBuiltins extends PythonBuiltins {
7786
private final static HiddenKey weakRefQueueKey = new HiddenKey("weakRefQueue");
@@ -123,18 +132,49 @@ public void postInitialize(PythonCore core) {
123132
@Builtin(name = "ReferenceType", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3, constructsClass = PythonBuiltinClassType.PReferenceType)
124133
@GenerateNodeFactory
125134
public abstract static class ReferenceTypeNode extends PythonBuiltinNode {
126-
@Child ReadAttributeFromObjectNode readQueue = ReadAttributeFromObjectNode.create();
135+
@Child private ReadAttributeFromObjectNode readQueue = ReadAttributeFromObjectNode.create();
136+
@Child private CExtNodes.GetTypeMemberNode getTpWeaklistoffsetNode;
127137

128-
@Specialization
129-
public PReferenceType refType(LazyPythonClass cls, Object object, PNone none) {
138+
@Specialization(guards = "!isNativeObject(object)")
139+
public PReferenceType refType(LazyPythonClass cls, Object object, @SuppressWarnings("unused") PNone none) {
130140
return factory().createReferenceType(cls, object, null, getWeakReferenceQueue());
131141
}
132142

133-
@Specialization
143+
@Specialization(guards = "!isNativeObject(object)")
134144
public PReferenceType refType(LazyPythonClass cls, Object object, Object callback) {
135145
return factory().createReferenceType(cls, object, callback, getWeakReferenceQueue());
136146
}
137147

148+
@Specialization
149+
public PReferenceType refType(LazyPythonClass cls, PythonAbstractNativeObject pythonObject, Object callback,
150+
@Cached("create()") GetLazyClassNode getClassNode,
151+
@Cached("create()") IsBuiltinClassProfile profile) {
152+
LazyPythonClass clazz = getClassNode.execute(pythonObject);
153+
154+
// if the object is a type, a weak ref is allowed
155+
if (profile.profileClass(clazz, PythonBuiltinClassType.PythonClass)) {
156+
return factory().createReferenceType(cls, pythonObject, callback, getWeakReferenceQueue());
157+
}
158+
159+
// if the object's type is a native type, we need to consider 'tp_weaklistoffset'
160+
if (PGuards.isNativeClass(clazz)) {
161+
if (getTpWeaklistoffsetNode == null) {
162+
CompilerDirectives.transferToInterpreterAndInvalidate();
163+
getTpWeaklistoffsetNode = insert(GetTypeMemberNode.create(NativeMemberNames.TP_WEAKLISTOFFSET));
164+
}
165+
Object tpWeaklistoffset = getTpWeaklistoffsetNode.execute(clazz);
166+
if (tpWeaklistoffset != PNone.NO_VALUE) {
167+
return factory().createReferenceType(cls, pythonObject, callback, getWeakReferenceQueue());
168+
}
169+
}
170+
return refType(cls, pythonObject, callback);
171+
}
172+
173+
@Fallback
174+
public PReferenceType refType(Object cls, Object object, Object callback) {
175+
throw raise(PythonErrorType.TypeError, "cannot create weak reference to '%p' object", object);
176+
}
177+
138178
private ReferenceQueue<Object> getWeakReferenceQueue() {
139179
Object queueObject = readQueue.execute(getCore().lookupType(PythonBuiltinClassType.PReferenceType), weakRefQueueKey);
140180
if (queueObject instanceof ReferenceQueue) {
@@ -145,11 +185,6 @@ private ReferenceQueue<Object> getWeakReferenceQueue() {
145185
throw new IllegalStateException("the weak reference queue was modified!");
146186
}
147187
}
148-
149-
@Fallback
150-
public PReferenceType refType(Object cls, Object object, Object callback) {
151-
throw raise(PythonErrorType.TypeError, "cannot create weak reference to '%p' object", object);
152-
}
153188
}
154189

155190
// getweakrefcount(obj)
@@ -162,7 +197,7 @@ public Object getCount(PReferenceType pReferenceType) {
162197
}
163198

164199
@Specialization
165-
public Object getCount(PNone none) {
200+
public Object getCount(@SuppressWarnings("unused") PNone none) {
166201
return 0;
167202
}
168203
}
@@ -172,7 +207,7 @@ public Object getCount(PNone none) {
172207
@GenerateNodeFactory
173208
public abstract static class GetWeakRefsNode extends PythonBuiltinNode {
174209
@Specialization
175-
public Object getRefs(PythonObject pythonObject) {
210+
public Object getRefs(@SuppressWarnings("unused") PythonObject pythonObject) {
176211
return PNone.NONE;
177212
}
178213
}
@@ -182,7 +217,7 @@ public Object getRefs(PythonObject pythonObject) {
182217
@GenerateNodeFactory
183218
public abstract static class RemoveDeadWeakRefsNode extends PythonBuiltinNode {
184219
@Specialization
185-
public Object removeDeadRefs(PDict dict, Object key) {
220+
public Object removeDeadRefs(@SuppressWarnings("unused") PDict dict, @SuppressWarnings("unused") Object key) {
186221
// TODO: do the removal from the dict ... (_weakref.c:60)
187222
return PNone.NONE;
188223
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public abstract class NativeCAPISymbols {
6464
public static final String FUN_GET_TP_BASES = "get_tp_bases";
6565
public static final String FUN_GET_TP_NAME = "get_tp_name";
6666
public static final String FUN_GET_TP_MRO = "get_tp_mro";
67+
public static final String FUN_GET_TP_SUBCLASSES = "get_tp_subclasses";
6768
public static final String FUN_DEREF_HANDLE = "truffle_deref_handle_for_managed";
6869
public static final String FUN_GET_BYTE_ARRAY_TYPE_ID = "get_byte_array_typeid";
6970
public static final String FUN_GET_PTR_ARRAY_TYPE_ID = "get_ptr_array_typeid";

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import com.oracle.graal.python.PythonLanguage;
3535
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
36+
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
3637
import com.oracle.graal.python.builtins.objects.array.PArray;
3738
import com.oracle.graal.python.builtins.objects.bytes.PByteArray;
3839
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
@@ -564,6 +565,10 @@ public PReferenceType createReferenceType(LazyPythonClass cls, Object object, Ob
564565
return trace(new PReferenceType(cls, object, callback, queue));
565566
}
566567

568+
public PReferenceType createReferenceType(Object object, Object callback, ReferenceQueue<Object> queue) {
569+
return createReferenceType(PythonBuiltinClassType.PReferenceType, object, callback, queue);
570+
}
571+
567572
/*
568573
* Frames, traces and exceptions
569574
*/

0 commit comments

Comments
 (0)