Structure* Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObject* object) { checkOffsetConsistency(); ASSERT(isDictionary()); if (isUncacheableDictionary()) { ASSERT(propertyTable()); size_t propertyCount = propertyTable()->size(); // Holds our values compacted by insertion order. Vector<JSValue> values(propertyCount); // Copies out our values from their hashed locations, compacting property table offsets as we go. unsigned i = 0; PropertyTable::iterator end = propertyTable()->end(); m_offset = invalidOffset; for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter, ++i) { values[i] = object->getDirect(iter->offset); m_offset = iter->offset = offsetForPropertyNumber(i, m_inlineCapacity); } // Copies in our values to their compacted locations. for (unsigned i = 0; i < propertyCount; i++) object->putDirect(globalData, offsetForPropertyNumber(i, m_inlineCapacity), values[i]); propertyTable()->clearDeletedOffsets(); checkOffsetConsistency(); } m_dictionaryKind = NoneDictionaryKind; return this; }
void Structure::createPropertyMap(JSGlobalData& globalData, unsigned capacity) { ASSERT(!propertyTable()); checkConsistency(); propertyTable().set(globalData, this, PropertyTable::create(globalData, capacity)); }
PropertyTable* Structure::takePropertyTableOrCloneIfPinned(JSGlobalData& globalData, Structure* owner) { materializePropertyMapIfNecessaryForPinning(globalData); if (m_isPinnedPropertyTable) return propertyTable()->copy(globalData, owner, propertyTable()->size() + 1); PropertyTable* takenPropertyTable = propertyTable().get(); propertyTable().clear(); return takenPropertyTable; }
void Structure::despecifyAllFunctions(JSGlobalData& globalData) { materializePropertyMapIfNecessary(globalData); if (!propertyTable()) return; PropertyTable::iterator end = propertyTable()->end(); for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) iter->specificValue.clear(); }
void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, PropertyName propertyName) { StringImpl* rep = propertyName.uid(); materializePropertyMapIfNecessary(globalData); ASSERT(isDictionary()); ASSERT(propertyTable()); PropertyMapEntry* entry = propertyTable()->find(rep).first; ASSERT(entry); entry->specificValue.clear(); }
bool Structure::despecifyFunction(JSGlobalData& globalData, PropertyName propertyName) { materializePropertyMapIfNecessary(globalData); if (!propertyTable()) return false; PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first; if (!entry) return false; ASSERT(entry->specificValue); entry->specificValue.clear(); return true; }
void Structure::checkConsistency() { if (!propertyTable()) return; if (!m_hasNonEnumerableProperties) { PropertyTable::iterator end = propertyTable()->end(); for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) { ASSERT(!(iter->attributes & DontEnum)); } } propertyTable()->checkConsistency(); }
PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes, JSCell*& specificValue) { ASSERT(structure()->classInfo() == &s_info); materializePropertyMapIfNecessary(globalData); if (!propertyTable()) return invalidOffset; PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first; if (!entry) return invalidOffset; attributes = entry->attributes; specificValue = entry->specificValue.get(); return entry->offset; }
void Structure::pin() { ASSERT(propertyTable()); m_isPinnedPropertyTable = true; clearPreviousID(); m_nameInPrevious.clear(); }
// In future we may want to cache this property. bool Structure::isSealed(JSGlobalData& globalData) { if (isExtensible()) return false; materializePropertyMapIfNecessary(globalData); if (!propertyTable()) return true; PropertyTable::iterator end = propertyTable()->end(); for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) { if ((iter->attributes & DontDelete) != DontDelete) return false; } return true; }
void Structure::getPropertyNamesFromStructure(JSGlobalData& globalData, PropertyNameArray& propertyNames, EnumerationMode mode) { materializePropertyMapIfNecessary(globalData); if (!propertyTable()) return; bool knownUnique = !propertyNames.size(); PropertyTable::iterator end = propertyTable()->end(); for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) { ASSERT(m_hasNonEnumerableProperties || !(iter->attributes & DontEnum)); if (iter->key->isIdentifier() && (!(iter->attributes & DontEnum) || mode == IncludeDontEnumProperties)) { if (knownUnique) propertyNames.addKnownUnique(iter->key); else propertyNames.add(iter->key); } } }
PropertyOffset Structure::putSpecificValue(JSGlobalData& globalData, PropertyName propertyName, unsigned attributes, JSCell* specificValue) { ASSERT(!JSC::isValidOffset(get(globalData, propertyName))); checkConsistency(); if (attributes & DontEnum) m_hasNonEnumerableProperties = true; StringImpl* rep = propertyName.uid(); if (!propertyTable()) createPropertyMap(globalData); PropertyOffset newOffset = propertyTable()->nextOffset(m_inlineCapacity); propertyTable()->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue), m_offset, PropertyTable::PropertyOffsetMayChange); checkConsistency(); return newOffset; }
PropertyOffset Structure::remove(PropertyName propertyName) { checkConsistency(); StringImpl* rep = propertyName.uid(); if (!propertyTable()) return invalidOffset; PropertyTable::find_iterator position = propertyTable()->find(rep); if (!position.first) return invalidOffset; PropertyOffset offset = position.first->offset; propertyTable()->remove(position); propertyTable()->addDeletedOffset(offset); checkConsistency(); return offset; }
void Structure::materializePropertyMap(JSGlobalData& globalData) { ASSERT(structure()->classInfo() == &s_info); ASSERT(!propertyTable()); Vector<Structure*, 8> structures; structures.append(this); Structure* structure = this; // Search for the last Structure with a property table. while ((structure = structure->previousID())) { if (structure->m_isPinnedPropertyTable) { ASSERT(structure->propertyTable()); ASSERT(!structure->previousID()); propertyTable().set(globalData, this, structure->propertyTable()->copy(globalData, 0, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity))); break; } structures.append(structure); } if (!propertyTable()) createPropertyMap(globalData, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)); for (ptrdiff_t i = structures.size() - 1; i >= 0; --i) { structure = structures[i]; if (!structure->m_nameInPrevious) continue; PropertyMapEntry entry(globalData, this, structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious.get()); propertyTable()->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange); } checkOffsetConsistency(); }
void Scene::createEntity(const std::string& entityType, const std::string& name, const Any& any) { AnyTableReader propertyTable(any); if (entityType == "VisibleEntity") { insert(VisibleEntity::create(name, this, propertyTable, m_modelTable)); } else if (entityType == "Light") { insert(Light::create(name, this, propertyTable)); } else if (entityType == "Camera") { insert(Camera::create(name, this, propertyTable)); } else if (entityType == "MarkerEntity") { insert(MarkerEntity::create(name, this, propertyTable)); } else if (entityType == "Skybox") { insert(Skybox::create(name, this, propertyTable)); } else { any.verify(false, std::string("Unrecognized Entity type: \"") + entityType + "\""); } m_lastStructuralChangeTime = System::time(); }
PropertyTable* Structure::copyPropertyTableForPinning(JSGlobalData& globalData, Structure* owner) { if (propertyTable()) return PropertyTable::clone(globalData, owner, *propertyTable().get()); return PropertyTable::create(globalData, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)); }
PropertyTable* Structure::copyPropertyTable(JSGlobalData& globalData, Structure* owner) { if (!propertyTable()) return 0; return PropertyTable::clone(globalData, owner, *propertyTable().get()); }