|
75 | 75 | import com.oracle.graal.python.builtins.modules.BuiltinConstructorsFactory;
|
76 | 76 | import com.oracle.graal.python.builtins.objects.PNone;
|
77 | 77 | import com.oracle.graal.python.builtins.objects.PNotImplemented;
|
| 78 | +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; |
| 79 | +import com.oracle.graal.python.builtins.objects.cext.structs.CFields; |
| 80 | +import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; |
78 | 81 | import com.oracle.graal.python.builtins.objects.dict.PDict;
|
79 | 82 | import com.oracle.graal.python.builtins.objects.function.PKeyword;
|
80 | 83 | import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorBuiltins.DescrDeleteNode;
|
|
84 | 87 | import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
|
85 | 88 | import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsClinicProviders.FormatNodeClinicProviderGen;
|
86 | 89 | import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsClinicProviders.ReduceExNodeClinicProviderGen;
|
87 |
| -import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory.GetAttributeNodeFactory; |
88 | 90 | import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory.DictNodeFactory;
|
| 91 | +import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory.GetAttributeNodeFactory; |
89 | 92 | import com.oracle.graal.python.builtins.objects.set.PSet;
|
90 | 93 | import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
|
91 | 94 | import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
|
92 | 95 | import com.oracle.graal.python.builtins.objects.type.TpSlots;
|
93 | 96 | import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
|
| 97 | +import com.oracle.graal.python.builtins.objects.type.TypeFlags; |
94 | 98 | import com.oracle.graal.python.builtins.objects.type.TypeNodes;
|
95 | 99 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode;
|
96 | 100 | import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
|
|
127 | 131 | import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
|
128 | 132 | import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
|
129 | 133 | import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile;
|
| 134 | +import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassProfile; |
130 | 135 | import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsOtherBuiltinClassProfile;
|
131 | 136 | import com.oracle.graal.python.nodes.object.DeleteDictNode;
|
132 | 137 | import com.oracle.graal.python.nodes.object.GetClassNode;
|
|
146 | 151 | import com.oracle.truffle.api.dsl.Cached;
|
147 | 152 | import com.oracle.truffle.api.dsl.Cached.Exclusive;
|
148 | 153 | import com.oracle.truffle.api.dsl.Cached.Shared;
|
149 |
| -import com.oracle.truffle.api.dsl.Fallback; |
| 154 | +import com.oracle.truffle.api.dsl.GenerateCached; |
| 155 | +import com.oracle.truffle.api.dsl.GenerateInline; |
150 | 156 | import com.oracle.truffle.api.dsl.GenerateNodeFactory;
|
151 | 157 | import com.oracle.truffle.api.dsl.Idempotent;
|
152 | 158 | import com.oracle.truffle.api.dsl.ImportStatic;
|
@@ -180,46 +186,49 @@ static Object getClass(Object self, @SuppressWarnings("unused") PNone value,
|
180 | 186 | return getClassNode.execute(inliningTarget, self);
|
181 | 187 | }
|
182 | 188 |
|
183 |
| - @Specialization(guards = "isNativeClass(klass)") |
184 |
| - static Object setClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object klass, |
185 |
| - @Shared @Cached PRaiseNode raiseNode) { |
186 |
| - throw raiseNode.raise(TypeError, ErrorMessages.CLASS_ASSIGNMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES); |
187 |
| - } |
188 |
| - |
189 |
| - @Specialization(guards = "isPythonClass(value) || isPythonBuiltinClassType(value)") |
190 |
| - static PNone setClass(VirtualFrame frame, PythonObject self, Object value, |
| 189 | + @Specialization(guards = "!isNoValue(value)") |
| 190 | + static PNone setClass(VirtualFrame frame, Object self, Object value, |
191 | 191 | @Bind("this") Node inliningTarget,
|
192 |
| - @Cached HiddenAttr.WriteNode writeHiddenAttrNode, |
193 |
| - @Cached IsOtherBuiltinClassProfile classProfile1, |
194 |
| - @Cached IsOtherBuiltinClassProfile classProfile2, |
| 192 | + @Cached TypeNodes.IsTypeNode isTypeNode, |
| 193 | + @Cached IsBuiltinClassProfile isModuleProfile, |
| 194 | + @Cached TypeNodes.GetTypeFlagsNode getTypeFlagsNode, |
195 | 195 | @Cached CheckCompatibleForAssigmentNode checkCompatibleForAssigmentNode,
|
196 | 196 | @Exclusive @Cached GetClassNode getClassNode,
|
197 |
| - @Exclusive @Cached PRaiseNode.Lazy raiseNode) { |
| 197 | + @Cached SetClassNode setClassNode, |
| 198 | + @Cached PRaiseNode.Lazy raiseNode) { |
| 199 | + if (!isTypeNode.execute(inliningTarget, value)) { |
| 200 | + throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CLASS_MUST_BE_SET_TO_CLASS, value); |
| 201 | + } |
198 | 202 | Object type = getClassNode.execute(inliningTarget, self);
|
199 |
| - if (isBuiltinClassNotModule(inliningTarget, value, classProfile1) || PGuards.isNativeClass(value) || isBuiltinClassNotModule(inliningTarget, type, classProfile2) || |
200 |
| - PGuards.isNativeClass(type)) { |
| 203 | + boolean bothModuleSubtypes = isModuleProfile.profileClass(inliningTarget, type, PythonBuiltinClassType.PythonModule) && |
| 204 | + isModuleProfile.profileClass(inliningTarget, value, PythonBuiltinClassType.PythonModule); |
| 205 | + boolean bothMutable = (getTypeFlagsNode.execute(type) & TypeFlags.IMMUTABLETYPE) == 0 && (getTypeFlagsNode.execute(value) & TypeFlags.IMMUTABLETYPE) == 0; |
| 206 | + if (!bothModuleSubtypes && !bothMutable) { |
201 | 207 | throw raiseNode.get(inliningTarget).raise(TypeError, ErrorMessages.CLASS_ASSIGNMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
|
202 | 208 | }
|
203 | 209 |
|
204 | 210 | checkCompatibleForAssigmentNode.execute(frame, type, value);
|
205 |
| - writeHiddenAttrNode.execute(inliningTarget, self, HiddenAttr.CLASS, value); |
| 211 | + setClassNode.execute(inliningTarget, self, value); |
| 212 | + |
206 | 213 | return PNone.NONE;
|
207 | 214 | }
|
208 | 215 |
|
209 |
| - private static boolean isBuiltinClassNotModule(Node inliningTarget, Object type, IsOtherBuiltinClassProfile classProfile) { |
210 |
| - return classProfile.profileIsOtherBuiltinClass(inliningTarget, type, PythonBuiltinClassType.PythonModule); |
211 |
| - } |
| 216 | + @GenerateInline |
| 217 | + @GenerateCached(false) |
| 218 | + abstract static class SetClassNode extends Node { |
| 219 | + public abstract void execute(Node inliningTarget, Object self, Object newClass); |
212 | 220 |
|
213 |
| - @Specialization(guards = {"isPythonClass(value) || isPythonBuiltinClassType(value)", "!isPythonObject(self)"}) |
214 |
| - static Object getClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object value, |
215 |
| - @Shared @Cached PRaiseNode raiseNode) { |
216 |
| - throw raiseNode.raise(TypeError, ErrorMessages.CLASS_ASSIGNMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES); |
217 |
| - } |
| 221 | + @Specialization |
| 222 | + static void doPythonObject(Node inliningTarget, PythonObject self, Object newClass, |
| 223 | + @Cached HiddenAttr.WriteNode writeHiddenAttrNode) { |
| 224 | + writeHiddenAttrNode.execute(inliningTarget, self, HiddenAttr.CLASS, newClass); |
| 225 | + } |
218 | 226 |
|
219 |
| - @Fallback |
220 |
| - static Object getClassError(@SuppressWarnings("unused") Object self, Object value, |
221 |
| - @Shared @Cached PRaiseNode raiseNode) { |
222 |
| - throw raiseNode.raise(TypeError, ErrorMessages.CLASS_MUST_BE_SET_TO_CLASS, value); |
| 227 | + @Specialization |
| 228 | + static void doNative(PythonAbstractNativeObject self, Object newClass, |
| 229 | + @Cached(inline = false) CStructAccess.WriteObjectNewRefNode writeObjectNewRefNode) { |
| 230 | + writeObjectNewRefNode.writeToObject(self, CFields.PyObject__ob_type, newClass); |
| 231 | + } |
223 | 232 | }
|
224 | 233 | }
|
225 | 234 |
|
|
0 commit comments