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"
29 #include "JSCInlines.h"
30 #include "JSFunction.h"
31 #include "JSGlobalObject.h"
32 #include "JSGlobalObjectFunctions.h"
34 #include "ObjectPrototype.h"
35 #include "PropertyDescriptor.h"
36 #include "PropertyNameArray.h"
37 #include "StackVisitor.h"
42 EncodedJSValue JSC_HOST_CALL
objectConstructorGetPrototypeOf(ExecState
*);
43 EncodedJSValue JSC_HOST_CALL
objectConstructorSetPrototypeOf(ExecState
*);
44 EncodedJSValue JSC_HOST_CALL
objectConstructorGetOwnPropertyNames(ExecState
*);
45 EncodedJSValue JSC_HOST_CALL
objectConstructorDefineProperty(ExecState
*);
46 EncodedJSValue JSC_HOST_CALL
objectConstructorDefineProperties(ExecState
*);
47 EncodedJSValue JSC_HOST_CALL
objectConstructorCreate(ExecState
*);
48 EncodedJSValue JSC_HOST_CALL
objectConstructorSeal(ExecState
*);
49 EncodedJSValue JSC_HOST_CALL
objectConstructorFreeze(ExecState
*);
50 EncodedJSValue JSC_HOST_CALL
objectConstructorPreventExtensions(ExecState
*);
51 EncodedJSValue JSC_HOST_CALL
objectConstructorIsSealed(ExecState
*);
52 EncodedJSValue JSC_HOST_CALL
objectConstructorIsFrozen(ExecState
*);
53 EncodedJSValue JSC_HOST_CALL
objectConstructorIsExtensible(ExecState
*);
54 EncodedJSValue JSC_HOST_CALL
objectConstructorIs(ExecState
*);
58 #include "ObjectConstructor.lut.h"
62 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ObjectConstructor
);
64 const ClassInfo
ObjectConstructor::s_info
= { "Function", &InternalFunction::s_info
, &objectConstructorTable
, CREATE_METHOD_TABLE(ObjectConstructor
) };
66 /* Source for ObjectConstructor.lut.h
67 @begin objectConstructorTable
68 getPrototypeOf objectConstructorGetPrototypeOf DontEnum|Function 1
69 setPrototypeOf objectConstructorSetPrototypeOf DontEnum|Function 2
70 getOwnPropertyDescriptor objectConstructorGetOwnPropertyDescriptor DontEnum|Function 2
71 getOwnPropertyNames objectConstructorGetOwnPropertyNames DontEnum|Function 1
72 keys objectConstructorKeys DontEnum|Function 1
73 defineProperty objectConstructorDefineProperty DontEnum|Function 3
74 defineProperties objectConstructorDefineProperties DontEnum|Function 2
75 create objectConstructorCreate DontEnum|Function 2
76 seal objectConstructorSeal DontEnum|Function 1
77 freeze objectConstructorFreeze DontEnum|Function 1
78 preventExtensions objectConstructorPreventExtensions DontEnum|Function 1
79 isSealed objectConstructorIsSealed DontEnum|Function 1
80 isFrozen objectConstructorIsFrozen DontEnum|Function 1
81 isExtensible objectConstructorIsExtensible DontEnum|Function 1
82 is objectConstructorIs DontEnum|Function 2
83 assign objectConstructorAssign DontEnum|Function 2
87 ObjectConstructor::ObjectConstructor(VM
& vm
, Structure
* structure
)
88 : InternalFunction(vm
, structure
)
92 void ObjectConstructor::finishCreation(VM
& vm
, JSGlobalObject
* globalObject
, ObjectPrototype
* objectPrototype
)
94 Base::finishCreation(vm
, objectPrototype
->classInfo()->className
);
96 putDirectWithoutTransition(vm
, vm
.propertyNames
->prototype
, objectPrototype
, DontEnum
| DontDelete
| ReadOnly
);
97 // no. of arguments for constructor
98 putDirectWithoutTransition(vm
, vm
.propertyNames
->length
, jsNumber(1), ReadOnly
| DontEnum
| DontDelete
);
100 if (!globalObject
->runtimeFlags().isSymbolDisabled())
101 JSC_NATIVE_FUNCTION("getOwnPropertySymbols", objectConstructorGetOwnPropertySymbols
, DontEnum
, 1);
103 JSC_NATIVE_FUNCTION(vm
.propertyNames
->getPrototypeOfPrivateName
, objectConstructorGetPrototypeOf
, DontEnum
, 1);
104 JSC_NATIVE_FUNCTION(vm
.propertyNames
->getOwnPropertyNamesPrivateName
, objectConstructorGetOwnPropertyNames
, DontEnum
, 1);
107 JSFunction
* ObjectConstructor::addDefineProperty(ExecState
* exec
, JSGlobalObject
* globalObject
)
110 JSFunction
* definePropertyFunction
= JSFunction::create(vm
, globalObject
, 3, vm
.propertyNames
->defineProperty
.string(), objectConstructorDefineProperty
);
111 putDirectWithoutTransition(vm
, vm
.propertyNames
->defineProperty
, definePropertyFunction
, DontEnum
);
112 return definePropertyFunction
;
115 bool ObjectConstructor::getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
&slot
)
117 return getStaticFunctionSlot
<JSObject
>(exec
, objectConstructorTable
, jsCast
<ObjectConstructor
*>(object
), propertyName
, slot
);
120 static ALWAYS_INLINE JSObject
* constructObject(ExecState
* exec
)
122 JSGlobalObject
* globalObject
= exec
->callee()->globalObject();
124 JSValue arg
= args
.at(0);
125 if (arg
.isUndefinedOrNull())
126 return constructEmptyObject(exec
, globalObject
->objectPrototype());
127 return arg
.toObject(exec
, globalObject
);
130 static EncodedJSValue JSC_HOST_CALL
constructWithObjectConstructor(ExecState
* exec
)
132 return JSValue::encode(constructObject(exec
));
135 ConstructType
ObjectConstructor::getConstructData(JSCell
*, ConstructData
& constructData
)
137 constructData
.native
.function
= constructWithObjectConstructor
;
138 return ConstructTypeHost
;
141 static EncodedJSValue JSC_HOST_CALL
callObjectConstructor(ExecState
* exec
)
143 return JSValue::encode(constructObject(exec
));
146 CallType
ObjectConstructor::getCallData(JSCell
*, CallData
& callData
)
148 callData
.native
.function
= callObjectConstructor
;
152 class ObjectConstructorGetPrototypeOfFunctor
{
154 ObjectConstructorGetPrototypeOfFunctor(JSObject
* object
)
155 : m_hasSkippedFirstFrame(false)
157 , m_result(JSValue::encode(jsUndefined()))
161 EncodedJSValue
result() const { return m_result
; }
163 StackVisitor::Status
operator()(StackVisitor
& visitor
)
165 if (!m_hasSkippedFirstFrame
) {
166 m_hasSkippedFirstFrame
= true;
167 return StackVisitor::Continue
;
170 if (m_object
->allowsAccessFrom(visitor
->callFrame()))
171 m_result
= JSValue::encode(m_object
->prototype());
172 return StackVisitor::Done
;
176 bool m_hasSkippedFirstFrame
;
178 EncodedJSValue m_result
;
181 EncodedJSValue JSC_HOST_CALL
objectConstructorGetPrototypeOf(ExecState
* exec
)
183 JSObject
* object
= exec
->argument(0).toObject(exec
);
184 if (exec
->hadException())
185 return JSValue::encode(jsNull());
186 ObjectConstructorGetPrototypeOfFunctor
functor(object
);
187 exec
->iterate(functor
);
188 return functor
.result();
191 EncodedJSValue JSC_HOST_CALL
objectConstructorSetPrototypeOf(ExecState
* exec
)
193 JSValue objectValue
= exec
->argument(0);
194 if (objectValue
.isUndefinedOrNull())
195 return throwVMTypeError(exec
);
197 JSValue protoValue
= exec
->argument(1);
198 if (!protoValue
.isObject() && !protoValue
.isNull())
199 return throwVMTypeError(exec
);
201 JSObject
* object
= objectValue
.toObject(exec
);
202 if (exec
->hadException())
203 return JSValue::encode(objectValue
);
205 if (!checkProtoSetterAccessAllowed(exec
, object
))
206 return JSValue::encode(objectValue
);
208 if (!object
->isExtensible())
209 return throwVMError(exec
, createTypeError(exec
, StrictModeReadonlyPropertyWriteError
));
211 if (!object
->setPrototypeWithCycleCheck(exec
, protoValue
)) {
212 exec
->vm().throwException(exec
, createError(exec
, ASCIILiteral("cyclic __proto__ value")));
213 return JSValue::encode(jsUndefined());
216 return JSValue::encode(objectValue
);
219 EncodedJSValue JSC_HOST_CALL
objectConstructorGetOwnPropertyDescriptor(ExecState
* exec
)
221 JSObject
* object
= exec
->argument(0).toObject(exec
);
222 if (exec
->hadException())
223 return JSValue::encode(jsNull());
224 auto propertyName
= exec
->argument(1).toPropertyKey(exec
);
225 if (exec
->hadException())
226 return JSValue::encode(jsNull());
227 PropertyDescriptor descriptor
;
228 if (!object
->getOwnPropertyDescriptor(exec
, propertyName
, descriptor
))
229 return JSValue::encode(jsUndefined());
230 if (exec
->hadException())
231 return JSValue::encode(jsUndefined());
233 JSObject
* description
= constructEmptyObject(exec
);
234 if (!descriptor
.isAccessorDescriptor()) {
235 description
->putDirect(exec
->vm(), exec
->propertyNames().value
, descriptor
.value() ? descriptor
.value() : jsUndefined(), 0);
236 description
->putDirect(exec
->vm(), exec
->propertyNames().writable
, jsBoolean(descriptor
.writable()), 0);
238 ASSERT(descriptor
.getter());
239 ASSERT(descriptor
.setter());
240 description
->putDirect(exec
->vm(), exec
->propertyNames().get
, descriptor
.getter(), 0);
241 description
->putDirect(exec
->vm(), exec
->propertyNames().set
, descriptor
.setter(), 0);
244 description
->putDirect(exec
->vm(), exec
->propertyNames().enumerable
, jsBoolean(descriptor
.enumerable()), 0);
245 description
->putDirect(exec
->vm(), exec
->propertyNames().configurable
, jsBoolean(descriptor
.configurable()), 0);
247 return JSValue::encode(description
);
250 // FIXME: Use the enumeration cache.
251 EncodedJSValue JSC_HOST_CALL
objectConstructorGetOwnPropertyNames(ExecState
* exec
)
253 JSObject
* object
= exec
->argument(0).toObject(exec
);
254 if (exec
->hadException())
255 return JSValue::encode(jsNull());
256 PropertyNameArray
properties(exec
);
257 object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, EnumerationMode(DontEnumPropertiesMode::Include
));
258 JSArray
* names
= constructEmptyArray(exec
, 0);
259 size_t numProperties
= properties
.size();
260 for (size_t i
= 0; i
< numProperties
; i
++)
261 names
->push(exec
, jsOwnedString(exec
, properties
[i
].string()));
262 return JSValue::encode(names
);
265 // FIXME: Use the enumeration cache.
266 EncodedJSValue JSC_HOST_CALL
objectConstructorGetOwnPropertySymbols(ExecState
* exec
)
268 JSObject
* object
= exec
->argument(0).toObject(exec
);
269 if (exec
->hadException())
270 return JSValue::encode(jsNull());
271 PropertyNameArray
properties(exec
);
272 object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, EnumerationMode(DontEnumPropertiesMode::Include
, SymbolPropertiesMode::Include
));
273 JSArray
* names
= constructEmptyArray(exec
, 0);
274 size_t numProperties
= properties
.size();
275 for (size_t i
= 0; i
< numProperties
; i
++) {
276 auto impl
= properties
[i
].impl();
277 if (impl
->isSymbol() && !exec
->propertyNames().isPrivateName(*impl
))
278 names
->push(exec
, Symbol::create(exec
->vm(), static_cast<SymbolImpl
&>(*impl
)));
280 return JSValue::encode(names
);
283 // FIXME: Use the enumeration cache.
284 EncodedJSValue JSC_HOST_CALL
objectConstructorKeys(ExecState
* exec
)
286 JSObject
* object
= exec
->argument(0).toObject(exec
);
287 if (exec
->hadException())
288 return JSValue::encode(jsNull());
289 PropertyNameArray
properties(exec
);
290 object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, EnumerationMode());
291 JSArray
* keys
= constructEmptyArray(exec
, 0);
292 size_t numProperties
= properties
.size();
293 for (size_t i
= 0; i
< numProperties
; i
++)
294 keys
->push(exec
, jsOwnedString(exec
, properties
[i
].string()));
295 return JSValue::encode(keys
);
298 // ES5 8.10.5 ToPropertyDescriptor
299 static bool toPropertyDescriptor(ExecState
* exec
, JSValue in
, PropertyDescriptor
& desc
)
301 if (!in
.isObject()) {
302 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Property description must be an object.")));
305 JSObject
* description
= asObject(in
);
307 PropertySlot
enumerableSlot(description
);
308 if (description
->getPropertySlot(exec
, exec
->propertyNames().enumerable
, enumerableSlot
)) {
309 desc
.setEnumerable(enumerableSlot
.getValue(exec
, exec
->propertyNames().enumerable
).toBoolean(exec
));
310 if (exec
->hadException())
314 PropertySlot
configurableSlot(description
);
315 if (description
->getPropertySlot(exec
, exec
->propertyNames().configurable
, configurableSlot
)) {
316 desc
.setConfigurable(configurableSlot
.getValue(exec
, exec
->propertyNames().configurable
).toBoolean(exec
));
317 if (exec
->hadException())
322 PropertySlot
valueSlot(description
);
323 if (description
->getPropertySlot(exec
, exec
->propertyNames().value
, valueSlot
)) {
324 desc
.setValue(valueSlot
.getValue(exec
, exec
->propertyNames().value
));
325 if (exec
->hadException())
329 PropertySlot
writableSlot(description
);
330 if (description
->getPropertySlot(exec
, exec
->propertyNames().writable
, writableSlot
)) {
331 desc
.setWritable(writableSlot
.getValue(exec
, exec
->propertyNames().writable
).toBoolean(exec
));
332 if (exec
->hadException())
336 PropertySlot
getSlot(description
);
337 if (description
->getPropertySlot(exec
, exec
->propertyNames().get
, getSlot
)) {
338 JSValue get
= getSlot
.getValue(exec
, exec
->propertyNames().get
);
339 if (exec
->hadException())
341 if (!get
.isUndefined()) {
343 if (getCallData(get
, callData
) == CallTypeNone
) {
344 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Getter must be a function.")));
351 PropertySlot
setSlot(description
);
352 if (description
->getPropertySlot(exec
, exec
->propertyNames().set
, setSlot
)) {
353 JSValue set
= setSlot
.getValue(exec
, exec
->propertyNames().set
);
354 if (exec
->hadException())
356 if (!set
.isUndefined()) {
358 if (getCallData(set
, callData
) == CallTypeNone
) {
359 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Setter must be a function.")));
366 if (!desc
.isAccessorDescriptor())
370 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Invalid property. 'value' present on property with getter or setter.")));
374 if (desc
.writablePresent()) {
375 exec
->vm().throwException(exec
, createTypeError(exec
, ASCIILiteral("Invalid property. 'writable' present on property with getter or setter.")));
381 EncodedJSValue JSC_HOST_CALL
objectConstructorDefineProperty(ExecState
* exec
)
383 if (!exec
->argument(0).isObject())
384 return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Properties can only be defined on Objects.")));
385 JSObject
* O
= asObject(exec
->argument(0));
386 auto propertyName
= exec
->argument(1).toPropertyKey(exec
);
387 if (exec
->hadException())
388 return JSValue::encode(jsNull());
389 PropertyDescriptor descriptor
;
390 if (!toPropertyDescriptor(exec
, exec
->argument(2), descriptor
))
391 return JSValue::encode(jsNull());
392 ASSERT((descriptor
.attributes() & Accessor
) || (!descriptor
.isAccessorDescriptor()));
393 ASSERT(!exec
->hadException());
394 O
->methodTable(exec
->vm())->defineOwnProperty(O
, exec
, propertyName
, descriptor
, true);
395 return JSValue::encode(O
);
398 static JSValue
defineProperties(ExecState
* exec
, JSObject
* object
, JSObject
* properties
)
400 PropertyNameArray
propertyNames(exec
);
401 asObject(properties
)->methodTable(exec
->vm())->getOwnPropertyNames(asObject(properties
), exec
, propertyNames
, EnumerationMode(DontEnumPropertiesMode::Exclude
, SymbolPropertiesMode::Include
));
402 size_t numProperties
= propertyNames
.size();
403 Vector
<PropertyDescriptor
> descriptors
;
404 MarkedArgumentBuffer markBuffer
;
405 for (size_t i
= 0; i
< numProperties
; i
++) {
406 JSValue prop
= properties
->get(exec
, propertyNames
[i
]);
407 if (exec
->hadException())
409 PropertyDescriptor descriptor
;
410 if (!toPropertyDescriptor(exec
, prop
, descriptor
))
412 descriptors
.append(descriptor
);
413 // Ensure we mark all the values that we're accumulating
414 if (descriptor
.isDataDescriptor() && descriptor
.value())
415 markBuffer
.append(descriptor
.value());
416 if (descriptor
.isAccessorDescriptor()) {
417 if (descriptor
.getter())
418 markBuffer
.append(descriptor
.getter());
419 if (descriptor
.setter())
420 markBuffer
.append(descriptor
.setter());
423 for (size_t i
= 0; i
< numProperties
; i
++) {
424 Identifier propertyName
= propertyNames
[i
];
425 if (exec
->propertyNames().isPrivateName(propertyName
))
427 object
->methodTable(exec
->vm())->defineOwnProperty(object
, exec
, propertyName
, descriptors
[i
], true);
428 if (exec
->hadException())
434 EncodedJSValue JSC_HOST_CALL
objectConstructorDefineProperties(ExecState
* exec
)
436 if (!exec
->argument(0).isObject())
437 return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Properties can only be defined on Objects.")));
438 return JSValue::encode(defineProperties(exec
, asObject(exec
->argument(0)), exec
->argument(1).toObject(exec
)));
441 EncodedJSValue JSC_HOST_CALL
objectConstructorCreate(ExecState
* exec
)
443 JSValue proto
= exec
->argument(0);
444 if (!proto
.isObject() && !proto
.isNull())
445 return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Object prototype may only be an Object or null.")));
446 JSObject
* newObject
= proto
.isObject()
447 ? constructEmptyObject(exec
, asObject(proto
))
448 : constructEmptyObject(exec
, exec
->lexicalGlobalObject()->nullPrototypeObjectStructure());
449 if (exec
->argument(1).isUndefined())
450 return JSValue::encode(newObject
);
451 if (!exec
->argument(1).isObject())
452 return throwVMError(exec
, createTypeError(exec
, ASCIILiteral("Property descriptor list must be an Object.")));
453 return JSValue::encode(defineProperties(exec
, newObject
, asObject(exec
->argument(1))));
456 EncodedJSValue JSC_HOST_CALL
objectConstructorSeal(ExecState
* exec
)
458 // 1. If Type(O) is not Object, return O.
459 JSValue obj
= exec
->argument(0);
461 return JSValue::encode(obj
);
462 JSObject
* object
= asObject(obj
);
464 if (isJSFinalObject(object
)) {
465 object
->seal(exec
->vm());
466 return JSValue::encode(obj
);
469 // 2. For each named own property name P of O,
470 PropertyNameArray
properties(exec
);
471 object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, EnumerationMode(DontEnumPropertiesMode::Include
, SymbolPropertiesMode::Include
));
472 PropertyNameArray::const_iterator end
= properties
.end();
473 for (PropertyNameArray::const_iterator iter
= properties
.begin(); iter
!= end
; ++iter
) {
474 Identifier propertyName
= *iter
;
475 if (exec
->propertyNames().isPrivateName(propertyName
))
477 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
478 PropertyDescriptor desc
;
479 if (!object
->getOwnPropertyDescriptor(exec
, propertyName
, desc
))
481 // b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
482 desc
.setConfigurable(false);
483 // c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
484 object
->methodTable(exec
->vm())->defineOwnProperty(object
, exec
, propertyName
, desc
, true);
485 if (exec
->hadException())
486 return JSValue::encode(obj
);
489 // 3. Set the [[Extensible]] internal property of O to false.
490 object
->preventExtensions(exec
->vm());
493 return JSValue::encode(obj
);
496 JSObject
* objectConstructorFreeze(ExecState
* exec
, JSObject
* object
)
498 if (isJSFinalObject(object
) && !hasIndexedProperties(object
->indexingType())) {
499 object
->freeze(exec
->vm());
503 // 2. For each named own property name P of O,
504 PropertyNameArray
properties(exec
);
505 object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, EnumerationMode(DontEnumPropertiesMode::Include
, SymbolPropertiesMode::Include
));
506 PropertyNameArray::const_iterator end
= properties
.end();
507 for (PropertyNameArray::const_iterator iter
= properties
.begin(); iter
!= end
; ++iter
) {
508 Identifier propertyName
= *iter
;
509 if (exec
->propertyNames().isPrivateName(propertyName
))
511 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
512 PropertyDescriptor desc
;
513 if (!object
->getOwnPropertyDescriptor(exec
, propertyName
, desc
))
515 // b. If IsDataDescriptor(desc) is true, then
516 // i. If desc.[[Writable]] is true, set desc.[[Writable]] to false.
517 if (desc
.isDataDescriptor())
518 desc
.setWritable(false);
519 // c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
520 desc
.setConfigurable(false);
521 // d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
522 object
->methodTable(exec
->vm())->defineOwnProperty(object
, exec
, propertyName
, desc
, true);
523 if (exec
->hadException())
527 // 3. Set the [[Extensible]] internal property of O to false.
528 object
->preventExtensions(exec
->vm());
534 EncodedJSValue JSC_HOST_CALL
objectConstructorFreeze(ExecState
* exec
)
536 // 1. If Type(O) is not Object, return O.
537 JSValue obj
= exec
->argument(0);
539 return JSValue::encode(obj
);
540 return JSValue::encode(objectConstructorFreeze(exec
, asObject(obj
)));
543 EncodedJSValue JSC_HOST_CALL
objectConstructorPreventExtensions(ExecState
* exec
)
545 JSValue obj
= exec
->argument(0);
547 return JSValue::encode(obj
);
548 asObject(obj
)->preventExtensions(exec
->vm());
549 return JSValue::encode(obj
);
552 EncodedJSValue JSC_HOST_CALL
objectConstructorIsSealed(ExecState
* exec
)
554 // 1. If Type(O) is not Object, return true.
555 JSValue obj
= exec
->argument(0);
557 return JSValue::encode(jsBoolean(true));
558 JSObject
* object
= asObject(obj
);
560 if (isJSFinalObject(object
))
561 return JSValue::encode(jsBoolean(object
->isSealed(exec
->vm())));
563 // 2. For each named own property name P of O,
564 PropertyNameArray
properties(exec
);
565 object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, EnumerationMode(DontEnumPropertiesMode::Include
, SymbolPropertiesMode::Include
));
566 PropertyNameArray::const_iterator end
= properties
.end();
567 for (PropertyNameArray::const_iterator iter
= properties
.begin(); iter
!= end
; ++iter
) {
568 Identifier propertyName
= *iter
;
569 if (exec
->propertyNames().isPrivateName(propertyName
))
571 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
572 PropertyDescriptor desc
;
573 if (!object
->getOwnPropertyDescriptor(exec
, propertyName
, desc
))
575 // b. If desc.[[Configurable]] is true, then return false.
576 if (desc
.configurable())
577 return JSValue::encode(jsBoolean(false));
580 // 3. If the [[Extensible]] internal property of O is false, then return true.
581 // 4. Otherwise, return false.
582 return JSValue::encode(jsBoolean(!object
->isExtensible()));
585 EncodedJSValue JSC_HOST_CALL
objectConstructorIsFrozen(ExecState
* exec
)
587 // 1. If Type(O) is not Object, return true.
588 JSValue obj
= exec
->argument(0);
590 return JSValue::encode(jsBoolean(true));
591 JSObject
* object
= asObject(obj
);
593 if (isJSFinalObject(object
))
594 return JSValue::encode(jsBoolean(object
->isFrozen(exec
->vm())));
596 // 2. For each named own property name P of O,
597 PropertyNameArray
properties(exec
);
598 object
->methodTable(exec
->vm())->getOwnPropertyNames(object
, exec
, properties
, EnumerationMode(DontEnumPropertiesMode::Include
, SymbolPropertiesMode::Include
));
599 PropertyNameArray::const_iterator end
= properties
.end();
600 for (PropertyNameArray::const_iterator iter
= properties
.begin(); iter
!= end
; ++iter
) {
601 Identifier propertyName
= *iter
;
602 if (exec
->propertyNames().isPrivateName(propertyName
))
604 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
605 PropertyDescriptor desc
;
606 if (!object
->getOwnPropertyDescriptor(exec
, propertyName
, desc
))
608 // b. If IsDataDescriptor(desc) is true then
609 // i. If desc.[[Writable]] is true, return false. c. If desc.[[Configurable]] is true, then return false.
610 if ((desc
.isDataDescriptor() && desc
.writable()) || desc
.configurable())
611 return JSValue::encode(jsBoolean(false));
614 // 3. If the [[Extensible]] internal property of O is false, then return true.
615 // 4. Otherwise, return false.
616 return JSValue::encode(jsBoolean(!object
->isExtensible()));
619 EncodedJSValue JSC_HOST_CALL
objectConstructorIsExtensible(ExecState
* exec
)
621 JSValue obj
= exec
->argument(0);
623 return JSValue::encode(jsBoolean(false));
624 return JSValue::encode(jsBoolean(asObject(obj
)->isExtensible()));
627 EncodedJSValue JSC_HOST_CALL
objectConstructorIs(ExecState
* exec
)
629 return JSValue::encode(jsBoolean(sameValue(exec
, exec
->argument(0), exec
->argument(1))));