summaryrefslogtreecommitdiff
path: root/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp699
1 files changed, 0 insertions, 699 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
deleted file mode 100644
index 0e3475f..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Eric Seidel (eric@webkit.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "JSObject.h"
-
-#include "DatePrototype.h"
-#include "ErrorConstructor.h"
-#include "GetterSetter.h"
-#include "JSGlobalObject.h"
-#include "NativeErrorConstructor.h"
-#include "ObjectPrototype.h"
-#include "PropertyDescriptor.h"
-#include "PropertyNameArray.h"
-#include "Lookup.h"
-#include "Nodes.h"
-#include "Operations.h"
-#include <math.h>
-#include <wtf/Assertions.h>
-
-namespace JSC {
-
-ASSERT_CLASS_FITS_IN_CELL(JSObject);
-
-static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
- // Add properties from the static hashtables of properties
- for (; classInfo; classInfo = classInfo->parentClass) {
- const HashTable* table = classInfo->propHashTable(exec);
- if (!table)
- continue;
- table->initializeIfNeeded(exec);
- ASSERT(table->table);
-
- int hashSizeMask = table->compactSize - 1;
- const HashEntry* entry = table->table;
- for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
- if (entry->key() && (!(entry->attributes() & DontEnum) || (mode == IncludeDontEnumProperties)))
- propertyNames.add(entry->key());
- }
- }
-}
-
-void JSObject::markChildren(MarkStack& markStack)
-{
-#ifndef NDEBUG
- bool wasCheckingForDefaultMarkViolation = markStack.m_isCheckingForDefaultMarkViolation;
- markStack.m_isCheckingForDefaultMarkViolation = false;
-#endif
-
- markChildrenDirect(markStack);
-
-#ifndef NDEBUG
- markStack.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation;
-#endif
-}
-
-UString JSObject::className() const
-{
- const ClassInfo* info = classInfo();
- if (info)
- return info->className;
- return "Object";
-}
-
-bool JSObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
-{
- return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
-}
-
-static void throwSetterError(ExecState* exec)
-{
- throwError(exec, TypeError, "setting a property that has only a getter");
-}
-
-// ECMA 8.6.2.2
-void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
-{
- ASSERT(value);
- ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
-
- if (propertyName == exec->propertyNames().underscoreProto) {
- // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
- if (!value.isObject() && !value.isNull())
- return;
-
- JSValue nextPrototypeValue = value;
- while (nextPrototypeValue && nextPrototypeValue.isObject()) {
- JSObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject();
- if (nextPrototype == this) {
- throwError(exec, GeneralError, "cyclic __proto__ value");
- return;
- }
- nextPrototypeValue = nextPrototype->prototype();
- }
-
- setPrototype(value);
- return;
- }
-
- // Check if there are any setters or getters in the prototype chain
- JSValue prototype;
- for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
- prototype = obj->prototype();
- if (prototype.isNull()) {
- putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
- return;
- }
- }
-
- unsigned attributes;
- JSCell* specificValue;
- if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly)
- return;
-
- for (JSObject* obj = this; ; obj = asObject(prototype)) {
-#ifdef QT_BUILD_SCRIPT_LIB
- PropertyDescriptor descriptor;
- if (obj->getPropertyDescriptor(exec, propertyName, descriptor)) {
- JSObject* setterFunc;
- if ((descriptor.isAccessorDescriptor() && ((setterFunc = asObject(descriptor.setter())), true))
- || (descriptor.value().isGetterSetter() && ((setterFunc = asGetterSetter(descriptor.value())->setter()), true))) {
-#else
- if (JSValue gs = obj->getDirect(propertyName)) {
- if (gs.isGetterSetter()) {
- JSObject* setterFunc = asGetterSetter(gs)->setter();
-#endif
- if (!setterFunc) {
- throwSetterError(exec);
- return;
- }
-
- CallData callData;
- CallType callType = setterFunc->getCallData(callData);
- MarkedArgumentBuffer args;
- args.append(value);
- call(exec, setterFunc, callType, callData, this, args);
- return;
- }
-
- // If there's an existing property on the object or one of its
- // prototypes it should be replaced, so break here.
- break;
- }
-
- prototype = obj->prototype();
- if (prototype.isNull())
- break;
- }
-
- putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
- return;
-}
-
-void JSObject::put(ExecState* exec, unsigned propertyName, JSValue value)
-{
- PutPropertySlot slot;
- put(exec, Identifier::from(exec, propertyName), value, slot);
-}
-
-void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
-{
- putDirectInternal(exec->globalData(), propertyName, value, attributes, checkReadOnly, slot);
-}
-
-void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
-{
- putDirectInternal(exec->globalData(), propertyName, value, attributes);
-}
-
-void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValue value, unsigned attributes)
-{
- putWithAttributes(exec, Identifier::from(exec, propertyName), value, attributes);
-}
-
-bool JSObject::hasProperty(ExecState* exec, const Identifier& propertyName) const
-{
- PropertySlot slot;
- return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot);
-}
-
-bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const
-{
- PropertySlot slot;
- return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot);
-}
-
-// ECMA 8.6.2.5
-bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
-{
- unsigned attributes;
- JSCell* specificValue;
- if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) {
- if ((attributes & DontDelete))
- return false;
- removeDirect(propertyName);
- return true;
- }
-
- // Look in the static hashtable of properties
- const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
- if (entry && entry->attributes() & DontDelete)
- return false; // this builtin property can't be deleted
-
- // FIXME: Should the code here actually do some deletion?
- return true;
-}
-
-bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const
-{
- PropertySlot slot;
- return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot);
-}
-
-bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName)
-{
- return deleteProperty(exec, Identifier::from(exec, propertyName));
-}
-
-static ALWAYS_INLINE JSValue callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
-{
- JSValue 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();
-
- JSValue 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 JSValue();
- return result;
-}
-
-bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result)
-{
- result = defaultValue(exec, PreferNumber);
- number = result.toNumber(exec);
- return !result.isString();
-}
-
-// ECMA 8.6.2.6
-JSValue JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
-{
- // Must call toString first for Date objects.
- if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) {
- JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
- if (value)
- return value;
- value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
- if (value)
- return value;
- } else {
- JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
- if (value)
- return value;
- value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
- if (value)
- return value;
- }
-
- ASSERT(!exec->hadException());
-
- return throwError(exec, TypeError, "No default value");
-}
-
-const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifier& propertyName) const
-{
- for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
- if (const HashTable* propHashTable = info->propHashTable(exec)) {
- if (const HashEntry* entry = propHashTable->entry(exec, propertyName))
- return entry;
- }
- }
- return 0;
-}
-
-void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
-{
- JSValue object = getDirect(propertyName);
- if (object && object.isGetterSetter()) {
- ASSERT(m_structure->hasGetterSetterProperties());
- asGetterSetter(object)->setGetter(getterFunction);
- return;
- }
-
- PutPropertySlot slot;
- GetterSetter* getterSetter = new (exec) GetterSetter(exec);
- putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Getter, 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->setGetter(getterFunction);
-}
-
-void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes)
-{
- JSValue 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);
-}
-
-JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
-{
- JSObject* object = this;
- while (true) {
- if (JSValue value = object->getDirect(propertyName)) {
- if (!value.isGetterSetter())
- return jsUndefined();
- JSObject* functionObject = asGetterSetter(value)->getter();
- if (!functionObject)
- return jsUndefined();
- return functionObject;
- }
-
- if (!object->prototype() || !object->prototype().isObject())
- return jsUndefined();
- object = asObject(object->prototype());
- }
-}
-
-JSValue JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
-{
- JSObject* object = this;
- while (true) {
- if (JSValue value = object->getDirect(propertyName)) {
- if (!value.isGetterSetter())
- return jsUndefined();
- JSObject* functionObject = asGetterSetter(value)->setter();
- if (!functionObject)
- return jsUndefined();
- return functionObject;
- }
-
- if (!object->prototype() || !object->prototype().isObject())
- return jsUndefined();
- object = asObject(object->prototype());
- }
-}
-
-bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue proto)
-{
- if (!value.isObject())
- return false;
-
- if (!proto.isObject()) {
- throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
- return false;
- }
-
- JSObject* object = asObject(value);
- while ((object = object->prototype().getObject())) {
- if (proto == object)
- return true;
- }
- return false;
-}
-
-bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyName) const
-{
- PropertyDescriptor descriptor;
- if (!const_cast<JSObject*>(this)->getOwnPropertyDescriptor(exec, propertyName, descriptor))
- return false;
- return descriptor.enumerable();
-}
-
-bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyName, JSCell*& specificValue) const
-{
- unsigned attributes;
- if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound)
- return true;
-
- // This could be a function within the static table? - should probably
- // also look in the hash? This currently should not be a problem, since
- // we've currently always call 'get' first, which should have populated
- // the normal storage.
- return false;
-}
-
-void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
- getOwnPropertyNames(exec, propertyNames, mode);
-
- if (prototype().isNull())
- return;
-
- JSObject* prototype = asObject(this->prototype());
- while(1) {
- if (prototype->structure()->typeInfo().overridesGetPropertyNames()) {
- prototype->getPropertyNames(exec, propertyNames, mode);
- break;
- }
- prototype->getOwnPropertyNames(exec, propertyNames, mode);
- JSValue nextProto = prototype->prototype();
- if (nextProto.isNull())
- break;
- prototype = asObject(nextProto);
- }
-}
-
-void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
- m_structure->getPropertyNames(propertyNames, mode);
- getClassPropertyNames(exec, classInfo(), propertyNames, mode);
-}
-
-bool JSObject::toBoolean(ExecState*) const
-{
- return true;
-}
-
-double JSObject::toNumber(ExecState* exec) const
-{
- JSValue primitive = toPrimitive(exec, PreferNumber);
- if (exec->hadException()) // should be picked up soon in Nodes.cpp
- return 0.0;
- return primitive.toNumber(exec);
-}
-
-UString JSObject::toString(ExecState* exec) const
-{
- JSValue primitive = toPrimitive(exec, PreferString);
- if (exec->hadException())
- return "";
- return primitive.toString(exec);
-}
-
-JSObject* JSObject::toObject(ExecState*) const
-{
- return const_cast<JSObject*>(this);
-}
-
-JSObject* JSObject::toThisObject(ExecState*) const
-{
- return const_cast<JSObject*>(this);
-}
-
-JSObject* JSObject::unwrappedObject()
-{
- return this;
-}
-
-void JSObject::removeDirect(const Identifier& propertyName)
-{
- size_t offset;
- if (m_structure->isUncacheableDictionary()) {
- offset = m_structure->removePropertyWithoutTransition(propertyName);
- if (offset != WTF::notFound)
- putDirectOffset(offset, jsUndefined());
- return;
- }
-
- RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset);
- setStructure(structure.release());
- if (offset != WTF::notFound)
- putDirectOffset(offset, jsUndefined());
-}
-
-void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
-{
- putDirectFunction(Identifier(exec, function->name(exec)), function, attr);
-}
-
-void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
-{
- putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr);
-}
-
-NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
-{
- if (JSObject* getterFunction = asGetterSetter(*location)->getter())
- slot.setGetterSlot(getterFunction);
- else
- slot.setUndefined();
-}
-
-Structure* JSObject::createInheritorID()
-{
-#ifdef QT_BUILD_SCRIPT_LIB
- // ### QtScript needs the hasOwnProperty() calls etc. for QScriptObject
- m_inheritorID = Structure::create(this, TypeInfo(ObjectType, ImplementsHasInstance | JSC::OverridesHasInstance | JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames));
-#else
- m_inheritorID = JSObject::createStructure(this);
-#endif
- return m_inheritorID.get();
-}
-
-void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
-{
- allocatePropertyStorageInline(oldSize, newSize);
-}
-
-bool JSObject::getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor& descriptor)
-{
- unsigned attributes = 0;
- JSCell* cell = 0;
- size_t offset = m_structure->get(propertyName, attributes, cell);
- if (offset == WTF::notFound)
- return false;
- descriptor.setDescriptor(getDirectOffset(offset), attributes);
- return true;
-}
-
-bool JSObject::getPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
-{
- JSObject* object = this;
- while (true) {
- if (object->getOwnPropertyDescriptor(exec, propertyName, descriptor))
- return true;
- JSValue prototype = object->prototype();
- if (!prototype.isObject())
- return false;
- object = asObject(prototype);
- }
-}
-
-static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& propertyName, PropertyDescriptor& descriptor, unsigned attributes, JSValue oldValue)
-{
- if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) {
- target->putWithAttributes(exec, propertyName, descriptor.value() ? descriptor.value() : oldValue, attributes & ~(Getter | Setter));
- return true;
- }
- attributes &= ~ReadOnly;
- if (descriptor.getter() && descriptor.getter().isObject())
- target->defineGetter(exec, propertyName, asObject(descriptor.getter()), attributes);
- if (exec->hadException())
- return false;
- if (descriptor.setter() && descriptor.setter().isObject())
- target->defineSetter(exec, propertyName, asObject(descriptor.setter()), attributes);
- return !exec->hadException();
-}
-
-bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
-{
- // If we have a new property we can just put it on normally
- PropertyDescriptor current;
- if (!getOwnPropertyDescriptor(exec, propertyName, current))
- return putDescriptor(exec, this, propertyName, descriptor, descriptor.attributes(), jsUndefined());
-
- if (descriptor.isEmpty())
- return true;
-
- if (current.equalTo(exec, descriptor))
- return true;
-
- // Filter out invalid changes
- if (!current.configurable()) {
- if (descriptor.configurable()) {
- if (throwException)
- throwError(exec, TypeError, "Attempting to configurable attribute of unconfigurable property.");
- return false;
- }
- if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) {
- if (throwException)
- throwError(exec, TypeError, "Attempting to change enumerable attribute of unconfigurable property.");
- return false;
- }
- }
-
- // A generic descriptor is simply changing the attributes of an existing property
- if (descriptor.isGenericDescriptor()) {
- if (!current.attributesEqual(descriptor)) {
- deleteProperty(exec, propertyName);
- putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value());
- }
- return true;
- }
-
- // Changing between a normal property or an accessor property
- if (descriptor.isDataDescriptor() != current.isDataDescriptor()) {
- if (!current.configurable()) {
- if (throwException)
- throwError(exec, TypeError, "Attempting to change access mechanism for an unconfigurable property.");
- return false;
- }
- deleteProperty(exec, propertyName);
- return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value() ? current.value() : jsUndefined());
- }
-
- // Changing the value and attributes of an existing property
- if (descriptor.isDataDescriptor()) {
- if (!current.configurable()) {
- if (!current.writable() && descriptor.writable()) {
- if (throwException)
- throwError(exec, TypeError, "Attempting to change writable attribute of unconfigurable property.");
- return false;
- }
- if (!current.writable()) {
- if (descriptor.value() || !JSValue::strictEqual(exec, current.value(), descriptor.value())) {
- if (throwException)
- throwError(exec, TypeError, "Attempting to change value of a readonly property.");
- return false;
- }
- }
- } else if (current.attributesEqual(descriptor)) {
- if (!descriptor.value())
- return true;
- PutPropertySlot slot;
- put(exec, propertyName, descriptor.value(), slot);
- if (exec->hadException())
- return false;
- return true;
- }
- deleteProperty(exec, propertyName);
- return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value());
- }
-
- // Changing the accessor functions of an existing accessor property
- ASSERT(descriptor.isAccessorDescriptor());
- if (!current.configurable()) {
- if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
- if (throwException)
- throwError(exec, TypeError, "Attempting to change the setter of an unconfigurable property.");
- return false;
- }
- if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
- if (throwException)
- throwError(exec, TypeError, "Attempting to change the getter of an unconfigurable property.");
- return false;
- }
- }
- JSValue accessor = getDirect(propertyName);
- if (!accessor)
- return false;
- GetterSetter* getterSetter = asGetterSetter(accessor);
- if (current.attributesEqual(descriptor)) {
- if (descriptor.setter())
- getterSetter->setSetter(asObject(descriptor.setter()));
- if (descriptor.getter())
- getterSetter->setGetter(asObject(descriptor.getter()));
- return true;
- }
- deleteProperty(exec, propertyName);
- unsigned attrs = current.attributesWithOverride(descriptor);
- if (descriptor.setter())
- attrs |= Setter;
- if (descriptor.getter())
- attrs |= Getter;
- putDirect(propertyName, getterSetter, attrs);
- return true;
-}
-
-} // namespace JSC