void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) { JSValuePtr object = getDirect(propertyName); if (object && object->isGetterSetter()) { ASSERT(m_structure->hasGetterSetterProperties()); asGetterSetter(object)->setSetter(setterFunction); return; } PutPropertySlot slot; GetterSetter* getterSetter = new (exec) GetterSetter; putDirect(propertyName, getterSetter, None, true, slot); // putDirect will change our Structure if we add a new property. For // getters and setters, though, we also need to change our Structure // if we override an existing non-getter or non-setter. if (slot.type() != PutPropertySlot::NewProperty) { if (!m_structure->isDictionary()) { RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure); setStructure(structure.release()); } } m_structure->setHasGetterSetterProperties(true); getterSetter->setSetter(setterFunction); }
static ALWAYS_INLINE JSValuePtr callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName) { JSValuePtr function = object->get(exec, propertyName); CallData callData; CallType callType = function->getCallData(callData); if (callType == CallTypeNone) return exec->exception(); // Prevent "toString" and "valueOf" from observing execution if an exception // is pending. if (exec->hadException()) return exec->exception(); JSValuePtr result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList()); ASSERT(!result->isGetterSetter()); if (exec->hadException()) return exec->exception(); if (result->isObject()) return noValue(); return result; }