|
55 | 55 | import com.oracle.truffle.api.library.ExportMessage;
|
56 | 56 | import com.oracle.truffle.api.object.DynamicObjectLibrary;
|
57 | 57 | import com.oracle.truffle.api.object.Shape;
|
| 58 | +import java.util.ArrayList; |
58 | 59 |
|
59 | 60 | public abstract class PythonManagedClass extends PythonObject implements PythonAbstractClass {
|
60 | 61 |
|
@@ -210,31 +211,69 @@ private void unsafeSetSuperClass(PythonAbstractClass... newBaseClasses) {
|
210 | 211 |
|
211 | 212 | @TruffleBoundary
|
212 | 213 | public void setSuperClass(PythonAbstractClass... newBaseClasses) {
|
213 |
| - PythonAbstractClass[] oldBaseClasses = getBaseClasses(); |
214 |
| - try { |
215 |
| - setSuperClassInternal(newBaseClasses); |
216 |
| - } catch (PException pe) { |
217 |
| - setSuperClassInternal(oldBaseClasses); |
218 |
| - throw pe; |
219 |
| - } |
220 |
| - } |
221 |
| - |
222 |
| - private void setSuperClassInternal(PythonAbstractClass[] basses) { |
223 |
| - for (PythonAbstractClass base : basses) { |
224 |
| - if (base != null) { |
225 |
| - GetSubclassesNode.getUncached().execute(base).add(this); |
| 214 | + ArrayList<Set<PythonAbstractClass>> newBasesSubclasses = new ArrayList<>(newBaseClasses.length); |
| 215 | + for (int i = 0; i < newBaseClasses.length; i++) { |
| 216 | + if (newBaseClasses[i] != null) { |
| 217 | + newBasesSubclasses.add(GetSubclassesNode.getUncached().execute(newBaseClasses[i])); |
226 | 218 | }
|
227 | 219 | }
|
228 | 220 |
|
229 |
| - this.baseClasses = basses; |
230 |
| - this.methodResolutionOrder.setInternalArrayObject(ComputeMroNode.doSlowPath(this)); |
| 221 | + PythonAbstractClass[] oldBaseClasses = getBaseClasses(); |
| 222 | + Object[] oldMRO = this.methodResolutionOrder.getInternalArray(); |
231 | 223 |
|
232 | 224 | Set<PythonAbstractClass> subclasses = GetSubclassesNode.getUncached().execute(this);
|
233 |
| - for (PythonAbstractClass scls : subclasses) { |
| 225 | + PythonAbstractClass[] subclassesArray = subclasses.toArray(new PythonAbstractClass[subclasses.size()]); |
| 226 | + Object[][] oldSubClasssMROs = new Object[subclasses.size()][]; |
| 227 | + for (int i = 0; i < subclassesArray.length; i++) { |
| 228 | + PythonAbstractClass scls = subclassesArray[i]; |
234 | 229 | if (scls instanceof PythonManagedClass) {
|
235 |
| - ((PythonManagedClass) scls).methodResolutionOrder.setInternalArrayObject(ComputeMroNode.doSlowPath(scls)); |
| 230 | + oldSubClasssMROs[i] = ((PythonManagedClass) scls).methodResolutionOrder.getInternalArray(); |
236 | 231 | }
|
237 | 232 | }
|
| 233 | + |
| 234 | + try { |
| 235 | + for (PythonAbstractClass base : newBaseClasses) { |
| 236 | + if (base != null) { |
| 237 | + GetSubclassesNode.getUncached().execute(base).add(this); |
| 238 | + } |
| 239 | + } |
| 240 | + |
| 241 | + this.baseClasses = newBaseClasses; |
| 242 | + this.methodResolutionOrder.setInternalArrayObject(ComputeMroNode.doSlowPath(this)); |
| 243 | + this.methodResolutionOrder.lookupChanged(); |
| 244 | + |
| 245 | + for (PythonAbstractClass scls : subclasses) { |
| 246 | + if (scls instanceof PythonManagedClass) { |
| 247 | + PythonManagedClass pmc = (PythonManagedClass) scls; |
| 248 | + pmc.methodResolutionOrder.setInternalArrayObject(ComputeMroNode.doSlowPath(scls)); |
| 249 | + pmc.methodResolutionOrder.lookupChanged(); |
| 250 | + } |
| 251 | + } |
| 252 | + } catch (PException pe) { |
| 253 | + // undo |
| 254 | + for (int i = 0; i < newBaseClasses.length; i++) { |
| 255 | + PythonAbstractClass base = newBaseClasses[i]; |
| 256 | + if (base != null) { |
| 257 | + Set<PythonAbstractClass> s = GetSubclassesNode.getUncached().execute(base); |
| 258 | + s.clear(); |
| 259 | + s.addAll(newBasesSubclasses.get(i)); |
| 260 | + } |
| 261 | + } |
| 262 | + |
| 263 | + this.baseClasses = oldBaseClasses; |
| 264 | + this.methodResolutionOrder.setInternalArrayObject(oldMRO); |
| 265 | + this.methodResolutionOrder.lookupChanged(); |
| 266 | + |
| 267 | + for (int i = 0; i < subclassesArray.length; i++) { |
| 268 | + PythonAbstractClass scls = subclassesArray[i]; |
| 269 | + if (oldSubClasssMROs[i] != null) { |
| 270 | + PythonManagedClass pmc = (PythonManagedClass) scls; |
| 271 | + pmc.methodResolutionOrder.setInternalArrayObject(oldSubClasssMROs[i]); |
| 272 | + pmc.methodResolutionOrder.lookupChanged(); |
| 273 | + } |
| 274 | + } |
| 275 | + throw pe; |
| 276 | + } |
238 | 277 | }
|
239 | 278 |
|
240 | 279 | final Set<PythonAbstractClass> getSubClasses() {
|
|
0 commit comments