InternalClass *InternalClass::changeMember(String *string, PropertyAttributes data, uint *index) { data.resolve(); uint idx = find(string); Q_ASSERT(idx != UINT_MAX); if (index) *index = idx; if (data == propertyData.at(idx)) return this; Transition t = { { string->identifier }, (int)data.flags() }; QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t); if (tit != transitions.constEnd()) return tit.value(); // create a new class and add it to the tree InternalClass *newClass = engine->emptyClass->changeVTable(vtable); newClass = newClass->changePrototype(prototype); for (uint i = 0; i < size; ++i) { if (i == idx) { newClass = newClass->addMember(nameMap.at(i), data); } else if (!propertyData.at(i).isEmpty()) { newClass = newClass->addMember(nameMap.at(i), propertyData.at(i)); } } transitions.insert(t, newClass); return newClass; }
void InternalClass::removeMember(Object *object, Identifier *id) { InternalClass *oldClass = object->internalClass; uint propIdx = oldClass->propertyTable.lookup(id); Q_ASSERT(propIdx < oldClass->size); Transition t = { { id } , -1 }; QHash<Transition, InternalClass *>::const_iterator tit = object->internalClass->transitions.constFind(t); if (tit != object->internalClass->transitions.constEnd()) { object->internalClass = tit.value(); } else { // create a new class and add it to the tree InternalClass *newClass = oldClass->engine->emptyClass->changeVTable(oldClass->vtable); newClass = newClass->changePrototype(oldClass->prototype); for (uint i = 0; i < oldClass->size; ++i) { if (i == propIdx) continue; if (!oldClass->propertyData.at(i).isEmpty()) newClass = newClass->addMember(oldClass->nameMap.at(i), oldClass->propertyData.at(i)); } object->internalClass = newClass; } // remove the entry in memberdata memmove(object->memberData.data() + propIdx, object->memberData.data() + propIdx + 1, (object->internalClass->size - propIdx)*sizeof(Value)); oldClass->transitions.insert(t, object->internalClass); }
InternalClass *InternalClass::changeVTable(const ManagedVTable *vt) { if (vtable == vt) return this; Transition t; t.vtable = vt; t.flags = Transition::VTableChange; QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t); if (tit != transitions.constEnd()) return tit.value(); // create a new class and add it to the tree InternalClass *newClass; if (this == engine->emptyClass) { newClass = engine->newClass(*this); newClass->vtable = vt; } else { newClass = engine->emptyClass->changeVTable(vt); newClass = newClass->changePrototype(prototype); for (uint i = 0; i < size; ++i) { if (!propertyData.at(i).isEmpty()) newClass = newClass->addMember(nameMap.at(i), propertyData.at(i)); } } transitions.insert(t, newClass); return newClass; }