49
49
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
50
50
import com .oracle .graal .python .builtins .PythonBuiltins ;
51
51
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 ;
52
56
import com .oracle .graal .python .builtins .objects .dict .PDict ;
53
57
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
54
58
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
55
59
import com .oracle .graal .python .builtins .objects .referencetype .PReferenceType ;
56
60
import com .oracle .graal .python .builtins .objects .referencetype .PReferenceType .WeakRefStorage ;
57
61
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
58
62
import com .oracle .graal .python .builtins .objects .type .LazyPythonClass ;
63
+ import com .oracle .graal .python .nodes .PGuards ;
59
64
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
60
65
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
61
66
import com .oracle .graal .python .runtime .AsyncHandler ;
62
67
import com .oracle .graal .python .runtime .PythonCore ;
63
68
import com .oracle .graal .python .runtime .exception .PythonErrorType ;
64
69
import com .oracle .truffle .api .CompilerDirectives ;
65
70
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 ;
66
75
import com .oracle .truffle .api .dsl .Fallback ;
67
76
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
68
77
import com .oracle .truffle .api .dsl .NodeFactory ;
69
78
import com .oracle .truffle .api .dsl .Specialization ;
70
79
import com .oracle .truffle .api .frame .VirtualFrame ;
71
80
import com .oracle .truffle .api .interop .TruffleObject ;
72
81
import com .oracle .truffle .api .object .HiddenKey ;
82
+ import com .oracle .truffle .api .dsl .TypeSystemReference ;
73
83
74
- @ SuppressWarnings ("unused" )
75
84
@ CoreFunctions (defineModule = "_weakref" )
76
85
public class WeakRefModuleBuiltins extends PythonBuiltins {
77
86
private final static HiddenKey weakRefQueueKey = new HiddenKey ("weakRefQueue" );
@@ -123,18 +132,49 @@ public void postInitialize(PythonCore core) {
123
132
@ Builtin (name = "ReferenceType" , minNumOfPositionalArgs = 2 , maxNumOfPositionalArgs = 3 , constructsClass = PythonBuiltinClassType .PReferenceType )
124
133
@ GenerateNodeFactory
125
134
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 ;
127
137
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 ) {
130
140
return factory ().createReferenceType (cls , object , null , getWeakReferenceQueue ());
131
141
}
132
142
133
- @ Specialization
143
+ @ Specialization ( guards = "!isNativeObject(object)" )
134
144
public PReferenceType refType (LazyPythonClass cls , Object object , Object callback ) {
135
145
return factory ().createReferenceType (cls , object , callback , getWeakReferenceQueue ());
136
146
}
137
147
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
+
138
178
private ReferenceQueue <Object > getWeakReferenceQueue () {
139
179
Object queueObject = readQueue .execute (getCore ().lookupType (PythonBuiltinClassType .PReferenceType ), weakRefQueueKey );
140
180
if (queueObject instanceof ReferenceQueue ) {
@@ -145,11 +185,6 @@ private ReferenceQueue<Object> getWeakReferenceQueue() {
145
185
throw new IllegalStateException ("the weak reference queue was modified!" );
146
186
}
147
187
}
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
- }
153
188
}
154
189
155
190
// getweakrefcount(obj)
@@ -162,7 +197,7 @@ public Object getCount(PReferenceType pReferenceType) {
162
197
}
163
198
164
199
@ Specialization
165
- public Object getCount (PNone none ) {
200
+ public Object getCount (@ SuppressWarnings ( "unused" ) PNone none ) {
166
201
return 0 ;
167
202
}
168
203
}
@@ -172,7 +207,7 @@ public Object getCount(PNone none) {
172
207
@ GenerateNodeFactory
173
208
public abstract static class GetWeakRefsNode extends PythonBuiltinNode {
174
209
@ Specialization
175
- public Object getRefs (PythonObject pythonObject ) {
210
+ public Object getRefs (@ SuppressWarnings ( "unused" ) PythonObject pythonObject ) {
176
211
return PNone .NONE ;
177
212
}
178
213
}
@@ -182,7 +217,7 @@ public Object getRefs(PythonObject pythonObject) {
182
217
@ GenerateNodeFactory
183
218
public abstract static class RemoveDeadWeakRefsNode extends PythonBuiltinNode {
184
219
@ Specialization
185
- public Object removeDeadRefs (PDict dict , Object key ) {
220
+ public Object removeDeadRefs (@ SuppressWarnings ( "unused" ) PDict dict , @ SuppressWarnings ( "unused" ) Object key ) {
186
221
// TODO: do the removal from the dict ... (_weakref.c:60)
187
222
return PNone .NONE ;
188
223
}
0 commit comments