18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2001 Peter Kelly (pmk@post.com) 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Eric Seidel (eric@webkit.org) 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSObject.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DatePrototype.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ErrorConstructor.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GetterSetter.h" 30e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "JSFunction.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSGlobalObject.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NativeErrorConstructor.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ObjectPrototype.h" 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "PropertyDescriptor.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PropertyNameArray.h" 36635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Lookup.h" 37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Nodes.h" 38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Operations.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h> 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h> 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectASSERT_CLASS_FITS_IN_CELL(JSObject); 4581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject); 462bde8e466a4451c7319e3a072d118917957d6554Steve BlockASSERT_CLASS_FITS_IN_CELL(JSFinalObject); 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochconst char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property."; 49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochconst ClassInfo JSObject::s_info = { "Object", 0, 0, 0 }; 5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 52d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode) 53cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 54cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Add properties from the static hashtables of properties 55cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block for (; classInfo; classInfo = classInfo->parentClass) { 56cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block const HashTable* table = classInfo->propHashTable(exec); 57cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!table) 58cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block continue; 59cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block table->initializeIfNeeded(exec); 60cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ASSERT(table->table); 61cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 62cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int hashSizeMask = table->compactSize - 1; 63cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block const HashEntry* entry = table->table; 64cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block for (int i = 0; i <= hashSizeMask; ++i, ++entry) { 65d0825bca7fe65beaee391d30da42e937db621564Steve Block if (entry->key() && (!(entry->attributes() & DontEnum) || (mode == IncludeDontEnumProperties))) 66cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block propertyNames.add(entry->key()); 67cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 68cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 69cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 70cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid JSObject::markChildren(MarkStack& markStack) 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifndef NDEBUG 74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool wasCheckingForDefaultMarkViolation = markStack.m_isCheckingForDefaultMarkViolation; 75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block markStack.m_isCheckingForDefaultMarkViolation = false; 76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 77058ccc7ba0a4d59b9f6e92808332aa9895425fc7Andrei Popescu 78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block markChildrenDirect(markStack); 79058ccc7ba0a4d59b9f6e92808332aa9895425fc7Andrei Popescu 80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifndef NDEBUG 81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block markStack.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation; 82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString JSObject::className() const 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const ClassInfo* info = classInfo(); 8881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(info); 8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return info->className; 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void throwSetterError(ExecState* exec) 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 99545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "setting a property that has only a getter")); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ECMA 8.6.2.2 1035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(value); 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (propertyName == exec->propertyNames().underscoreProto) { 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla. 110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!value.isObject() && !value.isNull()) 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!setPrototypeWithCycleCheck(exec->globalData(), value)) 113545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createError(exec, "cyclic __proto__ value")); 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check if there are any setters or getters in the prototype chain 1185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue prototype; 119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) { 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project prototype = obj->prototype(); 121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (prototype.isNull()) { 122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode()) 123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned attributes; 1295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSCell* specificValue; 1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if ((m_structure->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) { 131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (slot.isStrictMode()) 132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (JSObject* obj = this; ; obj = asObject(prototype)) { 1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (JSValue gs = obj->getDirect(exec->globalData(), propertyName)) { 138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (gs.isGetterSetter()) { 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* setterFunc = asGetterSetter(gs)->setter(); 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!setterFunc) { 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project throwSetterError(exec); 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallData callData; 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallType callType = setterFunc->getCallData(callData); 1475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian MarkedArgumentBuffer args; 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project args.append(value); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project call(exec, setterFunc, callType, callData, this, args); 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If there's an existing property on the object or one of its 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // prototypes it should be replaced, so break here. 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project prototype = obj->prototype(); 159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (prototype.isNull()) 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode()) 164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch throwTypeError(exec, StrictModeReadonlyPropertyWriteError); 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSObject::put(ExecState* exec, unsigned propertyName, JSValue value) 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PutPropertySlot slot; 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project put(exec, Identifier::from(exec, propertyName), value, slot); 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 174545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid JSObject::putWithAttributes(JSGlobalData* globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 175545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 176545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch putDirectInternal(*globalData, propertyName, value, attributes, checkReadOnly, slot); 177545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 178545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 179545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid JSObject::putWithAttributes(JSGlobalData* globalData, const Identifier& propertyName, JSValue value, unsigned attributes) 180545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 181545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch putDirectInternal(*globalData, propertyName, value, attributes); 182545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 183545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 184545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid JSObject::putWithAttributes(JSGlobalData* globalData, unsigned propertyName, JSValue value, unsigned attributes) 185545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{ 186545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch putWithAttributes(globalData, Identifier::from(globalData, propertyName), value, attributes); 187545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch} 188545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 1895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian putDirectInternal(exec->globalData(), propertyName, value, attributes, checkReadOnly, slot); 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) 1955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 1965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian putDirectInternal(exec->globalData(), propertyName, value, attributes); 1975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 1985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValue value, unsigned attributes) 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project putWithAttributes(exec, Identifier::from(exec, propertyName), value, attributes); 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::hasProperty(ExecState* exec, const Identifier& propertyName) const 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot; 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot); 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot; 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot); 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ECMA 8.6.2.5 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName) 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned attributes; 2205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSCell* specificValue; 2212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_structure->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound) { 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((attributes & DontDelete)) 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 2242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch removeDirect(exec->globalData(), propertyName); 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Look in the static hashtable of properties 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const HashEntry* entry = findPropertyHashEntry(exec, propertyName); 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (entry && entry->attributes() & DontDelete) 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; // this builtin property can't be deleted 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Should the code here actually do some deletion? 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot; 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot); 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::deleteProperty(ExecState* exec, unsigned propertyName) 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return deleteProperty(exec, Identifier::from(exec, propertyName)); 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic ALWAYS_INLINE JSValue callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue function = object->get(exec, propertyName); 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallData callData; 252545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch CallType callType = getCallData(function, callData); 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callType == CallTypeNone) 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return exec->exception(); 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Prevent "toString" and "valueOf" from observing execution if an exception 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // is pending. 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (exec->hadException()) 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return exec->exception(); 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList()); 262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!result.isGetterSetter()); 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (exec->hadException()) 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return exec->exception(); 265635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (result.isObject()) 2665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return JSValue(); 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = defaultValue(exec, PreferNumber); 273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project number = result.toNumber(exec); 274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return !result.isString(); 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ECMA 8.6.2.6 2785f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Must call toString first for Date objects. 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) { 2825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().toString); 283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (value) 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf); 286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (value) 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 2895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf); 290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (value) 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project value = callDefaultValueFunction(exec, this, exec->propertyNames().toString); 293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (value) 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!exec->hadException()); 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 299545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return throwError(exec, createTypeError(exec, "No default value")); 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifier& propertyName) const 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (const ClassInfo* info = classInfo(); info; info = info->parentClass) { 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (const HashTable* propHashTable = info->propHashTable(exec)) { 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (const HashEntry* entry = propHashTable->entry(exec, propertyName)) 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return entry; 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch JSValue object = getDirect(exec->globalData(), propertyName); 316635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (object && object.isGetterSetter()) { 317635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_structure->hasGetterSetterProperties()); 3182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block asGetterSetter(object)->setGetter(exec->globalData(), getterFunction); 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch JSGlobalData& globalData = exec->globalData(); 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PutPropertySlot slot; 3240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch GetterSetter* getterSetter = new (exec) GetterSetter(exec); 3252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch putDirectInternal(globalData, propertyName, getterSetter, attributes | Getter, true, slot); 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 327635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // putDirect will change our Structure if we add a new property. For 328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // getters and setters, though, we also need to change our Structure 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if we override an existing non-getter or non-setter. 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (slot.type() != PutPropertySlot::NewProperty) { 3312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_structure->isDictionary()) 3322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setStructure(exec->globalData(), Structure::getterSetterTransition(globalData, m_structure.get())); 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 335635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_structure->setHasGetterSetterProperties(true); 3362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch getterSetter->setGetter(globalData, getterFunction); 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch JSValue object = getDirect(exec->globalData(), propertyName); 342635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (object && object.isGetterSetter()) { 343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_structure->hasGetterSetterProperties()); 3442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block asGetterSetter(object)->setSetter(exec->globalData(), setterFunction); 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PutPropertySlot slot; 3490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch GetterSetter* getterSetter = new (exec) GetterSetter(exec); 350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Setter, true, slot); 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // putDirect will change our Structure if we add a new property. For 353635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // getters and setters, though, we also need to change our Structure 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if we override an existing non-getter or non-setter. 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (slot.type() != PutPropertySlot::NewProperty) { 3562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_structure->isDictionary()) 3572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setStructure(exec->globalData(), Structure::getterSetterTransition(exec->globalData(), m_structure.get())); 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_structure->setHasGetterSetterProperties(true); 3612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block getterSetter->setSetter(exec->globalData(), setterFunction); 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochJSValue JSObject::lookupGetter(ExecState* exec, const Identifier& propertyName) 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* object = this; 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 3682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (JSValue value = object->getDirect(exec->globalData(), propertyName)) { 369635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!value.isGetterSetter()) 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* functionObject = asGetterSetter(value)->getter(); 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!functionObject) 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return functionObject; 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 377635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!object->prototype() || !object->prototype().isObject()) 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object = asObject(object->prototype()); 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochJSValue JSObject::lookupSetter(ExecState* exec, const Identifier& propertyName) 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* object = this; 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 3872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (JSValue value = object->getDirect(exec->globalData(), propertyName)) { 388635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!value.isGetterSetter()) 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* functionObject = asGetterSetter(value)->setter(); 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!functionObject) 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return functionObject; 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!object->prototype() || !object->prototype().isObject()) 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object = asObject(object->prototype()); 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue proto) 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!value.isObject()) 4055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 4065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 407635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!proto.isObject()) { 408545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "instanceof called on an object with an invalid prototype property.")); 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* object = asObject(value); 413635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while ((object = object->prototype().getObject())) { 414635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (proto == object) 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyName) const 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 422643ca7872b450ea4efacab6188849e5aac2ba161Steve Block PropertyDescriptor descriptor; 423643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!const_cast<JSObject*>(this)->getOwnPropertyDescriptor(exec, propertyName, descriptor)) 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 425643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return descriptor.enumerable(); 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool JSObject::getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificValue) const 4295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 4305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned attributes; 4312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_structure->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound) 4325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 4335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // This could be a function within the static table? - should probably 4355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // also look in the hash? This currently should not be a problem, since 4365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // we've currently always call 'get' first, which should have populated 4375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // the normal storage. 4385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 4395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 4405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 441d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 443d0825bca7fe65beaee391d30da42e937db621564Steve Block getOwnPropertyNames(exec, propertyNames, mode); 444cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 445cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (prototype().isNull()) 446cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 447cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 448cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSObject* prototype = asObject(this->prototype()); 449cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block while(1) { 450cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (prototype->structure()->typeInfo().overridesGetPropertyNames()) { 451d0825bca7fe65beaee391d30da42e937db621564Steve Block prototype->getPropertyNames(exec, propertyNames, mode); 452cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block break; 453cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 454d0825bca7fe65beaee391d30da42e937db621564Steve Block prototype->getOwnPropertyNames(exec, propertyNames, mode); 455cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue nextProto = prototype->prototype(); 456cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (nextProto.isNull()) 457cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block break; 458cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block prototype = asObject(nextProto); 459cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 462d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 463231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_structure->getPropertyNames(exec->globalData(), propertyNames, mode); 465d0825bca7fe65beaee391d30da42e937db621564Steve Block getClassPropertyNames(exec, classInfo(), propertyNames, mode); 466231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 467231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSObject::toBoolean(ExecState*) const 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble JSObject::toNumber(ExecState* exec) const 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue primitive = toPrimitive(exec, PreferNumber); 476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (exec->hadException()) // should be picked up soon in Nodes.cpp 4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0.0; 478635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return primitive.toNumber(exec); 4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString JSObject::toString(ExecState* exec) const 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue primitive = toPrimitive(exec, PreferString); 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (exec->hadException()) 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return ""; 486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return primitive.toString(exec); 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4892bde8e466a4451c7319e3a072d118917957d6554Steve BlockJSObject* JSObject::toObject(ExecState*, JSGlobalObject*) const 4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return const_cast<JSObject*>(this); 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectJSObject* JSObject::toThisObject(ExecState*) const 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return const_cast<JSObject*>(this); 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 499a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochJSValue JSObject::toStrictThisObject(ExecState*) const 500a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 501a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return const_cast<JSObject*>(this); 502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 503a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 504635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectJSObject* JSObject::unwrappedObject() 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 506635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return this; 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid JSObject::seal(JSGlobalData& globalData) 51081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 5112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setStructure(globalData, Structure::sealTransition(globalData, m_structure.get())); 51281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 51381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 5142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid JSObject::freeze(JSGlobalData& globalData) 51581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 5162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setStructure(globalData, Structure::freezeTransition(globalData, m_structure.get())); 51781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 51881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 5192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid JSObject::preventExtensions(JSGlobalData& globalData) 52081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 52181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (isExtensible()) 5222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setStructure(globalData, Structure::preventExtensionsTransition(globalData, m_structure.get())); 52381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 52481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 5252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid JSObject::removeDirect(JSGlobalData& globalData, const Identifier& propertyName) 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t offset; 528231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_structure->isUncacheableDictionary()) { 5292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch offset = m_structure->removePropertyWithoutTransition(globalData, propertyName); 5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (offset != WTF::notFound) 5312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block putUndefinedAtDirectOffset(offset); 5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch setStructure(globalData, Structure::removePropertyTransition(globalData, m_structure.get(), propertyName, offset)); 5365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (offset != WTF::notFound) 5372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block putUndefinedAtDirectOffset(offset); 5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr) 5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block putDirectFunction(exec->globalData(), Identifier(exec, function->name(exec)), function, attr); 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 545e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid JSObject::putDirectFunction(ExecState* exec, JSFunction* function, unsigned attr) 546e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 5472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block putDirectFunction(exec->globalData(), Identifier(exec, function->name(exec)), function, attr); 548e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 549e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr) 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, function->name(exec)), function, attr); 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 555e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid JSObject::putDirectFunctionWithoutTransition(ExecState* exec, JSFunction* function, unsigned attr) 556e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 5572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block putDirectFunctionWithoutTransition(exec->globalData(), Identifier(exec, function->name(exec)), function, attr); 558e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 559e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 5602fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockNEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, WriteBarrierBase<Unknown>* location) 5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (JSObject* getterFunction = asGetterSetter(location->get())->getter()) { 563692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!structure()->isDictionary()) 564692e5dbf12901edacf14812a6fae25462920af42Steve Block slot.setCacheableGetterSlot(this, getterFunction, offsetForLocation(location)); 565692e5dbf12901edacf14812a6fae25462920af42Steve Block else 566692e5dbf12901edacf14812a6fae25462920af42Steve Block slot.setGetterSlot(getterFunction); 567692e5dbf12901edacf14812a6fae25462920af42Steve Block } else 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project slot.setUndefined(); 5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5712bde8e466a4451c7319e3a072d118917957d6554Steve BlockStructure* JSObject::createInheritorID(JSGlobalData& globalData) 5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_inheritorID.set(globalData, this, createEmptyObjectStructure(globalData, this)); 5742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(m_inheritorID->isEmpty()); 5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_inheritorID.get(); 5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize) 5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 58081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(newSize > oldSize); 58181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 58281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // It's important that this function not rely on m_structure, since 58381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // we might be in the middle of a transition. 58481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch bool wasInline = (oldSize < JSObject::baseExternalStorageCapacity); 58581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 58681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch PropertyStorage oldPropertyStorage = m_propertyStorage; 58781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch PropertyStorage newPropertyStorage = new WriteBarrierBase<Unknown>[newSize]; 58881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 58981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (unsigned i = 0; i < oldSize; ++i) 59081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch newPropertyStorage[i] = oldPropertyStorage[i]; 59181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 59281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!wasInline) 59381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch delete [] oldPropertyStorage; 59481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 59581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_propertyStorage = newPropertyStorage; 5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool JSObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 599231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 600231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block unsigned attributes = 0; 601231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSCell* cell = 0; 6022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch size_t offset = m_structure->get(exec->globalData(), propertyName, attributes, cell); 603231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (offset == WTF::notFound) 604231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 605231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block descriptor.setDescriptor(getDirectOffset(offset), attributes); 606231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 607231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 608231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 609231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool JSObject::getPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 611231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSObject* object = this; 612231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block while (true) { 613231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (object->getOwnPropertyDescriptor(exec, propertyName, descriptor)) 614231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 615231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSValue prototype = object->prototype(); 616231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!prototype.isObject()) 617231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 618231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block object = asObject(prototype); 619231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 620231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 621231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 62265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& propertyName, PropertyDescriptor& descriptor, unsigned attributes, const PropertyDescriptor& oldDescriptor) 623231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 624231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) { 62565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (descriptor.isGenericDescriptor() && oldDescriptor.isAccessorDescriptor()) { 62665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch GetterSetter* accessor = new (exec) GetterSetter(exec); 62765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (oldDescriptor.getter()) { 62865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch attributes |= Getter; 6292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block accessor->setGetter(exec->globalData(), asObject(oldDescriptor.getter())); 63065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 63165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (oldDescriptor.setter()) { 63265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch attributes |= Setter; 6332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block accessor->setSetter(exec->globalData(), asObject(oldDescriptor.setter())); 63465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 63565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch target->putWithAttributes(exec, propertyName, accessor, attributes); 63665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 63765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 63865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch JSValue newValue = jsUndefined(); 63965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (descriptor.value()) 64065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch newValue = descriptor.value(); 64165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch else if (oldDescriptor.value()) 64265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch newValue = oldDescriptor.value(); 64365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch target->putWithAttributes(exec, propertyName, newValue, attributes & ~(Getter | Setter)); 644231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 645231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 646231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block attributes &= ~ReadOnly; 647231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.getter() && descriptor.getter().isObject()) 648231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block target->defineGetter(exec, propertyName, asObject(descriptor.getter()), attributes); 649231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (exec->hadException()) 650231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 651231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.setter() && descriptor.setter().isObject()) 652231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block target->defineSetter(exec, propertyName, asObject(descriptor.setter()), attributes); 653231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return !exec->hadException(); 654231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 655231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 656231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException) 657231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 658231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If we have a new property we can just put it on normally 659231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block PropertyDescriptor current; 66065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!getOwnPropertyDescriptor(exec, propertyName, current)) { 66181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // unless extensions are prevented! 66281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (!isExtensible()) { 66381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (throwException) 66481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible.")); 66581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return false; 66681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 66765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PropertyDescriptor oldDescriptor; 66865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch oldDescriptor.setValue(jsUndefined()); 66965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return putDescriptor(exec, this, propertyName, descriptor, descriptor.attributes(), oldDescriptor); 67065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 671231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 672231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.isEmpty()) 673231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 674231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 675643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (current.equalTo(exec, descriptor)) 676231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 677231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 678231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Filter out invalid changes 679231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!current.configurable()) { 680231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.configurable()) { 681231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (throwException) 682545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property.")); 683231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 684231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 685231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) { 686231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (throwException) 687545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property.")); 688231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 689231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 690231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 691231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 692231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // A generic descriptor is simply changing the attributes of an existing property 693231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.isGenericDescriptor()) { 694231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!current.attributesEqual(descriptor)) { 695231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block deleteProperty(exec, propertyName); 69665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current); 697231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 698231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 699231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 700231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 701231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Changing between a normal property or an accessor property 702231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.isDataDescriptor() != current.isDataDescriptor()) { 703231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!current.configurable()) { 704231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (throwException) 705545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property.")); 706231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 707231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 708231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block deleteProperty(exec, propertyName); 70965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current); 710231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 711231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 712231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Changing the value and attributes of an existing property 713231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.isDataDescriptor()) { 714231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!current.configurable()) { 715231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!current.writable() && descriptor.writable()) { 716231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (throwException) 717545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property.")); 718231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 719231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 720231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!current.writable()) { 721643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (descriptor.value() || !JSValue::strictEqual(exec, current.value(), descriptor.value())) { 722231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (throwException) 723545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property.")); 724231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 725231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 726231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 727231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } else if (current.attributesEqual(descriptor)) { 728231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!descriptor.value()) 729231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 730231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block PutPropertySlot slot; 731231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block put(exec, propertyName, descriptor.value(), slot); 732231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (exec->hadException()) 733231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 734231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 735231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 736231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block deleteProperty(exec, propertyName); 73765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current); 738231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 739231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 740231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Changing the accessor functions of an existing accessor property 741231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(descriptor.isAccessorDescriptor()); 742231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!current.configurable()) { 7432bde8e466a4451c7319e3a072d118917957d6554Steve Block if (descriptor.setterPresent() && !(current.setterPresent() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) { 744231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (throwException) 745545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "Attempting to change the setter of an unconfigurable property.")); 746231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 747231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 7482bde8e466a4451c7319e3a072d118917957d6554Steve Block if (descriptor.getterPresent() && !(current.getterPresent() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) { 749231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (throwException) 750545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch throwError(exec, createTypeError(exec, "Attempting to change the getter of an unconfigurable property.")); 751231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 752231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 753231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 7542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch JSValue accessor = getDirect(exec->globalData(), propertyName); 755231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!accessor) 756231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 757231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block GetterSetter* getterSetter = asGetterSetter(accessor); 758231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (current.attributesEqual(descriptor)) { 759231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.setter()) 7602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block getterSetter->setSetter(exec->globalData(), asObject(descriptor.setter())); 761231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.getter()) 7622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block getterSetter->setGetter(exec->globalData(), asObject(descriptor.getter())); 763231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 764231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 765231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block deleteProperty(exec, propertyName); 766231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block unsigned attrs = current.attributesWithOverride(descriptor); 767231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.setter()) 768231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block attrs |= Setter; 769231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (descriptor.getter()) 770231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block attrs |= Getter; 7712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block putDirect(exec->globalData(), propertyName, getterSetter, attrs); 772231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 775a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochJSObject* throwTypeError(ExecState* exec, const UString& message) 776a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 777a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return throwError(exec, createTypeError(exec, message)); 778a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 779a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 781