size_t Structure::get(const Identifier& propertyName, unsigned& attributes) { ASSERT(!propertyName.isNull()); materializePropertyMapIfNecessary(); if (!m_propertyTable) return notFound; UString::Rep* rep = propertyName._ustring.rep(); unsigned i = rep->computedHash(); #if DUMP_PROPERTYMAP_STATS ++numProbes; #endif unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; if (entryIndex == emptyEntryIndex) return notFound; if (rep == m_propertyTable->entries()[entryIndex - 1].key) { attributes = m_propertyTable->entries()[entryIndex - 1].attributes; return m_propertyTable->entries()[entryIndex - 1].offset; } #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif unsigned k = 1 | doubleHash(rep->computedHash()); while (1) { i += k; #if DUMP_PROPERTYMAP_STATS ++numRehashes; #endif entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; if (entryIndex == emptyEntryIndex) return notFound; if (rep == m_propertyTable->entries()[entryIndex - 1].key) { attributes = m_propertyTable->entries()[entryIndex - 1].attributes; return m_propertyTable->entries()[entryIndex - 1].offset; } } }
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func) : Base(globalObject, structure) #if ENABLE(JIT) , m_executable(exec->globalData().getHostFunction(func)) #endif , m_scopeChain(globalObject->globalScopeChain()) { putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); #if ENABLE(JIT) putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum); #else UNUSED_PARAM(length); UNUSED_PARAM(func); ASSERT_NOT_REACHED(); #endif }
size_t Structure::remove(const Identifier& propertyName) { ASSERT(!propertyName.isNull()); checkConsistency(); StringImpl* rep = propertyName.impl(); if (!m_propertyTable) return notFound; PropertyTable::find_iterator position = m_propertyTable->find(rep); if (!position.first) return notFound; size_t offset = position.first->offset; m_propertyTable->remove(position); m_propertyTable->addDeletedOffset(offset); checkConsistency(); return offset; }
size_t Structure::remove(const Identifier& propertyName) { ASSERT(!propertyName.isNull()); checkConsistency(); UString::Rep* rep = propertyName._ustring.rep(); if (!m_propertyTable) return notFound; #if DUMP_PROPERTYMAP_STATS ++numProbes; ++numRemoves; #endif // Find the thing to remove. unsigned i = rep->computedHash(); unsigned k = 0; unsigned entryIndex; UString::Rep* key = 0; while (1) { entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; if (entryIndex == emptyEntryIndex) return notFound; key = m_propertyTable->entries()[entryIndex - 1].key; if (rep == key) break; if (k == 0) { k = 1 | doubleHash(rep->computedHash()); #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif } i += k; #if DUMP_PROPERTYMAP_STATS ++numRehashes; #endif } // Replace this one element with the deleted sentinel. Also clear out // the entry so we can iterate all the entries as needed. m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = deletedSentinelIndex; size_t offset = m_propertyTable->entries()[entryIndex - 1].offset; key->deref(); m_propertyTable->entries()[entryIndex - 1].key = 0; m_propertyTable->entries()[entryIndex - 1].attributes = 0; m_propertyTable->entries()[entryIndex - 1].offset = 0; if (!m_propertyTable->deletedOffsets) m_propertyTable->deletedOffsets = new Vector<unsigned>; m_propertyTable->deletedOffsets->append(offset); ASSERT(m_propertyTable->keyCount >= 1); --m_propertyTable->keyCount; ++m_propertyTable->deletedSentinelCount; if (m_propertyTable->deletedSentinelCount * 4 >= m_propertyTable->size) rehashPropertyMapHashTable(); checkConsistency(); return offset; }
size_t Structure::put(const Identifier& propertyName, unsigned attributes) { ASSERT(!propertyName.isNull()); ASSERT(get(propertyName) == notFound); checkConsistency(); UString::Rep* rep = propertyName._ustring.rep(); if (!m_propertyTable) createPropertyMapHashTable(); // FIXME: Consider a fast case for tables with no deleted sentinels. unsigned i = rep->computedHash(); unsigned k = 0; bool foundDeletedElement = false; unsigned deletedElementIndex = 0; // initialize to make the compiler happy #if DUMP_PROPERTYMAP_STATS ++numProbes; #endif while (1) { unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; if (entryIndex == emptyEntryIndex) break; if (entryIndex == deletedSentinelIndex) { // If we find a deleted-element sentinel, remember it for use later. if (!foundDeletedElement) { foundDeletedElement = true; deletedElementIndex = i; } } if (k == 0) { k = 1 | doubleHash(rep->computedHash()); #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif } i += k; #if DUMP_PROPERTYMAP_STATS ++numRehashes; #endif } // Figure out which entry to use. unsigned entryIndex = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount + 2; if (foundDeletedElement) { i = deletedElementIndex; --m_propertyTable->deletedSentinelCount; // Since we're not making the table bigger, we can't use the entry one past // the end that we were planning on using, so search backwards for the empty // slot that we can use. We know it will be there because we did at least one // deletion in the past that left an entry empty. while (m_propertyTable->entries()[--entryIndex - 1].key) { } } // Create a new hash table entry. m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex; // Create a new hash table entry. rep->ref(); m_propertyTable->entries()[entryIndex - 1].key = rep; m_propertyTable->entries()[entryIndex - 1].attributes = attributes; m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed; unsigned newOffset; if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) { newOffset = m_propertyTable->deletedOffsets->last(); m_propertyTable->deletedOffsets->removeLast(); } else newOffset = m_propertyTable->keyCount; m_propertyTable->entries()[entryIndex - 1].offset = newOffset; ++m_propertyTable->keyCount; if ((m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount) * 2 >= m_propertyTable->size) expandPropertyMapHashTable(); checkConsistency(); return newOffset; }
InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const Identifier& name) : JSObjectWithGlobalObject(globalObject, structure) { putDirect(globalData->propertyNames->name, jsString(globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); }
void PropertyMap::remove(const Identifier &name) { assert(!name.isNull()); checkConsistency(); UString::Rep *rep = name._ustring.rep(); UString::Rep *key; if (!_table) { #if USE_SINGLE_ENTRY key = _singleEntry.key; if (rep == key) { key->deref(); _singleEntry.key = 0; checkConsistency(); } #endif return; } // Find the thing to remove. unsigned h = rep->hash(); int sizeMask = _table->sizeMask; Entry *entries = _table->entries; int i = h & sizeMask; int k = 0; #if DUMP_STATISTICS ++numProbes; ++numRemoves; numCollisions += entries[i].key && entries[i].key != rep; #endif while ((key = entries[i].key)) { if (rep == key) break; if (k == 0) k = 1 | (h % sizeMask); i = (i + k) & sizeMask; #if DUMP_STATISTICS ++numRehashes; #endif } if (!key) return; // Replace this one element with the deleted sentinel. Also set value to 0 and attributes to DontEnum // to help callers that iterate all keys not have to check for the sentinel. key->deref(); key = deletedSentinel(); entries[i].key = key; entries[i].value = 0; entries[i].attributes = DontEnum; assert(_table->keyCount >= 1); --_table->keyCount; ++_table->sentinelCount; if (_table->sentinelCount * 4 >= _table->size) rehash(); checkConsistency(); }
void PropertyMap::put(const Identifier &name, JSValue *value, int attributes, bool roCheck) { assert(!name.isNull()); assert(value != 0); checkConsistency(); UString::Rep *rep = name._ustring.rep(); #if DEBUG_PROPERTIES printf("adding property %s, attributes = 0x%08x (", name.ascii(), attributes); printAttributes(attributes); printf(")\n"); #endif #if USE_SINGLE_ENTRY if (!_table) { UString::Rep *key = _singleEntry.key; if (key) { if (rep == key && !(roCheck && (_singleEntry.attributes & ReadOnly))) { _singleEntry.value = value; return; } } else { rep->ref(); _singleEntry.key = rep; _singleEntry.value = value; _singleEntry.attributes = static_cast<short>(attributes); checkConsistency(); return; } } #endif if (!_table || _table->keyCount * 2 >= _table->size) expand(); unsigned h = rep->hash(); int sizeMask = _table->sizeMask; Entry *entries = _table->entries; int i = h & sizeMask; int k = 0; bool foundDeletedElement = false; int deletedElementIndex = 0; /* initialize to make the compiler happy */ #if DUMP_STATISTICS ++numProbes; numCollisions += entries[i].key && entries[i].key != rep; #endif while (UString::Rep *key = entries[i].key) { if (rep == key) { if (roCheck && (_table->entries[i].attributes & ReadOnly)) return; // Put a new value in an existing hash table entry. entries[i].value = value; // Attributes are intentionally not updated. return; } // If we find the deleted-element sentinel, remember it for use later. if (key == deletedSentinel() && !foundDeletedElement) { foundDeletedElement = true; deletedElementIndex = i; } if (k == 0) k = 1 | (h % sizeMask); i = (i + k) & sizeMask; #if DUMP_STATISTICS ++numRehashes; #endif } // Use either the deleted element or the 0 at the end of the chain. if (foundDeletedElement) { i = deletedElementIndex; --_table->sentinelCount; } // Create a new hash table entry. rep->ref(); entries[i].key = rep; entries[i].value = value; entries[i].attributes = static_cast<short>(attributes); entries[i].index = ++_table->lastIndexUsed; ++_table->keyCount; checkConsistency(); }
void InternalFunction::finishCreation(JSGlobalData& globalData, const Identifier& name) { Base::finishCreation(globalData); ASSERT(inherits(&s_info)); putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); }
void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const Identifier& name) { Base::finishCreation(exec->globalData()); ASSERT(inherits(&s_info)); m_executable.set(exec->globalData(), this, executable); putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); }
String::String(const Identifier& str) { if (str.isNull()) return; m_impl = StringImpl::create(str.ustring()); }
void MidiControllerAutomationHandler::restoreFromValueTree(const ValueTree &v) { if (v.getType() != Identifier("MidiAutomation")) return; clear(); for (int i = 0; i < v.getNumChildren(); i++) { ValueTree cc = v.getChild(i); int controller = cc.getProperty("Controller", 1); auto& aArray = automationData[controller]; AutomationData a; a.ccNumber = controller; a.processor = ProcessorHelpers::getFirstProcessorWithName(mc->getMainSynthChain(), cc.getProperty("Processor")); a.macroIndex = cc.getProperty("MacroIndex"); auto attributeString = cc.getProperty("Attribute", a.attribute).toString(); const bool isParameterId = attributeString.containsAnyOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); // The parameter was stored correctly as ID if (isParameterId && a.processor.get() != nullptr) { const Identifier pId(attributeString); for (int j = 0; j < a.processor->getNumParameters(); j++) { if (a.processor->getIdentifierForParameterIndex(j) == pId) { a.attribute = j; break; } } } else { // This tries to obtain the correct id. auto presetVersion = v.getRoot().getProperty("Version").toString(); const Identifier pId = UserPresetHelpers::getAutomationIndexFromOldVersion(presetVersion, attributeString.getIntValue()); if (pId.isNull()) { a.attribute = attributeString.getIntValue(); } else { for (int j = 0; j < a.processor->getNumParameters(); j++) { if (a.processor->getIdentifierForParameterIndex(j) == pId) { a.attribute = j; break; } } } } double start = cc.getProperty("Start"); double end = cc.getProperty("End"); double skew = cc.getProperty("Skew", a.parameterRange.skew); double interval = cc.getProperty("Interval", a.parameterRange.interval); auto fullStart = cc.getProperty("FullStart", start); auto fullEnd = cc.getProperty("FullEnd", end); a.parameterRange = NormalisableRange<double>(start, end, interval, skew); a.fullRange = NormalisableRange<double>(fullStart, fullEnd, interval, skew); a.used = true; a.inverted = cc.getProperty("Inverted", false); aArray.addIfNotAlreadyThere(a); } sendChangeMessage(); refreshAnyUsedState(); }