3737import com .oracle .graal .python .builtins .objects .type .PythonAbstractClass ;
3838import com .oracle .graal .python .builtins .objects .type .PythonManagedClass ;
3939import com .oracle .graal .python .builtins .objects .type .TypeNodes ;
40+ import com .oracle .truffle .api .Assumption ;
4041import com .oracle .truffle .api .CompilerAsserts ;
4142import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
4243import com .oracle .truffle .api .object .DynamicObject ;
4748import com .oracle .truffle .api .object .dsl .Nullable ;
4849
4950public class PythonObject extends PythonAbstractObject {
51+ private LazyPythonClass storedPythonClass ;
5052 private final DynamicObject storage ;
5153
5254 public PythonObject (LazyPythonClass pythonClass ) {
5355 assert pythonClass != null : getClass ().getSimpleName ();
54- storage = TypeNodes .GetInstanceShape .doSlowPath (pythonClass ).newInstance ();
56+ this .storedPythonClass = pythonClass ;
57+ this .storage = TypeNodes .GetInstanceShape .doSlowPath (pythonClass ).newInstance ();
5558 assert getLazyPythonClass () == pythonClass ;
5659 }
5760
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 ();
6065 }
6166
6267 public final PythonAbstractClass getPythonClass () {
@@ -69,15 +74,25 @@ public final PythonAbstractClass getPythonClass() {
6974 }
7075 }
7176
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+ }
7489 }
7590
7691 /**
7792 * This is usually final, a fact may be optimized further if the storage turns into a constant.
7893 */
7994 public final LazyPythonClass getLazyPythonClass () {
80- return PythonObjectLayoutImpl . INSTANCE . getLazyPythonClass ( storage ) ;
95+ return storedPythonClass ;
8196 }
8297
8398 public final DynamicObject getStorage () {
@@ -132,7 +147,7 @@ public String toString() {
132147 }
133148
134149 /**
135- * Returns the dictionary backed by {@link #storage} (only available for user objects).
150+ * Returns the dictionary (only available for user objects).
136151 */
137152 public final PHashingCollection getDict () {
138153 return PythonObjectLayoutImpl .INSTANCE .getDict (storage );
@@ -161,10 +176,17 @@ protected static interface PythonObjectLayout {
161176 void setLazyPythonClass (DynamicObject object , LazyPythonClass value );
162177 }
163178
179+ private static final Shape emptyShape = PythonObjectLayoutImpl .INSTANCE .createPythonObjectShape (null ).getShape ();
180+
164181 public static Shape freshShape (LazyPythonClass klass ) {
182+ assert (PythonLanguage .getCurrent ().singleContextAssumption .isValid () && klass != null ) || klass instanceof PythonBuiltinClassType ;
165183 return PythonObjectLayoutImpl .INSTANCE .createPythonObjectShape (klass ).getShape ();
166184 }
167185
186+ public static Shape freshShape () {
187+ return emptyShape ;
188+ }
189+
168190 public static LazyPythonClass getLazyPythonClass (ObjectType type ) {
169191 return PythonObjectLayoutImpl .INSTANCE .getLazyPythonClass (type );
170192 }
0 commit comments