void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
{
    JSValue* object = getDirect(propertyName);
    if (object && object->isGetterSetter()) {
        ASSERT(m_structureID->hasGetterSetterProperties());
        asGetterSetter(object)->setSetter(setterFunction);
        return;
    }

    PutPropertySlot slot;
    GetterSetter* getterSetter = new (exec) GetterSetter;
    putDirect(propertyName, getterSetter, None, true, slot);

    // putDirect will change our StructureID if we add a new property. For
    // getters and setters, though, we also need to change our StructureID
    // if we override an existing non-getter or non-setter.
    if (slot.type() != PutPropertySlot::NewProperty) {
        if (!m_structureID->isDictionary()) {
            RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID);
            setStructureID(structureID.release());
        }
    }

    m_structureID->setHasGetterSetterProperties(true);
    getterSetter->setSetter(setterFunction);
}
예제 #2
0
void JSObject::removeDirect(const Identifier& propertyName)
{
    if (m_structureID->isDictionary()) {
        m_structureID->propertyMap().remove(propertyName, m_propertyStorage);
        return;
    }

    RefPtr<StructureID> structureID = StructureID::toDictionaryTransition(m_structureID);
    structureID->propertyMap().remove(propertyName, m_propertyStorage);
    setStructureID(structureID.release());
}
void JSObject::removeDirect(const Identifier& propertyName)
{
    size_t offset;
    if (m_structureID->isDictionary()) {
        offset = m_structureID->removePropertyWithoutTransition(propertyName);
        if (offset != WTF::notFound)
            m_propertyStorage[offset] = jsUndefined();
        return;
    }

    RefPtr<StructureID> structureID = StructureID::removePropertyTransition(m_structureID, propertyName, offset);
    if (offset != WTF::notFound)
        m_propertyStorage[offset] = jsUndefined();
    setStructureID(structureID.release());
}