void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes) { ASSERT(value); ASSERT(value.isGetterSetter() == !!(attributes & Accessor)); m_attributes = attributes; if (value.isGetterSetter()) { m_attributes &= ~ReadOnly; // FIXME: we should be able to ASSERT this! GetterSetter* accessor = asGetterSetter(value); m_getter = accessor->getter() ? accessor->getter() : jsUndefined(); m_setter = accessor->setter() ? accessor->setter() : jsUndefined(); m_seenAttributes = EnumerablePresent | ConfigurablePresent; } else { m_value = value; m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent; } }
void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes) { ASSERT(value); m_attributes = attributes; if (attributes & (Getter | Setter)) { GetterSetter* accessor = asGetterSetter(value); m_getter = accessor->getter(); m_setter = accessor->setter(); ASSERT(m_getter || m_setter); m_seenAttributes = EnumerablePresent | ConfigurablePresent; m_attributes &= ~ReadOnly; } else { m_value = value; m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent; } }
void callSetter(ExecState* exec, JSValue base, JSValue getterSetter, JSValue value, ECMAMode ecmaMode) { GetterSetter* getterSetterObj = jsCast<GetterSetter*>(getterSetter); if (getterSetterObj->isSetterNull()) { if (ecmaMode == StrictMode) throwTypeError(exec, StrictModeReadonlyPropertyWriteError); return; } JSObject* setter = getterSetterObj->setter(); MarkedArgumentBuffer args; args.append(value); CallData callData; CallType callType = setter->methodTable(exec->vm())->getCallData(setter, callData); call(exec, setter, callType, callData, base, args); }
void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes) { ASSERT(value); // We need to mask off the PropertyAttribute::CustomValue bit because // PropertyDescriptor::attributesEqual() does an equivalent test on // m_attributes, and a property that has a CustomValue should be indistinguishable // from a property that has a normal value as far as JS code is concerned. // PropertyAttribute does not need knowledge of the underlying implementation // actually being a CustomValue. So, we'll just mask it off up front here. m_attributes = attributes & ~PropertyAttribute::CustomValue; if (value.isGetterSetter()) { m_attributes &= ~PropertyAttribute::ReadOnly; // FIXME: we should be able to ASSERT this! GetterSetter* accessor = jsCast<GetterSetter*>(value); m_getter = !accessor->isGetterNull() ? accessor->getter() : jsUndefined(); m_setter = !accessor->isSetterNull() ? accessor->setter() : jsUndefined(); m_seenAttributes = EnumerablePresent | ConfigurablePresent; } else { m_value = value; m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent; } }
EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec) { JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); auto propertyName = exec->argument(0).toPropertyKey(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); PropertySlot slot(thisObject); if (thisObject->getPropertySlot(exec, propertyName, slot) && slot.isAccessor()) { GetterSetter* getterSetter = slot.getterSetter(); return getterSetter->isSetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->setter()); } return JSValue::encode(jsUndefined()); }