37
37
import com .oracle .graal .python .builtins .objects .type .PythonAbstractClass ;
38
38
import com .oracle .graal .python .builtins .objects .type .PythonManagedClass ;
39
39
import com .oracle .graal .python .builtins .objects .type .TypeNodes ;
40
+ import com .oracle .truffle .api .Assumption ;
40
41
import com .oracle .truffle .api .CompilerAsserts ;
41
42
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
42
43
import com .oracle .truffle .api .object .DynamicObject ;
47
48
import com .oracle .truffle .api .object .dsl .Nullable ;
48
49
49
50
public class PythonObject extends PythonAbstractObject {
51
+ private LazyPythonClass storedPythonClass ;
50
52
private final DynamicObject storage ;
51
53
52
54
public PythonObject (LazyPythonClass pythonClass ) {
53
55
assert pythonClass != null : getClass ().getSimpleName ();
54
- storage = TypeNodes .GetInstanceShape .doSlowPath (pythonClass ).newInstance ();
56
+ this .storedPythonClass = pythonClass ;
57
+ this .storage = TypeNodes .GetInstanceShape .doSlowPath (pythonClass ).newInstance ();
55
58
assert getLazyPythonClass () == pythonClass ;
56
59
}
57
60
58
- public PythonObject (Shape instanceShape ) {
59
- storage = instanceShape .newInstance ();
61
+ public PythonObject (LazyPythonClass pythonClass , Shape instanceShape ) {
62
+ assert pythonClass != null ;
63
+ this .storedPythonClass = pythonClass ;
64
+ this .storage = instanceShape .newInstance ();
60
65
}
61
66
62
67
public final PythonAbstractClass getPythonClass () {
@@ -69,15 +74,25 @@ public final PythonAbstractClass getPythonClass() {
69
74
}
70
75
}
71
76
72
- public final void setLazyPythonClass (PythonAbstractClass cls ) {
73
- PythonObjectLayoutImpl .INSTANCE .setLazyPythonClass (storage , cls );
77
+ public final void setLazyPythonClass (PythonAbstractClass cls , Assumption storingClassesInShapes ) {
78
+ storedPythonClass = cls ;
79
+ if (storingClassesInShapes .isValid ()) {
80
+ PythonObjectLayoutImpl .INSTANCE .setLazyPythonClass (storage , cls );
81
+ } else {
82
+ if (PythonObjectLayoutImpl .INSTANCE .getLazyPythonClass (storage ) != null ) {
83
+ // for the builtin class enums, we now should change the shape
84
+ // to the generic one that just doesn't store the class
85
+ Shape shape = storage .getShape ();
86
+ storage .setShapeAndGrow (shape , shape .changeType (emptyShape .getObjectType ()));
87
+ }
88
+ }
74
89
}
75
90
76
91
/**
77
92
* This is usually final, a fact may be optimized further if the storage turns into a constant.
78
93
*/
79
94
public final LazyPythonClass getLazyPythonClass () {
80
- return PythonObjectLayoutImpl . INSTANCE . getLazyPythonClass ( storage ) ;
95
+ return storedPythonClass ;
81
96
}
82
97
83
98
public final DynamicObject getStorage () {
@@ -132,7 +147,7 @@ public String toString() {
132
147
}
133
148
134
149
/**
135
- * Returns the dictionary backed by {@link #storage} (only available for user objects).
150
+ * Returns the dictionary (only available for user objects).
136
151
*/
137
152
public final PHashingCollection getDict () {
138
153
return PythonObjectLayoutImpl .INSTANCE .getDict (storage );
@@ -161,10 +176,17 @@ protected static interface PythonObjectLayout {
161
176
void setLazyPythonClass (DynamicObject object , LazyPythonClass value );
162
177
}
163
178
179
+ private static final Shape emptyShape = PythonObjectLayoutImpl .INSTANCE .createPythonObjectShape (null ).getShape ();
180
+
164
181
public static Shape freshShape (LazyPythonClass klass ) {
182
+ assert (PythonLanguage .getCurrent ().singleContextAssumption .isValid () && klass != null ) || klass instanceof PythonBuiltinClassType ;
165
183
return PythonObjectLayoutImpl .INSTANCE .createPythonObjectShape (klass ).getShape ();
166
184
}
167
185
186
+ public static Shape freshShape () {
187
+ return emptyShape ;
188
+ }
189
+
168
190
public static LazyPythonClass getLazyPythonClass (ObjectType type ) {
169
191
return PythonObjectLayoutImpl .INSTANCE .getLazyPythonClass (type );
170
192
}
0 commit comments