68
68
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__CLASSCELL__ ;
69
69
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__DICTOFFSET__ ;
70
70
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__DICT__ ;
71
- import static com .oracle .graal .python .nodes .SpecialAttributeNames .__ITEMSIZE__ ;
72
71
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__MODULE__ ;
73
72
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__MRO_ENTRIES__ ;
74
73
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__NAME__ ;
169
168
import com .oracle .graal .python .builtins .objects .type .PythonBuiltinClass ;
170
169
import com .oracle .graal .python .builtins .objects .type .PythonClass ;
171
170
import com .oracle .graal .python .builtins .objects .type .PythonManagedClass ;
171
+ import static com .oracle .graal .python .builtins .objects .type .TypeBuiltins .TYPE_ITEMSIZE ;
172
172
import com .oracle .graal .python .builtins .objects .type .TypeNodes ;
173
173
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetBestBaseClassNode ;
174
+ import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetItemsizeNode ;
174
175
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetMroNode ;
175
176
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetNameNode ;
176
177
import com .oracle .graal .python .builtins .objects .type .TypeNodes .IsAcceptableBaseNode ;
187
188
import com .oracle .graal .python .nodes .attributes .LookupInheritedAttributeNode ;
188
189
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
189
190
import com .oracle .graal .python .nodes .attributes .SetAttributeNode ;
191
+ import com .oracle .graal .python .nodes .attributes .WriteAttributeToObjectNode ;
190
192
import com .oracle .graal .python .nodes .builtins .TupleNodes ;
191
193
import com .oracle .graal .python .nodes .call .CallNode ;
192
194
import com .oracle .graal .python .nodes .call .special .CallUnaryMethodNode ;
@@ -2090,6 +2092,8 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
2090
2092
@ Cached CallNode callNewFuncNode ,
2091
2093
@ Cached ("create(__DICT__)" ) LookupAttributeInMRONode getDictAttrNode ,
2092
2094
@ Cached ("create(__WEAKREF__)" ) LookupAttributeInMRONode getWeakRefAttrNode ,
2095
+ @ Cached GetItemsizeNode getItemSize ,
2096
+ @ Cached WriteAttributeToObjectNode writeItemSize ,
2093
2097
@ Cached GetBestBaseClassNode getBestBaseNode ,
2094
2098
@ Cached DictBuiltins .CopyNode copyDict ) {
2095
2099
// Determine the proper metatype to deal with this
@@ -2107,7 +2111,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
2107
2111
2108
2112
try {
2109
2113
PDict namespace = (PDict ) copyDict .call (frame , namespaceOrig );
2110
- PythonClass newType = typeMetaclass (frame , name , bases , namespace , metaclass , nslib , getDictAttrNode , getWeakRefAttrNode , getBestBaseNode );
2114
+ PythonClass newType = typeMetaclass (frame , name , bases , namespace , metaclass , nslib , getDictAttrNode , getWeakRefAttrNode , getBestBaseNode , getItemSize , writeItemSize );
2111
2115
2112
2116
for (DictEntry entry : nslib .entries (namespace .getDictStorage ())) {
2113
2117
Object setName = getSetNameNode .execute (entry .value );
@@ -2202,7 +2206,8 @@ private String getModuleNameFromGlobals(PythonObject globals, HashingStorageLibr
2202
2206
}
2203
2207
2204
2208
private PythonClass typeMetaclass (VirtualFrame frame , String name , PTuple bases , PDict namespace , Object metaclass ,
2205
- HashingStorageLibrary nslib , LookupAttributeInMRONode getDictAttrNode , LookupAttributeInMRONode getWeakRefAttrNode , GetBestBaseClassNode getBestBaseNode ) {
2209
+ HashingStorageLibrary nslib , LookupAttributeInMRONode getDictAttrNode , LookupAttributeInMRONode getWeakRefAttrNode , GetBestBaseClassNode getBestBaseNode ,
2210
+ GetItemsizeNode getItemSize , WriteAttributeToObjectNode writeItemSize ) {
2206
2211
Object [] array = ensureGetObjectArrayNode ().execute (bases );
2207
2212
2208
2213
PythonAbstractClass [] basesArray ;
@@ -2259,12 +2264,12 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
2259
2264
// may_add_dict = base->tp_dictoffset == 0
2260
2265
boolean mayAddDict = getDictAttrNode .execute (base ) == PNone .NO_VALUE ;
2261
2266
// may_add_weak = base->tp_weaklistoffset == 0 && base->tp_itemsize == 0
2262
- // TODO: maybe also slots size as equivalent of tp_itemsize?
2263
- boolean mayAddWeakRef = getWeakRefAttrNode .execute (base ) == PNone .NO_VALUE ;
2267
+ boolean hasItemSize = getItemSize . execute ( base ) != 0 ;
2268
+ boolean mayAddWeakRef = getWeakRefAttrNode .execute (base ) == PNone .NO_VALUE && ! hasItemSize ;
2264
2269
2265
2270
if (slots [0 ] == null ) {
2266
2271
// takes care of checking if we may_add_dict and adds it if needed
2267
- addDictIfNative (frame , pythonClass );
2272
+ addDictIfNative (frame , pythonClass , getItemSize , writeItemSize );
2268
2273
addDictDescrAttribute (basesArray , getDictAttrNode , pythonClass );
2269
2274
addWeakrefDescrAttribute (pythonClass );
2270
2275
} else {
@@ -2287,8 +2292,6 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
2287
2292
slotsStorage = ((PList ) slotsObject ).getSequenceStorage ();
2288
2293
}
2289
2294
int slotlen = getListLenNode ().execute (slotsStorage );
2290
- // TODO: tfel - check if slots are allowed. They are not if the base class is var
2291
- // sized
2292
2295
2293
2296
for (int i = 0 ; i < slotlen ; i ++) {
2294
2297
String slotName ;
@@ -2300,7 +2303,7 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
2300
2303
throw raise (TypeError , ErrorMessages .MUST_BE_STRINGS_NOT_P , "__slots__ items" , element );
2301
2304
}
2302
2305
if (__DICT__ .equals (slotName )) {
2303
- if (!mayAddDict || addDict || addDictIfNative (frame , pythonClass )) {
2306
+ if (!mayAddDict || addDict || addDictIfNative (frame , pythonClass , getItemSize , writeItemSize )) {
2304
2307
throw raise (TypeError , ErrorMessages .DICT_SLOT_DISALLOWED_WE_GOT_ONE );
2305
2308
}
2306
2309
addDict = true ;
@@ -2574,15 +2577,15 @@ private CastToListNode getCastToListNode() {
2574
2577
/**
2575
2578
* check that the native base does not already have tp_dictoffset
2576
2579
*/
2577
- private boolean addDictIfNative (VirtualFrame frame , PythonManagedClass pythonClass ) {
2580
+ private boolean addDictIfNative (VirtualFrame frame , PythonManagedClass pythonClass , GetItemsizeNode getItemSize , WriteAttributeToObjectNode writeItemSize ) {
2578
2581
boolean addedNewDict = false ;
2579
2582
if (pythonClass .needsNativeAllocation ()) {
2580
2583
for (Object cls : getMro (pythonClass )) {
2581
2584
if (PGuards .isNativeClass (cls )) {
2582
2585
// Use GetAnyAttributeNode since these are get-set-descriptors
2583
2586
long dictoffset = ensureCastToIntNode ().execute (ensureGetAttributeNode ().executeObject (frame , cls , __DICTOFFSET__ ));
2584
2587
long basicsize = ensureCastToIntNode ().execute (ensureGetAttributeNode ().executeObject (frame , cls , __BASICSIZE__ ));
2585
- long itemsize = ensureCastToIntNode ().execute (ensureGetAttributeNode (). executeObject ( frame , cls , __ITEMSIZE__ ));
2588
+ long itemsize = ensureCastToIntNode ().execute (getItemSize . execute ( cls ));
2586
2589
if (dictoffset == 0 ) {
2587
2590
addedNewDict = true ;
2588
2591
// add_dict
@@ -2595,7 +2598,7 @@ private boolean addDictIfNative(VirtualFrame frame, PythonManagedClass pythonCla
2595
2598
}
2596
2599
ensureWriteAttrNode ().execute (frame , pythonClass , __DICTOFFSET__ , dictoffset );
2597
2600
ensureWriteAttrNode ().execute (frame , pythonClass , __BASICSIZE__ , basicsize );
2598
- ensureWriteAttrNode () .execute (frame , pythonClass , __ITEMSIZE__ , itemsize );
2601
+ writeItemSize .execute (pythonClass , TYPE_ITEMSIZE , itemsize );
2599
2602
break ;
2600
2603
}
2601
2604
}
0 commit comments