2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 
   3  *  Copyright (C) 2008 Apple Inc. All rights reserved. 
   5  *  This library is free software; you can redistribute it and/or 
   6  *  modify it under the terms of the GNU Lesser General Public 
   7  *  License as published by the Free Software Foundation; either 
   8  *  version 2 of the License, or (at your option) any later version. 
  10  *  This library is distributed in the hope that it will be useful, 
  11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
  12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  13  *  Lesser General Public License for more details. 
  15  *  You should have received a copy of the GNU Lesser General Public 
  16  *  License along with this library; if not, write to the Free Software 
  17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA 
  22 #include "ObjectConstructor.h" 
  24 #include "ButterflyInlines.h" 
  25 #include "CopiedSpaceInlines.h" 
  27 #include "ExceptionHelpers.h" 
  28 #include "JSFunction.h" 
  30 #include "JSGlobalObject.h" 
  32 #include "ObjectPrototype.h" 
  33 #include "JSCInlines.h" 
  34 #include "PropertyDescriptor.h" 
  35 #include "PropertyNameArray.h" 
  36 #include "StackVisitor.h" 
  40 static EncodedJSValue JSC_HOST_CALL 
objectConstructorGetPrototypeOf(ExecState
*); 
  41 static EncodedJSValue JSC_HOST_CALL 
objectConstructorGetOwnPropertyDescriptor(ExecState
*); 
  42 static EncodedJSValue JSC_HOST_CALL 
objectConstructorGetOwnPropertyNames(ExecState
*); 
  43 static EncodedJSValue JSC_HOST_CALL 
objectConstructorKeys(ExecState
*); 
  44 static EncodedJSValue JSC_HOST_CALL 
objectConstructorDefineProperty(ExecState
*); 
  45 static EncodedJSValue JSC_HOST_CALL 
objectConstructorDefineProperties(ExecState
*); 
  46 static EncodedJSValue JSC_HOST_CALL 
objectConstructorCreate(ExecState
*); 
  47 static EncodedJSValue JSC_HOST_CALL 
objectConstructorSeal(ExecState
*); 
  48 static EncodedJSValue JSC_HOST_CALL 
objectConstructorFreeze(ExecState
*); 
  49 static EncodedJSValue JSC_HOST_CALL 
objectConstructorPreventExtensions(ExecState
*); 
  50 static EncodedJSValue JSC_HOST_CALL 
objectConstructorIsSealed(ExecState
*); 
  51 static EncodedJSValue JSC_HOST_CALL 
objectConstructorIsFrozen(ExecState
*); 
  52 static EncodedJSValue JSC_HOST_CALL 
objectConstructorIsExtensible(ExecState
*); 
  56 #include "ObjectConstructor.lut.h" 
  60 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ObjectConstructor
); 
  62 const ClassInfo 
