void TiObject::defineSetter(TiExcState* exec, const Identifier& propertyName, TiObject* setterFunction, unsigned attributes) { TiValue object = getDirect(propertyName); if (object && object.isGetterSetter()) { ASSERT(m_structure->hasGetterSetterProperties()); asGetterSetter(object)->setSetter(setterFunction); return; } PutPropertySlot slot; GetterSetter* getterSetter = new (exec) GetterSetter(exec); putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Setter, 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 TiValue callDefaultValueFunction(TiExcState* exec, const TiObject* object, const Identifier& propertyName) { TiValue 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(); TiValue result = call(exec, function, callType, callData, const_cast<TiObject*>(object), exec->emptyList()); ASSERT(!result.isGetterSetter()); if (exec->hadException()) return exec->exception(); if (result.isObject()) return TiValue(); return result; }