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; } }
EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value) { JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); GetterSetter* getterSetter = asGetterSetter(value); JSObject* getter = getterSetter->getter(); if (!getter) return JSValue::encode(jsUndefined()); CallData callData; CallType callType = getter->methodTable()->getCallData(getter, callData); return JSValue::encode(call(exec, getter, callType, callData, asObject(base), ArgList())); }
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 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 objectProtoFuncLookupGetter(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->isGetterNull() ? JSValue::encode(jsUndefined()) : JSValue::encode(getterSetter->getter()); } return JSValue::encode(jsUndefined()); }