ObjectConstructor::s_info 
= { "Function", &InternalFunction::s_info
, 0, ExecState::objectConstructorTable
, CREATE_METHOD_TABLE(ObjectConstructor
) }; 
  64 /* Source for ObjectConstructor.lut.h 
  65 @begin objectConstructorTable 
  66   getPrototypeOf            objectConstructorGetPrototypeOf             DontEnum|Function 1 
  67   getOwnPropertyDescriptor  objectConstructorGetOwnPropertyDescriptor   DontEnum|Function 2 
  68   getOwnPropertyNames       objectConstructorGetOwnPropertyNames        DontEnum|Function 1 
  69   keys                      objectConstructorKeys                       DontEnum|Function 1 
  70   defineProperty            objectConstructorDefineProperty             DontEnum|Function 3 
  71   defineProperties          objectConstructorDefineProperties           DontEnum|Function 2 
  72   create                    objectConstructorCreate                     DontEnum|Function 2 
  73   seal                      objectConstructorSeal                       DontEnum|Function 1 
  74   freeze                    objectConstructorFreeze                     DontEnum|Function 1 
  75   preventExtensions         objectConstructorPreventExtensions          DontEnum|Function 1 
  76   isSealed                  objectConstructorIsSealed                   DontEnum|Function 1 
  77   isFrozen                  objectConstructorIsFrozen                   DontEnum|Function 1 
  78   isExtensible              objectConstructorIsExtensible               DontEnum|Function 1 
  82 ObjectConstructor::ObjectConstructor(VM
& vm
, Structure
* structure
) 
  83     : InternalFunction(vm
, structure
) 
  87 void ObjectConstructor::finishCreation(VM
& vm
, ObjectPrototype
* objectPrototype
) 
  89     Base::finishCreation(vm
, Identifier(&vm
, "Object").string()); 
  91     putDirectWithoutTransition(vm
, vm
.propertyNames
->prototype
, objectPrototype
, DontEnum 
| DontDelete 
| ReadOnly
); 
  92     // no. of arguments for constructor 
  93     putDirectWithoutTransition(vm
, vm
.propertyNames
->length
, jsNumber(1), ReadOnly 
| DontEnum 
| DontDelete
); 
  96 bool ObjectConstructor::getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot 
&slot
) 
  98     return getStaticFunctionSlot
<JSObject
>(exec
, ExecState::objectConstructorTable(exec
->vm()), jsCast
<ObjectConstructor
*>(object
), propertyName
, slot
); 
 101 static ALWAYS_INLINE JSObject
* constructObject(ExecState
* exec
) 
 103     JSGlobalObject
* globalObject 
= exec
->callee()->globalObject(); 
 105     JSValue arg 
= args
.at(0); 
 106     if (arg
.isUndefinedOrNull()) 
 107         return constructEmptyObject(exec
, globalObject
->objectPrototype()); 
 108     return arg
.toObject(exec
, globalObject
); 
 111 static EncodedJSValue JSC_HOST_CALL 
constructWithObjectConstructor(ExecState
* exec
) 
 113     return JSValue::encode(constructObject(exec
)); 
 116 ConstructType 
ObjectConstructor::getConstructData(JSCell
*, ConstructData
& constructData
) 
 118     constructData
.native
.function 
= constructWithObjectConstructor
; 
 119     return ConstructTypeHost
; 
 122 static EncodedJSValue JSC_HOST_CALL 
callObjectConstructor(ExecState
* exec
) 
 124     return JSValue::encode(constructObject(exec
)); 
 127 CallType 
ObjectConstructor::getCallData(JSCell
*, CallData
& callData
) 
 129     callData
.native
.function 
= callObjectConstructor
; 
 133 class ObjectConstructorGetPrototypeOfFunctor 
{ 
 135     ObjectConstructorGetPrototypeOfFunctor(JSObject
* object
) 
 136         : m_hasSkippedFirstFrame(false) 
 138         , m_result(JSValue::encode(jsUndefined())) 
 142     EncodedJSValue 
result() const { return m_result
; } 
 144     StackVisitor::Status 
operator()(StackVisitor
& visitor
) 
 146         if (!m_hasSkippedFirstFrame
) { 
 147             m_hasSkippedFirstFrame 
= true; 
 148             return StackVisitor::Continue
; 
 151     if (m_object
->allowsAccessFrom(visitor
->callFrame())) 
 152         m_result 
= JSValue::encode(m_object
->prototype()); 
 153     return StackVisitor::Done
; 
 157     bool m_hasSkippedFirstFrame
; 
 159     EncodedJSValue m_result
; 
 162 EncodedJSValue JSC_HOST_CALL 
objectConstructorGetPrototypeOf(ExecState
* exec
) 
 164     if (!exec
->argument(0).isObject()) 
 165         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Requested prototype of a value that is not an object."))); 
 166     JSObject
* object 
= asObject(exec
->argument(0)); 
 167     ObjectConstructorGetPrototypeOfFunctor 
functor(object
); 
 168     exec
->iterate(functor
); 
 169     return functor
.result(); 
 172 EncodedJSValue JSC_HOST_CALL 
objectConstructorGetOwnPropertyDescriptor(ExecState
* exec
) 
 174     if (!exec
->argument(0).isObject()) 
 175         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Requested property descriptor of a value that is not an object."))); 
 176     String propertyName 
= exec
->argument(1).toString(exec
)->value(exec
); 
 177     if (exec
->hadException()) 
 178         return JSValue::encode(jsNull()); 
 179     JSObject
* object 
= asObject(exec
->argument(0)); 
 180     PropertyDescriptor descriptor
; 
 181     if (!object
->getOwnPropertyDescriptor(exec
, Identifier(exec
, propertyName
), descriptor
)) 
 182         return JSValue::encode(jsUndefined()); 
 183     if (exec
->hadException()) 
 184         return JSValue::encode(jsUndefined()); 
 186     JSObject
* description 
= constructEmptyObject(exec
); 
 187     if (!descriptor
.isAccessorDescriptor()) { 
 188         description
->putDirect(exec
->vm(), exec
->propertyNames().value
, descriptor
.value() ? descriptor
.value() : jsUndefined(), 0); 
 189         description
->putDirect(exec
->vm(), exec
->propertyNames().writable
, jsBoolean(descriptor
.writable()), 0); 
 191         ASSERT(descriptor
.getter()); 
 192         ASSERT(descriptor
.setter()); 
 193         description
->putDirect(exec
->vm(), exec
->propertyNames().get
, descriptor
.getter(), 0); 
 194         description
->putDirect(exec
->vm(), exec
->propertyNames().set
, descriptor
.setter(), 0); 
 197     description
->putDirect(exec
->vm(), exec
->propertyNames().enumerable
, jsBoolean(descriptor
.enumerable()), 0); 
 198     description
->putDirect(exec
->vm(), exec
->propertyNames().configurable
, jsBoolean(descriptor
.configurable()), 0); 
 200     return JSValue::encode(description
); 
 203 // FIXME: Use the enumeration cache. 
 204 EncodedJSValue JSC_HOST_CALL 
objectConstructorGetOwnPropertyNames(ExecState
* exec
) 
 206     if (!exec
->argument(0).isObject()) 
 207         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Requested property names of a value that is not an object."))); 
 208     PropertyNameArray 
properties(exec
); 
 209     asObject(exec
->argument(0))->methodTable(exec
->vm())->getOwnPropertyNames(asObject(exec
->argument(0)), exec
, properties
, IncludeDontEnumProperties
); 
 210     JSArray
* names 
= constructEmptyArray(exec
, 0); 
 211     size_t numProperties 
= properties
.size(); 
 212     for (size_t i 
= 0; i 
< numProperties
; i
++) 
 213         names
->push(exec
, jsOwnedString(exec
, properties
[i
].string())); 
 214     return JSValue::encode(names
); 
 217 // FIXME: Use the enumeration cache. 
 218 EncodedJSValue JSC_HOST_CALL 
objectConstructorKeys(ExecState
* exec
) 
 220     if (!exec
->argument(0).isObject()) 
 221         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Requested keys of a value that is not an object."))); 
 222     PropertyNameArray 
properties(exec
); 
 223     asObject(exec
->argument(0))->methodTable(exec
->vm())->getOwnPropertyNames(asObject(exec
->argument(0)), exec
, properties
, ExcludeDontEnumProperties
); 
 224     JSArray
* keys 
= constructEmptyArray(exec
, 0); 
 225     size_t numProperties 
= properties
.size(); 
 226     for (size_t i 
= 0; i 
< numProperties
; i
++) 
 227         keys
->push(exec
, jsOwnedString(exec
, properties
[i
].string())); 
 228     return JSValue::encode(keys
); 
 231 // ES5 8.10.5 ToPropertyDescriptor 
 232 static bool toPropertyDescriptor(ExecState
* exec
, JSValue in
, PropertyDescriptor
& desc
) 
 234     if (!in
.isObject()) { 
 235         exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Property description must be an object."))); 
 238     JSObject
* description 
= asObject(in
); 
 240     PropertySlot 
enumerableSlot(description
); 
 241     if (description
->getPropertySlot(exec
, exec
->propertyNames().enumerable
, enumerableSlot
)) { 
 242         desc
.setEnumerable(enumerableSlot
.getValue(exec
, exec
->propertyNames().enumerable
).toBoolean(exec
)); 
 243         if (exec
->hadException()) 
 247     PropertySlot 
configurableSlot(description
); 
 248     if (description
->getPropertySlot(exec
, exec
->propertyNames().configurable
, configurableSlot
)) { 
 249         desc
.setConfigurable(configurableSlot
.getValue(exec
, exec
->propertyNames().configurable
).toBoolean(exec
)); 
 250         if (exec
->hadException()) 
 255     PropertySlot 
valueSlot(description
); 
 256     if (description
->getPropertySlot(exec
, exec
->propertyNames().value
, valueSlot
)) { 
 257         desc
.setValue(valueSlot
.getValue(exec
, exec
->propertyNames().value
)); 
 258         if (exec
->hadException()) 
 262     PropertySlot 
writableSlot(description
); 
 263     if (description
->getPropertySlot(exec
, exec
->propertyNames().writable
, writableSlot
)) { 
 264         desc
.setWritable(writableSlot
.getValue(exec
, exec
->propertyNames().writable
).toBoolean(exec
)); 
 265         if (exec
->hadException()) 
 269     PropertySlot 
getSlot(description
); 
 270     if (description
->getPropertySlot(exec
, exec
->propertyNames().get
, getSlot
)) { 
 271         JSValue get 
= getSlot
.getValue(exec
, exec
->propertyNames().get
); 
 272         if (exec
->hadException()) 
 274         if (!get
.isUndefined()) { 
 276             if (getCallData(get
, callData
) == CallTypeNone
) { 
 277                 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Getter must be a function."))); 
 284     PropertySlot 
setSlot(description
); 
 285     if (description
->getPropertySlot(exec
, exec
->propertyNames().set
, setSlot
)) { 
 286         JSValue set 
= setSlot
.getValue(exec
, exec
->propertyNames().set
); 
 287         if (exec
->hadException()) 
 289         if (!set
.isUndefined()) { 
 291             if (getCallData(set
, callData
) == CallTypeNone
) { 
 292                 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Setter must be a function."))); 
 299     if (!desc
.isAccessorDescriptor()) 
 303         exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Invalid property.  'value' present on property with getter or setter."))); 
 307     if (desc
.writablePresent()) { 
 308         exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Invalid property.  'writable' present on property with getter or setter."))); 
 314 EncodedJSValue JSC_HOST_CALL 
objectConstructorDefineProperty(ExecState
* exec
) 
 316     if (!exec
->argument(0).isObject()) 
 317         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Properties can only be defined on Objects."))); 
 318     JSObject
* O 
= asObject(exec
->argument(0)); 
 319     String propertyName 
= exec
->argument(1).toString(exec
)->value(exec
); 
 320     if (exec
->hadException()) 
 321         return JSValue::encode(jsNull()); 
 322     PropertyDescriptor descriptor
; 
 323     if (!toPropertyDescriptor(exec
, exec
->argument(2), descriptor
)) 
 324         return JSValue::encode(jsNull()); 
 325     ASSERT((descriptor
.attributes() & Accessor
) || (!descriptor
.isAccessorDescriptor())); 
 326     ASSERT(!exec
->hadException()); 
 327     O
->methodTable(exec
->vm())->defineOwnProperty(O
, exec
, Identifier(exec
, propertyName
), descriptor
, true); 
 328     return JSValue::encode(O
); 
 331 static JSValue 
defineProperties(ExecState
* exec
, JSObject
* object
, JSObject
* properties
) 
 333     PropertyNameArray 
propertyNames(exec
); 
 334     asObject(properties
)->methodTable(exec
->vm())->getOwnPropertyNames(asObject(properties
), exec
, propertyNames
, ExcludeDontEnumProperties
); 
 335     size_t numProperties 
= propertyNames
.size(); 
 336     Vector
<PropertyDescriptor
> descriptors
; 
 337     MarkedArgumentBuffer markBuffer
; 
 338     for (size_t i 
= 0; i 
< numProperties
; i
++) { 
 339         JSValue prop 
= properties
->get(exec
, propertyNames
[i
]); 
 340         if (exec
->hadException()) 
 342         PropertyDescriptor descriptor
; 
 343         if (!toPropertyDescriptor(exec
, prop
, descriptor
)) 
 345         descriptors
.append(descriptor
); 
 346         // Ensure we mark all the values that we're accumulating 
 347         if (descriptor
.isDataDescriptor() && descriptor
.value()) 
 348             markBuffer
.append(descriptor
.value()); 
 349         if (descriptor
.isAccessorDescriptor()) { 
 350             if (descriptor
.getter()) 
 351                 markBuffer
.append(descriptor
.getter()); 
 352             if (descriptor
.setter()) 
 353                 markBuffer
.append(descriptor
.setter()); 
 356     for (size_t i 
= 0; i 
< numProperties
; i
++) { 
 357         object
->methodTable(exec
->vm())->defineOwnProperty(object
, exec
, propertyNames
[i
], descriptors
[i
], true); 
 358         if (exec
->hadException()) 
 364 EncodedJSValue JSC_HOST_CALL 
objectConstructorDefineProperties(ExecState
* exec
) 
 366     if (!exec
->argument(0).isObject()) 
 367         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Properties can only be defined on Objects."))); 
 368     return JSValue::encode(defineProperties(exec
, asObject(exec
->argument(0)), exec
->argument(1).toObject(exec
))); 
 371 EncodedJSValue JSC_HOST_CALL 
objectConstructorCreate(ExecState
* exec
) 
 373     JSValue proto 
= exec
->argument(0); 
 374     if (!proto
.isObject() && !proto
.isNull()) 
 375         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object prototype may only be an Object or null."))); 
 376     JSObject
* newObject 
= proto
.isObject() 
 377         ? constructEmptyObject(exec
, asObject(proto
)) 
 378         : constructEmptyObject(exec
, exec
->lexicalGlobalObject()->nullPrototypeObjectStructure()); 
 379     if (exec
->argument(1).isUndefined()) 
 380         return JSValue::encode(newObject
); 
 381     if (!exec
->argument(1).isObject()) 
 382         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Property descriptor list must be an Object."))); 
 383     return JSValue::encode(defineProperties(exec
, newObject
, asObject(exec
->argument(1)))); 
 386 EncodedJSValue JSC_HOST_CALL 
objectConstructorSeal(ExecState
* exec
) 
 388     // 1. If Type(O) is not Object throw a TypeError exception. 
 389     JSValue obj 
= exec
->argument(0); 
 391         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object.seal can only be called on Objects."))); 
 392     JSObject
* object 
= asObject(obj
); 
 394     if (isJSFinalObject(object
)) { 
 395         object
->seal(exec
->vm()); 
 396         return JSValue::encode(obj
); 
 399     // 2. For each named own property name P of O, 
 400     PropertyNameArray 
properties(exec
); 
 401     object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, IncludeDontEnumProperties
); 
 402     PropertyNameArray::const_iterator end 
= properties
.end(); 
 403     for (PropertyNameArray::const_iterator iter 
= properties
.begin(); iter 
!= end
; ++iter
) { 
 404         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 
 405         PropertyDescriptor desc
; 
 406         if (!object
->getOwnPropertyDescriptor(exec
, *iter
, desc
)) 
 408         // b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false. 
 409         desc
.setConfigurable(false); 
 410         // c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments. 
 411         object
->methodTable(exec
->vm())->defineOwnProperty(object
, exec
, *iter
, desc
, true); 
 412         if (exec
->hadException()) 
 413             return JSValue::encode(obj
); 
 416     // 3. Set the [[Extensible]] internal property of O to false. 
 417     object
->preventExtensions(exec
->vm()); 
 420     return JSValue::encode(obj
); 
 423 EncodedJSValue JSC_HOST_CALL 
objectConstructorFreeze(ExecState
* exec
) 
 425     // 1. If Type(O) is not Object throw a TypeError exception. 
 426     JSValue obj 
= exec
->argument(0); 
 428         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object.freeze can only be called on Objects."))); 
 429     JSObject
* object 
= asObject(obj
); 
 431     if (isJSFinalObject(object
) && !hasIndexedProperties(object
->indexingType())) { 
 432         object
->freeze(exec
->vm()); 
 433         return JSValue::encode(obj
); 
 436     // 2. For each named own property name P of O, 
 437     PropertyNameArray 
properties(exec
); 
 438     object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, IncludeDontEnumProperties
); 
 439     PropertyNameArray::const_iterator end 
= properties
.end(); 
 440     for (PropertyNameArray::const_iterator iter 
= properties
.begin(); iter 
!= end
; ++iter
) { 
 441         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 
 442         PropertyDescriptor desc
; 
 443         if (!object
->getOwnPropertyDescriptor(exec
, *iter
, desc
)) 
 445         // b. If IsDataDescriptor(desc) is true, then 
 446         // i. If desc.[[Writable]] is true, set desc.[[Writable]] to false. 
 447         if (desc
.isDataDescriptor()) 
 448             desc
.setWritable(false); 
 449         // c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false. 
 450         desc
.setConfigurable(false); 
 451         // d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments. 
 452         object
->methodTable(exec
->vm())->defineOwnProperty(object
, exec
, *iter
, desc
, true); 
 453         if (exec
->hadException()) 
 454             return JSValue::encode(obj
); 
 457     // 3. Set the [[Extensible]] internal property of O to false. 
 458     object
->preventExtensions(exec
->vm()); 
 461     return JSValue::encode(obj
); 
 464 EncodedJSValue JSC_HOST_CALL 
objectConstructorPreventExtensions(ExecState
* exec
) 
 466     JSValue obj 
= exec
->argument(0); 
 468         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object.preventExtensions can only be called on Objects."))); 
 469     asObject(obj
)->preventExtensions(exec
->vm()); 
 470     return JSValue::encode(obj
); 
 473 EncodedJSValue JSC_HOST_CALL 
objectConstructorIsSealed(ExecState
* exec
) 
 475     // 1. If Type(O) is not Object throw a TypeError exception. 
 476     JSValue obj 
= exec
->argument(0); 
 478         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object.isSealed can only be called on Objects."))); 
 479     JSObject
* object 
= asObject(obj
); 
 481     if (isJSFinalObject(object
)) 
 482         return JSValue::encode(jsBoolean(object
->isSealed(exec
->vm()))); 
 484     // 2. For each named own property name P of O, 
 485     PropertyNameArray 
properties(exec
); 
 486     object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, IncludeDontEnumProperties
); 
 487     PropertyNameArray::const_iterator end 
= properties
.end(); 
 488     for (PropertyNameArray::const_iterator iter 
= properties
.begin(); iter 
!= end
; ++iter
) { 
 489         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 
 490         PropertyDescriptor desc
; 
 491         if (!object
->getOwnPropertyDescriptor(exec
, *iter
, desc
)) 
 493         // b. If desc.[[Configurable]] is true, then return false. 
 494         if (desc
.configurable()) 
 495             return JSValue::encode(jsBoolean(false)); 
 498     // 3. If the [[Extensible]] internal property of O is false, then return true. 
 499     // 4. Otherwise, return false. 
 500     return JSValue::encode(jsBoolean(!object
->isExtensible())); 
 503 EncodedJSValue JSC_HOST_CALL 
objectConstructorIsFrozen(ExecState
* exec
) 
 505     // 1. If Type(O) is not Object throw a TypeError exception. 
 506     JSValue obj 
= exec
->argument(0); 
 508         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object.isFrozen can only be called on Objects."))); 
 509     JSObject
* object 
= asObject(obj
); 
 511     if (isJSFinalObject(object
)) 
 512         return JSValue::encode(jsBoolean(object
->isFrozen(exec
->vm()))); 
 514     // 2. For each named own property name P of O, 
 515     PropertyNameArray 
properties(exec
); 
 516     object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, IncludeDontEnumProperties
); 
 517     PropertyNameArray::const_iterator end 
= properties
.end(); 
 518     for (PropertyNameArray::const_iterator iter 
= properties
.begin(); iter 
!= end
; ++iter
) { 
 519         // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 
 520         PropertyDescriptor desc
; 
 521         if (!object
->getOwnPropertyDescriptor(exec
, *iter
, desc
)) 
 523         // b. If IsDataDescriptor(desc) is true then 
 524         // i. If desc.[[Writable]] is true, return false. c. If desc.[[Configurable]] is true, then return false. 
 525         if ((desc
.isDataDescriptor() && desc
.writable()) || desc
.configurable()) 
 526             return JSValue::encode(jsBoolean(false)); 
 529     // 3. If the [[Extensible]] internal property of O is false, then return true. 
 530     // 4. Otherwise, return false. 
 531     return JSValue::encode(jsBoolean(!object
->isExtensible())); 
 534 EncodedJSValue JSC_HOST_CALL 
objectConstructorIsExtensible(ExecState
* exec
) 
 536     JSValue obj 
= exec
->argument(0); 
 538         return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object.isExtensible can only be called on Objects."))); 
 539     return JSValue::encode(jsBoolean(asObject(obj
)->isExtensible()));